349 Commits

Author SHA1 Message Date
Yingwei Zheng
c89d731c5d
[LVI] Infer non-zero from equality icmp (#112838)
This following pattern is common in loop headers:
```
  %101 = sub nuw i64 %78, %98
  %103 = icmp eq i64 %78, %98
  br i1 %103, label %.thread.i.i, label %.preheader.preheader.i.i

.preheader.preheader.i.i:
  %invariant.umin.i.i = call i64 @llvm.umin.i64(i64 %101, i64 9)
  %umax.i = call i64 @llvm.umax.i64(i64 %invariant.umin.i.i, i64 1)
  br label %.preheader.i.i

.preheader.i.i:
  ...
  %116 = add nuw nsw i64 %.011.i.i, 1
  %exitcond.not.i = icmp eq i64 %116, %umax.i
  br i1 %exitcond.not.i, label %.critedge.i.i, label %.preheader.i.i
```
As `%78` is not equal to `%98` in BB `.preheader.preheader.i.i`, we can
prove `%101` is non-zero. Then we can simplify the loop exit condition.

Addresses regression introduced by
https://github.com/llvm/llvm-project/pull/112742.
2024-10-18 21:19:02 +08:00
Nikita Popov
3127b659fa
[CVP] Infer range return attribute (#99620)
We already infer this in IPSCCP (which runs very early, so cannot
benefit from inlining and simplifications) and SCCP (which runs without
PredicateInfo, so does not use assumes). Do it in CVP as well, so it can
handle cases that IPSCCP/SCCP can't.

Fixes https://github.com/llvm/llvm-project/issues/98946 (everything
apart from f2, where the assume is dropped by the frontend).
2024-09-20 14:29:19 +02:00
Yingwei Zheng
07b29fc808
[ConstantRange] Improve shlWithNoWrap (#101800)
Closes https://github.com/dtcxzyw/llvm-tools/issues/22.
2024-08-07 02:00:33 +08:00
Yingwei Zheng
1a5d8926c5
[ConstantRange] Add support for shlWithNoWrap (#100594)
This patch adds initial support for `ConstantRange:: shlWithNoWrap` to
fold https://github.com/dtcxzyw/llvm-tools/issues/22. However, this
patch cannot fix the original issue. Improvements will be submitted in subsequent patches.
2024-08-02 00:03:44 +08:00
Yingwei Zheng
ca00cec997
[ConstantRange] Infer nonnegative for mul nuw nsw (#100554)
Alive2: https://alive2.llvm.org/ce/z/byzmsV
2024-07-25 21:29:18 +08:00
Nikita Popov
6235698f47 [CVP] Add tests for range return attributes (NFC) 2024-07-19 11:09:50 +02:00
Nikita Popov
d2e8b1d717 [CVP] Regenerate test checks (NFC) 2024-07-19 11:09:50 +02:00
Rajat Bajpai
90668d2404
[CVP][LVI] Add support for InsertElementInst in LVI (#99368)
Currently, the LVI analysis pass doesn't support InsertElementInst
vector instruction. Due to this, some optimization opportunities are
missed. For example, in the below example, ICMP instruction can be
folded but it doesn't.

```
...
%ie1 = insertelement <2 x i32> poison, i32 10, i64 0
%ie2 = insertelement <2 x i32> %ie1, i32 20, i64 1
%icmp = icmp <2 x i1> %ie2, <i32 40, i32 40>
...
```

This change adds InsertElementInst support in the LVI analysis pass to
fix the motivating example.
2024-07-19 08:46:41 +02:00
Nikita Popov
7d74ca9513
[ValueLattice] Support constant vectors in mergeIn() (#99466)
This is a followup to vector support in LVI/CVP/SCCP. In mergeIn(), if
one of the operands is a vector of integer constant, we should try to
convert it into a constant range, in case that allows performing a range
union to something better than overdefined.
2024-07-18 16:48:21 +02:00
Nikita Popov
94cd18b7fc [CVP] Add test for phi merging of vectors (NFC) 2024-07-18 09:58:52 +02:00
Nikita Popov
130f0f526d [LVI][CVP] Add support for vector comparisons 2024-07-05 17:02:03 +02:00
Nikita Popov
4339d2edf6 [CVP] Add missing CHECK lines in test (NFC) 2024-07-05 16:57:08 +02:00
goldsteinn
899fe2cf31
[CVP][LVI] Fix incorrect scalar type when getting constant folded vec (#97682)
Fixes #97674

After #97428 added support for vectors, our constant ranges can now be
from splat vectors so when they reduce to a singe constant value, we
need to return the original type as opposed to just an int.
2024-07-04 15:14:39 +08:00
Nikita Popov
c2072d993a [CVP] Support vectors for and elision 2024-07-03 14:40:48 +02:00
Nikita Popov
1eec81a831
[CVP][LVI] Add support for vectors (#97428)
The core change here is to add support for converting vector constants
into constant ranges. The rest is just relaxing isIntegerTy() checks and
making sure we don't use APIs that assume vectors.

There are a couple of places that don't support vectors yet, most
notably the "simplest" fold (comparisons to a constant) isn't supported
yet. I'll leave these to a followup.
2024-07-03 12:41:49 +02:00
Nikita Popov
abb5bd3732 [CVP] Add vector test cases (NFC) 2024-07-02 17:24:16 +02:00
Poseydon42
a616f57c1f
[CorrelatedValuePropagation] Fold calls to UCMP/SCMP when we know that ranges of operands do not overlap (#97235)
This patch adds folds for calls to `ucmp`/`scmp` intrinsics where we can
establish that the range of the first operand is strictly to the left or
strictly to the right of the range of the second operand.
2024-07-02 12:18:52 +02:00
Yingwei Zheng
394e321a2e
Reland "[CVP] Check whether the default case is reachable (#79993)" (#96089)
This patch reverts https://github.com/llvm/llvm-project/pull/81585 as
https://github.com/llvm/llvm-project/pull/78582 has been landed.
Now clang works well with reproducer
https://github.com/llvm/llvm-project/pull/79993#issuecomment-1936822679.
2024-06-20 13:45:18 +08:00
Antonio Frighetto
c22d3917b9 [LVI][ConstantRange] Generalize mask not equal conditions handling
Extend `V & Mask != 0` for non-zero constants if satisfiable, when
retrieving constraint value information from a non-equality comparison.

Proof: https://alive2.llvm.org/ce/z/dc5BeT.

Motivating example: https://github.com/gcc-mirror/gcc/blob/master/gcc/testsuite/gcc.dg/tree-ssa/vrp76.c.
2024-06-17 21:13:52 +02:00
Nikita Popov
deab451e7a
[IR] Remove support for icmp and fcmp constant expressions (#93038)
Remove support for the icmp and fcmp constant expressions.

This is part of:
https://discourse.llvm.org/t/rfc-remove-most-constant-expressions/63179

As usual, many of the updated tests will no longer test what they were
originally intended to -- this is hard to preserve when constant
expressions get removed, and in many cases just impossible as the
existence of a specific kind of constant expression was the cause of the
issue in the first place.
2024-06-04 08:31:03 +02:00
Antonio Frighetto
e897b0bbe9 [ConstantRange][LVI] Add support for multiplyWithNoWrap
Introduce support for computing multiplication ranges when nowrap
flags are known. This is achieved by intersecting the multiplication
range with the saturating one. Note that we may still conservatively
return overdefined when handling non-wrapped/non-sign-wrapped ranges.
2024-05-24 19:25:09 +02:00
Noah Goldstein
925a11128c [CVP] Convert sitofp -> uitofp nneg and add nneg flag to uitofp
Similiar to the `InstCombine` changes, just furthering the scope of
the canonicalization/`uitofp nneg` support
2024-05-07 14:57:29 -05:00
Noah Goldstein
31dd0ef73c [CVP] Add tests for adding nneg flag to uitofp and converting sitofp -> uitofp nneg; NFC 2024-05-07 14:57:29 -05:00
Yingwei Zheng
df9c00beea
[CVP] Use at-use info in processBinOp (#88523)
This patch uses `getConstantRangeAtUse` to infer nsw/nuw flags with
at-use info. It will enables more optimizations in InstCombine.

Compile-time impact:
http://llvm-compile-time-tracker.com/compare.php?from=a5ed14bc8e122fa5ac0aa81f8d8390931bd6b4e4&to=a83d3402b663439b91cb37a046fb7ac0220ba5c7&stat=instructions%3Au

Related issue: #87854
2024-04-13 15:07:55 +08:00
Andreas Jonson
d4cd65ecf2
[LVI] Handle range attributes (#86413)
This adds handling of range attribute for return values of Call and
Invoke in getFromRangeMetadata and handling of argument with range
attribute in solveBlockValueNonLocal.
There is one additional check of the range metadata at line 1120 in
getValueFromSimpleICmpCondition that is not covered in this PR as after
https://github.com/llvm/llvm-project/pull/75311 there is no test that
cover that check any more and I have not been able to create a test that
trigger that code.
2024-04-04 14:48:11 +08:00
Noah Goldstein
0e78655731 [LVI] Use m_AddLike instead of m_Add when matching simple condition
We have more complete logic for handling `Add`, so try to use that
logic for `or disjoint` (which can definitionally be treated as
`add`).

Closes #86058
2024-03-28 13:49:05 -05:00
Noah Goldstein
efa1544c2c [LVI] Add tests for tracking or disjoint like add; NFC 2024-03-28 13:49:05 -05:00
Philip Reames
49b1fc4f83
[CVP] Freeze Y when expanding urem x, y with X < 2Y (#84390)
We're going from a single use to two independent uses, we need these two
to see consistent values for undef. As an example, consider x = 0x2 when
y = 0b00u1. If the sub use picks 0b0001 and the cmp use picks 0b0011,
that would be incorrect.
2024-03-07 14:37:10 -08:00
Philip Reames
a10fd16270 [CVP] Add test coverage for an upcoming generalization of expandUDivOrURem 2024-03-07 12:02:09 -08:00
Yingwei Zheng
cc83927516
[CVP] Canonicalize signed minmax into unsigned (#82478)
This patch turns signed minmax to unsigned to match the behavior for
signed icmps.
Alive2: https://alive2.llvm.org/ce/z/UAAM42
2024-02-23 02:42:49 +08:00
Yingwei Zheng
3ef63a71ad
[CVP] Refactor processMinMaxIntrinsic to check non-strict predicate in both directions (#82596)
This patch uses `getConstantRangeAtUse` in `processMinMaxIntrinsic` to
address the comment
https://github.com/llvm/llvm-project/pull/82478#discussion_r1497300920.
After this patch we can reuse the range result in
https://github.com/llvm/llvm-project/pull/82478.
2024-02-22 20:57:34 +08:00
Yingwei Zheng
ca61e6a71d
Revert "[CVP] Check whether the default case is reachable (#79993)" (#81585)
This reverts commit a034e65e972175a2465deacb8c78bc7efc99bd23.

Some protobuf users reported that this patch caused a significant
compile-time regression because `TailDuplicator` works poorly with a
specific pattern.

We will reland it once the codegen issue is fixed.
2024-02-13 17:28:06 +08:00
Nikita Popov
2d69827c5c [Transforms] Convert tests to opaque pointers (NFC) 2024-02-05 11:57:34 +01:00
Yingwei Zheng
a034e65e97
[CVP] Check whether the default case is reachable (#79993)
This patch eliminates unreachable default cases using context-sensitive
range information.
2024-01-31 13:11:10 +08:00
Nikita Popov
f20488687e [CVP] Add test with nested cycle (NFC)
This is a regression test for a miscompile that would have been
introduced by an upcoming patch.
2024-01-18 16:57:29 +01:00
Yingwei Zheng
848d7af956
[CVP] Improve the value solving of select at use (#76700)
This patch improves the value solving of select at use if the condition
is an icmp and we know the result of comparison from
`LVI->getPredicateAt`.

Compile-time impact:
http://llvm-compile-time-tracker.com/compare.php?from=7e405eb722e40c79b7726201d0f76b5dab34ba0f&to=3c315b1ddcb0ad82554b33f08b9356679fae4bb7&stat=instructions:u

|stage1-O3|stage1-ReleaseThinLTO|stage1-ReleaseLTO-g|stage1-O0-g|stage2-O3|stage2-O0-g|stage2-clang|
|--|--|--|--|--|--|--|
|-0.01%|+0.01%|-0.00%|-0.00%|-0.08%|+0.02%|-0.01%|
2024-01-06 02:32:57 +08:00
Nikita Popov
d5db2cdb22 [LVI] Don't push both binop operands at once
If one of the binop operands depends on the other, this may end
up evaluating them in the wrong order, producing sub-optimal
results.

Make sure that only one unevaluated operand gets pushed per
iteration.

Fixes https://github.com/llvm/llvm-project/issues/76705.
2024-01-02 11:24:47 +01:00
Nikita Popov
aa6bb1697f [CVP] Add test for #76705 (NFC) 2024-01-02 11:24:47 +01:00
Nikita Popov
734ee0e01f
[LVI] Support using block values when handling conditions (#75311)
Currently, LVI will only use conditions like "X < C" to constrain the
value of X on the relevant edge. This patch extends it to handle
conditions like "X < Y" by querying the known range of Y.

This means that getValueFromCondition() and various related APIs can now
return nullopt to indicate that they have pushed to the worklist, and
need to be called again later. This behavior is currently controlled by
a UseBlockValue option, and only enabled for actual edge value handling.
All other places deriving constraints from conditions keep using the
previous logic for now.

This change was originally motivated as a fix for the regression
reported in
https://github.com/llvm/llvm-project/pull/73662#issuecomment-1849281758.
Unfortunately, it doesn't actually fix it, because we run into another
issue there (LVI currently is really bad at handling values used in
loops).

This change has some compile-time impact, but it's fairly small,
in the 0.05% range.
2024-01-02 10:49:45 +01:00
Shan Huang
06a9c6738a
[CVP] Fix #76058: missing debug location in processSDiv function (#76118)
This PR fixes #76058.
2023-12-22 09:26:32 +01:00
Nikita Popov
a134abf4be
[ValueTracking] Make isGuaranteedNotToBeUndef() more precise (#76160)
Currently isGuaranteedNotToBeUndef() is the same as
isGuaranteedNotToBeUndefOrPoison(). This function is used in places
where we only care about undef (due to multi-use issues), not poison.

Make it more precise by only considering instructions that can create
undef (like loads or call), and ignore those that can only create
poison. In particular, we can ignore poison-generating flags.

This means that inferring more flags has less chance to pessimize other
transforms.
2023-12-21 16:49:37 +01:00
Nikita Popov
38c1ff89ee [CVP] Add additional tests for undef check (NFC) 2023-12-21 15:40:14 +01:00
Nikita Popov
41f905ddf0 [CVP] Add tests for using block values in conditions (NFC) 2023-12-13 10:52:42 +01:00
Nikita Popov
967e84eee3 [CVP] Don't use undef range for LHS of div/rem transforms
Using it for RHS is fine, as undef is UB in that case.
2023-12-12 12:06:19 +01:00
Nikita Popov
4b7f14573e [CVP] Add test for invalid use of undef range in urem transform (NFC) 2023-12-12 12:06:19 +01:00
Nikita Popov
84df226c4a [CVP] Don't use undef ranges in willNotOverflow() 2023-12-12 11:54:33 +01:00
Nikita Popov
2db1a42184 [CVP] Add test for invalid use of undef range for saturating insts (NFC) 2023-12-12 11:54:33 +01:00
Nikita Popov
4949fb7954 [CVP] Don't allow undef range when inferring nowrap flags 2023-12-12 11:26:00 +01:00
Nikita Popov
5799d13107 [CVP] Add test for incorrect use of range with undef (NFC) 2023-12-12 11:26:00 +01:00
Nikita Popov
23d0a3044c [CVP] Regenerate test checks (NFC) 2023-12-12 11:26:00 +01:00