27 Commits

Author SHA1 Message Date
Sanjay Patel
b24e2f6ef6 [InstCombine] use logical-and matcher to avoid crash
Follow-on to:
ec0b406e16c44f1554

This should prevent crashing for example like issue #58552
by not matching a select-of-vectors-with-scalar-condition.

The test that shows a regression seems unlikely to occur
in real code.

This also picks up an optimization in the case where a real
(bitwise) logic op is used. We could already convert some
similar select ops to real logic via impliesPoison(), so
we don't see more diffs on commuted tests. Using commutative
matchers (when safe) might also handle one of the TODO tests.
2022-11-02 08:23:52 -04:00
Sanjay Patel
6f77979a4b [InstCombine] add tests for logical-and / logical-or folds; NFC
Similar to 29661fe94bf12ced1 - there are matching
deficiencies and a potential crash lurking in
these patterns.
2022-11-02 08:23:52 -04:00
Sanjay Patel
ec0b406e16 [InstCombine] use logical-or matcher to avoid crash
This should prevent crashing for the example in issue #58552
by not matching a select-of-vectors-with-scalar-condition.

A similar change is likely needed for the related fold to
properly fix that kind of bug.

The test that shows a regression seems unlikely to occur
in real code.

This also picks up an optimization in the case where a real
(bitwise) logic op is used. We could already convert some
similar select ops to real logic via impliesPoison(), so
we don't see more diffs on commuted tests. Using commutative
matchers (when safe) might also handle one of the TODO tests.
2022-11-01 16:47:41 -04:00
Sanjay Patel
29661fe94b [InstCombine] add tests for logical-and / logical-or folds; NFC 2022-11-01 16:47:41 -04:00
Sanjay Patel
5dcfc32822 [InstCombine] allow more commutative matches for logical-and to select fold
This is a sibling transform to the fold just above it. That was changed
to allow the corresponding commuted patterns with:
307307456277
e1bd759ea567
8628e6df7000
2022-10-24 16:40:43 -04:00
Sanjay Patel
8628e6df70 [InstCombine] use freeze to enable poison-safe logic->select fold
Without a freeze, this transform can leak poison to the output:
https://alive2.llvm.org/ce/z/GJuF9i

This makes the transform as uniform as possible, and it can help
reduce patterns like issue #58313 (although that particular
example probably still needs another transform).

Differential Revision: https://reviews.llvm.org/D136527
2022-10-22 10:42:14 -04:00
Sanjay Patel
db40f9b774 [InstCombine] add test for logical-ands to select; NFC 2022-10-22 10:42:14 -04:00
Sanjay Patel
e1bd759ea5 [InstCombine] allow more matches for logical-ands --> select
This allows patterns with real 'and' instructions because
those are safe to transform:
https://alive2.llvm.org/ce/z/7-U_Ak
2022-10-22 08:15:50 -04:00
Sanjay Patel
3073074562 [InstCombine] allow more commutative matches for logical-and to select fold
When the common value is part of either select condition,
this is safe to reduce. Otherwise, it is not poison-safe
(with the select form of the pattern):
https://alive2.llvm.org/ce/z/FxQTzB

This is another patch motivated by issue #58313.
2022-10-21 13:29:13 -04:00
Sanjay Patel
d7fecf26f4 [InstCombine] allow some commutative matches for logical-and to select fold
This is obviously correct for real logic instructions,
and it also works for the poison-safe variants that use
selects:
https://alive2.llvm.org/ce/z/wyHiwX

This is motivated by the lack of 'xor' folding seen in issue #58313.
This more general fold should help reduce some of those patterns,
but I'm not sure if this specific case does anything for that
particular example.
2022-10-21 11:28:38 -04:00
Sanjay Patel
bf75e937bb [InstCombine] match logical and/or more generally in fold to select
This allows the regular bitwise logic opcodes in addition to the
poison-safe select variants:
https://alive2.llvm.org/ce/z/8xB9gy

Handling commuted variants safely is likely trickier, so that's
left to another patch.
2022-10-21 09:03:36 -04:00
Sanjay Patel
5a53fe846b [InstCombine] add tests for logical selects; NFC 2022-10-21 09:03:35 -04:00
Bjorn Pettersson
4ab40eca08 [test][InstCombine] Update some test cases to use opaque pointers
These tests cases were converted using the script at
https://gist.github.com/nikic/98357b71fd67756b0f064c9517b62a34

Differential Revision: https://reviews.llvm.org/D135094
2022-10-03 22:17:59 +02:00
Bjorn Pettersson
acdc419c89 [test] Use -passes=instcombine instead of -instcombine in lots of tests. NFC
Another step moving away from the deprecated syntax of specifying
pass pipeline in opt.

Differential Revision: https://reviews.llvm.org/D119081
2022-02-07 14:26:59 +01:00
Juneyoung Lee
8a156d1c27 [InstCombine] Fully disable select to and/or i1 folding
This is a patch that disables the poison-unsafe select -> and/or i1 folding.

It has been blocking D72396 and also has been the source of a few miscompilations
described in llvm.org/pr49688 .
D99674 conditionally blocked this folding and successfully fixed the latter one.
The former one was still blocked, and this patch addresses it.

Note that a few test functions that has `_logical` suffix are now deoptimized.
These are created by @nikic to check the impact of disabling this optimization
by copying existing original functions and replacing and/or with select.

I can see that most of these are poison-unsafe; they can be revived by introducing
freeze instruction. I left comments at fcmp + select optimizations (or-fcmp.ll, and-fcmp.ll)
because I think they are good targets for freeze fix.

Reviewed By: nikic

Differential Revision: https://reviews.llvm.org/D101191
2021-05-06 09:29:52 +09:00
Juneyoung Lee
1fef5c88a6 [InstCombine] Fold more select of selects using isImpliedCondition
This is a simple folding that does these:

```
select x_inv, true, (select y, x, false)
=>
select x_inv, true, y
```
https://alive2.llvm.org/ce/z/-STJ2d

```
select (select y, x, false), true, x_inv
=>
select y, true, x_inv
```
https://alive2.llvm.org/ce/z/6ruYt6

Reviewed By: spatel

Differential Revision: https://reviews.llvm.org/D101807
2021-05-05 13:44:58 +09:00
Juneyoung Lee
a71d666d18 [InstCombine] Precommit tests for D101807 (NFC) 2021-05-05 13:44:57 +09:00
Juneyoung Lee
39eb2665d9 [InstCombine] Add a few more patterns for folding select of select
This is a patch that folds select of select to salvage some optimizations after select -> and/or folding is disabled.

```
select (select a, true, b), c, false -> select a, c, false
select c, (select a, true, b), false -> select c, a, false
  if c implies that b is false (isImpliedCondition).
```
https://alive2.llvm.org/ce/z/ANatjt, https://alive2.llvm.org/ce/z/rv8zTB

```
sel (sel c, a, false), true, (sel !c, b, false) -> sel c, a, b
sel (sel !c, a, false), true, (sel c, b, false) -> sel c, b, a
```
https://alive2.llvm.org/ce/z/U2kp-t, https://alive2.llvm.org/ce/z/bc88EE

See D101191

Reviewed By: nikic

Differential Revision: https://reviews.llvm.org/D101375
2021-05-02 19:00:42 +09:00
Juneyoung Lee
ecfe75eb74 [InstCombine] Precommit tests for D101375 (NFC) 2021-05-02 19:00:42 +09:00
Juneyoung Lee
5260873c3b [InstCombine] add tests for simplification of logical and/ors (NFC) 2021-02-18 17:42:06 +09:00
Nikita Popov
21443381c0 Reapply [InstCombine] Replace one-use select operand based on condition
Relative to the original change, this adds a check that the
instruction on which we're replacing operands is safe to speculatively
execute, because that's what we're effectively doing. We're executing
the instruction with the replaced operand, which is fine if it's pure,
but not fine if can cause side-effects or UB (aka is not speculatable).

Additionally, we cannot (generally) replace operands in phi nodes,
as these may refer to a different loop iteration. This is also covered
by the speculation check.

-----

InstCombine already performs a fold where X == Y ? f(X) : Z is
transformed to X == Y ? f(Y) : Z if f(Y) simplifies. However,
if f(X) only has one use, then we can always directly replace the
use inside the instruction. To actually be profitable, limit it to
the case where Y is a non-expr constant.

This could be further extended to replace uses further up a one-use
instruction chain, but for now this only looks one level up.

Among other things, this also subsumes D94860.

Differential Revision: https://reviews.llvm.org/D94862
2021-01-19 20:26:38 +01:00
Hans Wennborg
58bdfcfac0 Revert 5238e7b302 "[InstCombine] Replace one-use select operand based on condition"
This caused a miscompile in Chromium, see comments on the codereview for
discussion and pointer to a reproducer.

> InstCombine already performs a fold where X == Y ? f(X) : Z is
> transformed to X == Y ? f(Y) : Z if f(Y) simplifies. However,
> if f(X) only has one use, then we can always directly replace the
> use inside the instruction. To actually be profitable, limit it to
> the case where Y is a non-expr constant.
>
> This could be further extended to replace uses further up a one-use
> instruction chain, but for now this only looks one level up.
>
> Among other things, this also subsumes D94860.
>
> Differential Revision: https://reviews.llvm.org/D94862

This also reverts the follow-up
a003f26539cf4db744655e76c41f4c4a8913f116:

> [llvm] Prevent infinite loop in InstCombine of select statements
>
> This fixes an issue where the RHS and LHS the comparison operation
> creating the predicate were swapped back and forth forever.
>
> Differential Revision: https://reviews.llvm.org/D94934
2021-01-19 11:50:56 +01:00
Juneyoung Lee
0441df94ad [InstCombine,InstSimplify] Optimize select followed by and/or/xor
This patch adds `A & (A && B)` -> `A && B`  (similarly for or + logical or)

Also, this patch adds `~(select C, (icmp pred X, Y), const)` -> `select C, (icmp pred' X, Y), ~const`.

Alive2 proof:
merge_and: https://alive2.llvm.org/ce/z/teMR97
merge_or: https://alive2.llvm.org/ce/z/b4yZUp
xor_and: https://alive2.llvm.org/ce/z/_-TXHi
xor_or: https://alive2.llvm.org/ce/z/2uYx_a

Reviewed By: nikic

Differential Revision: https://reviews.llvm.org/D94861
2021-01-19 09:14:17 +09:00
Juneyoung Lee
2639c162b7 [InstCombine] more tests for D94861 (NFC) 2021-01-18 11:12:52 +09:00
Nikita Popov
5238e7b302 [InstCombine] Replace one-use select operand based on condition
InstCombine already performs a fold where X == Y ? f(X) : Z is
transformed to X == Y ? f(Y) : Z if f(Y) simplifies. However,
if f(X) only has one use, then we can always directly replace the
use inside the instruction. To actually be profitable, limit it to
the case where Y is a non-expr constant.

This could be further extended to replace uses further up a one-use
instruction chain, but for now this only looks one level up.

Among other things, this also subsumes D94860.

Differential Revision: https://reviews.llvm.org/D94862
2021-01-16 23:25:02 +01:00
Juneyoung Lee
e0a979ccad [InstCombine] Add more tests to select-safe-transforms.ll (NFC) 2021-01-16 19:49:12 +09:00
Juneyoung Lee
b664bef2ad [InstCombine] Add a test file that contains safe select transforms (NFC) 2021-01-16 19:27:43 +09:00