86 Commits

Author SHA1 Message Date
Andreas Jonson
9399a1ddb8
[InstSimplify] Handle trunc to i1 in Select with bit test folds. (#122944)
Proof: https://alive2.llvm.org/ce/z/Jncqb2
2025-02-01 08:48:32 +01:00
Andreas Jonson
cd264f09a4 [InstSimplify] Test select bit test with trunc to i1 (NFC) 2025-01-13 23:52:23 +01:00
Paul Walker
38fffa630e
[LLVM][IR] Use splat syntax when printing Constant[Data]Vector. (#112548) 2024-11-06 11:53:33 +00:00
Ramkumar Ramachandra
c5f82f7893
ValueTracking: introduce llvm::isNotCrossLaneOperation (#112011)
Factor out and unify common code from InstSimplify and InstCombine that
partially guard against cross-lane vector operations into
llvm::isNotCrossLaneOperation in ValueTracking.

Alive2 proofs for changed tests: https://alive2.llvm.org/ce/z/68H4ka
2024-10-14 11:37:30 +01:00
Jay Foad
f3a02253e9
[test] Remove immarg parameter attribute from calls (#97432)
It is documented that immarg is only valid on intrinsic declarations,
although the verifier also tolerates it on intrinsic calls.

This patch updates tests that are not specifically testing the
behavior of the IR parser or verifier.
2024-07-03 09:02:31 +01:00
Maciej Gabka
bfc0317153
Move several vector intrinsics out of experimental namespace (#88748)
This patch is moving out following intrinsics:
* vector.interleave2/deinterleave2
* vector.reverse
* vector.splice

from the experimental namespace.

All these intrinsics exist in LLVM for more than a year now, and are
widely used, so should not be considered as experimental.
2024-04-29 10:16:45 +01:00
Nikita Popov
d9a5aa8e2d
[PatternMatch] Do not accept undef elements in m_AllOnes() and friends (#88217)
Change all the cstval_pred_ty based PatternMatch helpers (things like
m_AllOnes and m_Zero) to only allow poison elements inside vector
splats, not undef elements.

Historically, we used to represent non-demanded elements in vectors
using undef. Nowadays, we use poison instead. As such, I believe that
support for undef in vector splats is no longer useful.

At the same time, while poison splat elements are pretty much always
safe to ignore, this is not generally the case for undef elements. We
have existing miscompiles in our tests due to this (see the
masked-merge-*.ll tests changed here) and it's easy to miss such cases
in the future, now that we write tests using poison instead of undef
elements.

I think overall, keeping support for undef elements no longer makes
sense, and we should drop it. Once this is done consistently, I think we
may also consider allowing poison in m_APInt by default, as doing that
change is much less risky than doing the same with undef.

This change involves a substantial amount of test changes. For most
tests, I've just replaced undef with poison, as I don't think there is
value in retaining both. For some tests (where the distinction between
undef and poison is important), I've duplicated tests.
2024-04-17 18:22:05 +09:00
Nikita Popov
97e3220d63 [InstSimplify] Consider bitcast as potential cross-lane operation
The bitcast might change the number of vector lanes, in which case
it will be a cross-lane operation.

Fixes https://github.com/llvm/llvm-project/issues/77320.
2024-01-08 15:52:58 +01:00
Nikita Popov
ade7ae4760 [InstSimplify] Add test for #77320 (NFC) 2024-01-08 15:52:58 +01:00
Yingwei Zheng
554feb0058
[InstSimplify] Simplify select cond, undef, val to val if val = poison implies cond = poison (#76465)
This patch folds:
```
select cond, undef, val -> val
select cond, val, undef -> val
```
iff `impliesPoison(val, cond)` returns true.

Example:
```
define i32 @src1(i32 %retval.0.i.i) {
  %cmp.i = icmp sgt i32 %retval.0.i.i, -1
  %spec.select.i = select i1 %cmp.i, i32 %retval.0.i.i, i32 undef
  ret i32 %spec.select.i
}

define i32 @tgt1(i32 %retval.0.i.i) {
  ret i32 %retval.0.i.i
}
```
Alive2: https://alive2.llvm.org/ce/z/okJW3G

Compile-time impact:
http://llvm-compile-time-tracker.com/compare.php?from=38c9390b59c4d2b9181614d6a909887497d3692f&to=e146f51ba278aa3bb6879a9ec651831ac8938e91&stat=instructions%3Au
2023-12-28 23:37:19 +08:00
Nikita Popov
cd31cf5989 [InstSimplify] Fix or disjoint miscompile with op replacement
Make sure %x does not get folded to "or disjoint %x, %x" without
dropping the flag, as this would be a derefinement.
2023-12-01 11:45:09 +01:00
Nikita Popov
5a1020bb00 [InstSimplify] Add test for disjoint or miscompile (NFC)
The absorption case is already handled correctly, but the
idempentence case is not.
2023-12-01 11:45:09 +01:00
Nikita Popov
07c18a05e2 [InstSimplify] Fix select bit test miscompile with disjoint
The select condition ensures the disjointness here. The transform
is not valid without dropping the flag, which InstSimplify can't
do.
2023-11-30 16:55:32 +01:00
Nikita Popov
c89553ae82 [InstSimplify] Add test for or disjoint miscompile (NFC) 2023-11-30 16:55:32 +01:00
Nikita Popov
0db5d8e123 Reapply [InstSimplify] Make simplifyWithOpReplaced() recursive (PR63104)
A similar assumption as for the x^x case also existed for the absorber
case, which lead to a stage2 miscompile. That assumption is not fixed.

-----

Support replacement of operands not only in the immediate
instruction, but also instructions it uses.

To the most part, this extension is straightforward, but there are
two bits worth highlighting:

First, we can now no longer assume that if the Op is a vector, the
instruction also returns a vector. If Op is a vector and the
instruction returns a scalar, we should consider it as a cross-lane
operation.

Second, for the x ^ x special case and the absorber special case, we
can no longer assume that one of the operands is RepOp, as we might
have a replacement higher up the instruction chain.

There is one optimization regression, but it is in a fuzzer-generated
test case.

Fixes https://github.com/llvm/llvm-project/issues/63104.
2023-07-18 10:36:39 +02:00
Nikita Popov
96d6869332 [InstSimplify] Add additional tests for with op replaced fold (NFC) 2023-07-18 10:12:28 +02:00
Nikita Popov
2bc7d02312 Revert "[InstSimplify] Make simplifyWithOpReplaced() recursive (PR63104)"
This is very likely the cause of a stage 2 failure in
Transforms/LoopVectorize/check-prof-info.ll. Revert until I can
investigate this.

This reverts commit 3d199d086e076f0b9b90d4c59f2226a417a639b5.
2023-07-14 18:33:39 +02:00
Nikita Popov
3d199d086e [InstSimplify] Make simplifyWithOpReplaced() recursive (PR63104)
Support replacement of operands not only in the immediate
instruction, but also instructions it uses.

To the most part, this extension is straightforward, but there are
two bits worth highlighting:

First, we can now no longer assume that if the Op is a vector, the
instruction also returns a vector. If Op is a vector and the
instruction returns a scalar, we should consider it as a cross-lane
operation.

Second, for the x ^ x special case, we can no longer assume that
the operand is RepOp, as we might have a replacement higher up the
instruction chain.

There is one optimization regression, but it is in a fuzzer-generated
test case.

Fixes https://github.com/llvm/llvm-project/issues/63104.
2023-07-14 16:33:40 +02:00
Nikita Popov
91b84811ab [InstSimplify] Add tests for recursive simplify with op replaced (NFC) 2023-07-14 16:06:34 +02:00
Peixin Qiao
31dda3913f [InstCombine] Precommit a test
This patch precommits a test for:
https://reviews.llvm.org/D148420

Reviewed By: nikic

Differential Revision: https://reviews.llvm.org/D150069
2023-07-12 18:44:36 +08:00
luxufan
1ac99bc452 [InstSimplify] Simplify select i1 ConstExpr, i1 true, i1 false to ConstExpr
`select i1 non-const, i1 true, i1 false` has been optimized to
`non-const`. There is no reason that we can not optimize `select i1
ConstExpr, i1 true, i1 false` to `ConstExpr`.

Reviewed By: nikic

Differential Revision: https://reviews.llvm.org/D151631
2023-06-03 15:09:00 +08:00
Zhongyunde
cd87fe0c8b [Instsimplfy] X == Y ? 0 : X ^ Y --> X ^ Y
Alive2: https://alive2.llvm.org/ce/z/cykffE
Fixes: https://github.com/llvm/llvm-project/issues/62753

Reviewed By: nikic
Differential Revision: https://reviews.llvm.org/D150750
2023-05-17 18:36:39 +08:00
Jun Zhang
a47b56f4ef
[Instsimplfy] X == Y ? 0 : X - Y --> X - Y
Alive2: https://alive2.llvm.org/ce/z/rPN1GB
Fixes: https://github.com/llvm/llvm-project/issues/62238

Depends on D150377

Signed-off-by: Jun Zhang <jun@junz.org>

Differential Revision: https://reviews.llvm.org/D150378
2023-05-16 19:15:47 +08:00
Jun Zhang
ba3dbcc779
Add baseline tests for PR62238
Differential Revision: https://reviews.llvm.org/D150377

Signed-off-by: Jun Zhang <jun@junz.org>
2023-05-16 19:15:30 +08:00
Nikita Popov
beb16abf31 [InstSimplify] Add test for select op replacement in phi (NFC) 2023-04-25 15:41:07 +02:00
Peixin Qiao
b7e000d8c9 [InstSimplify] Precommit a test
This patch precommits a test for:

https://reviews.llvm.org/D148420
2023-04-17 21:55:51 +08:00
Sanjay Patel
ae2322a0dc [InstSimplify] enhance simplifyWithOpReplaced() to allow more 'select' removal
This is a generalization of a suggestion from issue #60799
that allows removing a redundant guard of an input value
via icmp+select. It should also solve issue #60801.

This only comes into play for a select with an equality
condition where we are trying to substitute a constant into
the false arm of a select. (A 'true' select arm substitution
allows "refinement", so it is not on this code path.)

The constant must be the same in the compare and the select,
and it must be a "binop absorber" (X op C = C). That query
currently includes 'or', 'and', and 'mul', so there are tests
for all of those opcodes.

We then use "impliesPoison" on the false arm binop and the
original "Op" to be replaced to ensure that the select is not
actually blocking poison from leaking. That could be
potentially expensive as we recursively test each operand, but
it is currently limited to a depth of 2. That's enough to catch
our motivating cases, but probably nothing more complicated
(although that seems unlikely).

I don't know how to generalize a proof for Alive2 for this, but
here's a positive and negative test example to help illustrate
the subtle logic differences of poison/undef propagation:
https://alive2.llvm.org/ce/z/Sz5K-c

Differential Revision: https://reviews.llvm.org/D144493
2023-02-21 17:03:40 -05:00
Sanjay Patel
dbc00b88e9 [InstSimplify] add tests for simplifyWithOpReplaced(); NFC
issue #60799
issue #60801
2023-02-21 12:49:34 -05:00
Sanjay Patel
9444252a67 [InstSimplify] with poison-safe logical ops: (X && Y) || X --> X
https://alive2.llvm.org/ce/z/ptZcJH

issue #60167
2023-01-20 17:35:24 -05:00
Nikita Popov
41dde5d858 [InstSimplify] Support vectors in simplifyWithOpReplaced()
We can handle vectors inside simplifyWithOpReplaced(), as long as
cross-lane operations are excluded. The equality can hold (or not
hold) for each vector lane independently, so we shouldn't use the
replacement value from other lanes.

I believe the only operations relevant here are shufflevector (where
all previous bugs were seen) and calls (which might use shuffle-like
intrinsics and would require more careful classification).

Differential Revision: https://reviews.llvm.org/D134348
2022-09-22 10:45:42 +02:00
Nikita Popov
7652710f9f [InstSimplify] Add additional simplifyWithOpReplaced() vector tests (NFC) 2022-09-21 16:59:28 +02:00
Nikita Popov
a342350b53 [InstSimplify] Add vector tests for simplifyWithOpReplaced (NFC) 2022-09-21 12:20:38 +02:00
Nikita Popov
04b944e230 [InstSimplify] Convert tests to opaque pointers (NFC)
The only interesting test change is in @PR31262, where the following
fold is now performed, while it previously was not:
https://alive2.llvm.org/ce/z/a5Qmr6

llvm/test/Transforms/InstSimplify/ConstProp/gep.ll has not been
updated, because there is a tradeoff between folding and inrange
preservation there that we may want to discuss.

Updates have been performed using:
https://gist.github.com/nikic/98357b71fd67756b0f064c9517b62a34
2022-06-10 17:16:28 +02:00
Bjorn Pettersson
b280ee1dd7 [test] Use -passes=instsimplify instead of -instsimplify in a number of tests. NFC
Another step moving away from the deprecated syntax of specifying
pass pipeline in opt.

Differential Revision: https://reviews.llvm.org/D119080
2022-02-07 14:26:58 +01:00
Juneyoung Lee
5af8bacc94 [InstSimplify] Add more poison folding optimizations
This adds more poison folding optimizations to InstSimplify.

Since all binary operators propagate poison, these are fine.

Also, the precondition of `select cond, undef, x` -> `x` is relaxed to allow the case when `x` is undef.

Reviewed By: nikic

Differential Revision: https://reviews.llvm.org/D104661
2021-06-23 20:25:24 +09:00
Sanjay Patel
ca7eaa0a54 [InstSimplify] allow undef element match in vector select condition value
The semantics of select with undefined/poison condition
are not explicitly stated in the LangRef, but this matches
comments in the code and Alive2 appears to concur:
https://alive2.llvm.org/ce/z/KXytmd

We can find this pattern after demanded elements transforms.

As noted in D101191, fuzzers are finding infinite loops because
we may not account for this pattern in other passes.
2021-05-25 14:25:34 -04:00
Sanjay Patel
e2a0f512ea [InstSimplify] fix potential miscompile in select value equivalence
This is the sibling fix to c590a9880d7a -
as there, we can't subsitute a vector value the equality
compare replacement that we are trying requires that the
comparison is true for the entire value. Vector select
can be partly true/false.
2021-04-05 16:52:34 -04:00
Sanjay Patel
78e5cf66fe [InstSimplify] add test for vector select with operand replacement; NFC
We need a sibling fix to c590a9880d7a
( https://llvm.org/PR49832 ) to avoid miscompiling.
2021-04-05 16:52:34 -04:00
Craig Topper
4c38c35c8d [ValueTracking] Teach canCreateUndefOrPoison that ctpop does not create undef or poison.
This select of ctpop with 0 pattern can get left behind after
loop idiom recognize converts a loop to ctpop. LLVM 10 was able
to optimize this, but LLVM 11 and later is not. The difference
seems to be that some select transforms are now limited based
on canCreateUndefOrPoison.

Teaching canCreateUndefOrPoison about ctpop restores the
LLVM 10 codegen.

Differential Revision: https://reviews.llvm.org/D99207
2021-03-23 12:42:18 -07:00
Nikita Popov
ece1403aca [InstSimplify] Add additional select operand replacement tests (NFC)
This tests for binops with identity elements.
2021-03-21 15:30:30 +01:00
Juneyoung Lee
864dda5fd5 [InstSimplify] Add tests that fold instructions with poison operands (NFC) 2020-12-02 01:01:59 +09:00
Cullen Rhodes
7b8d50b141 [InstSimplify] Clarify use of FixedVectorType in SimplifySelectInst
Folding a select of vector constants that include undef elements only
applies to fixed vectors, but there's no earlier check the type is not
scalable so it crashes for scalable vectors. This adds a check so this
optimization is only attempted for fixed vectors.

Reviewed By: sdesmalen

Differential Revision: https://reviews.llvm.org/D92046
2020-11-27 09:55:29 +00:00
Nikita Popov
a5be86fde5 [InstSimplify] Protect against more poison in SimplifyWithOpReplaced (PR47322)
Replace the check for poison-producing instructions in
SimplifyWithOpReplaced() with the generic helper canCreatePoison()
that properly handles poisonous shifts and thus avoids the problem
from PR47322.

This additionally fixes a bug in IIQ.UseInstrInfo=false mode, which
previously could have caused this code to ignore poison flags.
Setting UseInstrInfo=false should reduce the possible optimizations,
not increase them.

This is not a full solution to the problem, as poison could be
introduced more indirectly. This is just a minimal, easy to backport
fix.

Differential Revision: https://reviews.llvm.org/D86834
2020-08-29 21:59:39 +02:00
Craig Topper
a7a06ded8b Recommit "[InstSimplify] Remove select ?, undef, X -> X and select ?, X, undef -> X transforms" and its follow up patches
This recommits the following patches now that D85684 has landed

1cf6f210a2e [IR] Disable select ? C : undef -> C fold in ConstantFoldSelectInstruction unless we know C isn't poison.
469da663f2d [InstSimplify] Re-enable select ?, undef, X -> X transform when X is provably not poison
122b0640fc9 [InstSimplify] Don't fold vectors of partial undef in SimplifySelectInst if the non-undef element value might produce poison
ac0af12ed2f [InstSimplify] Add test cases for opportunities to fold select ?, X, undef -> X when we can prove X isn't poison
9b1e95329af [InstSimplify] Remove select ?, undef, X -> X and select ?, X, undef -> X transforms
2020-08-12 10:45:27 -07:00
Nikita Popov
566a66703f [InstSimplify] Add test for expand binop undef issue (NFC)
Add test case from https://reviews.llvm.org/D83360#2146539.
2020-08-10 22:39:59 +02:00
Craig Topper
00f3579aea Revert "[InstSimplify] Remove select ?, undef, X -> X and select ?, X, undef -> X transforms" and subsequent patches
This reverts most of the following patches due to reports of miscompiles.
I've left the added test cases with comments updated to be FIXMEs.

1cf6f210a2e [IR] Disable select ? C : undef -> C fold in ConstantFoldSelectInstruction unless we know C isn't poison.
469da663f2d [InstSimplify] Re-enable select ?, undef, X -> X transform when X is provably not poison
122b0640fc9 [InstSimplify] Don't fold vectors of partial undef in SimplifySelectInst if the non-undef element value might produce poison
ac0af12ed2f [InstSimplify] Add test cases for opportunities to fold select ?, X, undef -> X when we can prove X isn't poison
9b1e95329af [InstSimplify] Remove select ?, undef, X -> X and select ?, X, undef -> X transforms
2020-07-15 22:02:33 -07:00
Craig Topper
1cf6f210a2 [IR] Disable select ? C : undef -> C fold in ConstantFoldSelectInstruction unless we know C isn't poison.
This matches the recent change to InstSimplify from D83440.

Differential Revision: https://reviews.llvm.org/D83535
2020-07-10 10:42:25 -07:00
Craig Topper
469da663f2 [InstSimplify] Re-enable select ?, undef, X -> X transform when X is provably not poison
Follow up from the transform being removed in D83360. If X is probably not poison, then the transform is safe.

Still plan to remove or adjust the code from ConstantFolding after this.

Differential Revision: https://reviews.llvm.org/D83440
2020-07-09 12:21:03 -07:00
Craig Topper
122b0640fc [InstSimplify] Don't fold vectors of partial undef in SimplifySelectInst if the non-undef element value might produce poison
We can't fold to the non-undef value unless we know it isn't poison. So check each element with isGuaranteedNotToBeUndefOrPoison. This currently rules out all constant expressions.

Differential Revision: https://reviews.llvm.org/D83442
2020-07-09 11:01:12 -07:00
Craig Topper
ac0af12ed2 [InstSimplify] Add test cases for opportunities to fold select ?, X, undef -> X when we can prove X isn't poison
Part of addressing post-commit feedback from D83360
2020-07-08 15:24:55 -07:00