SuccessChanges

Summary

  1. [NFC] SimplifyCFGOpt::simplifyUnreachable(): pacify unused variable warning (details)
  2. [IR][InstCombine] Add m_ImmConstant(), that matches on non-ConstantExpr constants, and use it (details)
  3. [NFC][InstCombine] Autogenerate check lines in vec_shuffle.ll test (details)
  4. [NFC][InstCombine] Add test for `a & ~(a ^ b)` pattern (details)
  5. [InstCombine] Fold `a & ~(a ^ b)` to `x & y` (details)
  6. [NFC][InstCombine] Add test coverage for `(x ^ C) ^ y` pattern (details)
  7. [InstCombine] Hoist xor-by-constant from xor-by-value (details)
  8. [NFC][LoopIdiom] Improve test coverage for 'left-shift-until-bittest' pattern (details)
  9. [LoopIdiom] 'left-shift-until-bittest': keep no-wrap flags on shift, fix edge-case miscompilation for %x.next (details)
Commit ff3749fc7933a6f45b77739380e434060ca7693d by lebedev.ri
[NFC] SimplifyCFGOpt::simplifyUnreachable(): pacify unused variable warning

Thanks to Luke Benes for pointing it out.
The file was modifiedllvm/lib/Transforms/Utils/SimplifyCFG.cpp
Commit b3021a72a6d2fea8702b75f34f9f3317ae923d92 by lebedev.ri
[IR][InstCombine] Add m_ImmConstant(), that matches on non-ConstantExpr constants, and use it

A pattern to ignore ConstantExpr's is quite common, since they frequently
lead into infinite combine loops, so let's make writing it easier.
The file was modifiedllvm/lib/Transforms/InstCombine/InstructionCombining.cpp
The file was modifiedllvm/lib/Transforms/InstCombine/InstCombineNegator.cpp
The file was modifiedllvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
The file was modifiedllvm/include/llvm/IR/PatternMatch.h
The file was modifiedllvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
Commit da4c7e15df33aa659d160b645c595b977c81ad02 by lebedev.ri
[NFC][InstCombine] Autogenerate check lines in vec_shuffle.ll test
The file was modifiedllvm/test/Transforms/InstCombine/vec_shuffle.ll
Commit 1fda23367d46955fcb6e605f4114d47e499f0901 by lebedev.ri
[NFC][InstCombine] Add test for `a & ~(a ^ b)` pattern

... which is a variation of `a & (a ^ ~b)` --> a & b`.
A follow-up patch exposes this missing fold, so we need to fix it first.
The file was modifiedllvm/test/Transforms/InstCombine/and-xor-or.ll
Commit 5b78303433c0778a839e89d20daa57fbc037d0c7 by lebedev.ri
[InstCombine] Fold `a & ~(a ^ b)` to `x & y`

```
----------------------------------------
define i32 @and_xor_not_common_op(i32 %a, i32 %b) {
%0:
  %b2 = xor i32 %b, 4294967295
  %t2 = xor i32 %a, %b2
  %t4 = and i32 %t2, %a
  ret i32 %t4
}
=>
define i32 @and_xor_not_common_op(i32 %a, i32 %b) {
%0:
  %t4 = and i32 %a, %b
  ret i32 %t4
}
Transformation seems to be correct!
```
The file was modifiedllvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
The file was modifiedllvm/test/Transforms/InstCombine/and-xor-or.ll
Commit 8001dcbd50ce501e75e06886c5e225298e9eea2b by lebedev.ri
[NFC][InstCombine] Add test coverage for `(x ^ C) ^ y` pattern
The file was addedllvm/test/Transforms/InstCombine/hoist-xor-by-constant-from-xor-by-value.ll
Commit d9ebaeeb468d6a8f29eb479f18d2790f7efb8565 by lebedev.ri
[InstCombine] Hoist xor-by-constant from xor-by-value

This is one of the deficiencies that can be observed in
https://godbolt.org/z/YPczsG after D91038 patch set.

This exposed two missing folds, one was fixed by the previous commit,
another one is `(A ^ B) | ~(A ^ B) --> -1` / `(A ^ B) & ~(A ^ B) --> 0`.

`-early-cse` will catch it: https://godbolt.org/z/4n1T1v,
but isn't meaningful to fix it in InstCombine,
because we'd need to essentially do our own CSE,
and we can't even rely on `Instruction::isIdenticalTo()`,
because there are no guarantees that the order of operands matches.
So let's just accept it as a loss.
The file was modifiedllvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
The file was modifiedllvm/test/Transforms/InstCombine/unfold-masked-merge-with-const-mask-vector.ll
The file was modifiedllvm/test/Transforms/InstCombine/or-xor.ll
The file was modifiedllvm/test/Transforms/InstCombine/vec_shuffle.ll
The file was modifiedllvm/test/Transforms/InstCombine/invert-variable-mask-in-masked-merge-vector.ll
The file was modifiedllvm/test/Transforms/InstCombine/xor2.ll
The file was modifiedllvm/test/Transforms/InstCombine/invert-variable-mask-in-masked-merge-scalar.ll
The file was modifiedllvm/test/Transforms/InstCombine/hoist-xor-by-constant-from-xor-by-value.ll
The file was modifiedllvm/test/Transforms/InstCombine/vec_shuffle-inseltpoison.ll
The file was modifiedllvm/test/Transforms/InstCombine/unfold-masked-merge-with-const-mask-scalar.ll
Commit 6e074a8324d86af93930001e4bdcaff8ebc9890e by lebedev.ri
[NFC][LoopIdiom] Improve test coverage for 'left-shift-until-bittest' pattern

In particular, add tests with no-wrap flags on shift,
a test where %x is not `1`, and ensure that tests where %bit
is a constant bitwidth-1, or is not a constant bitwidth-1
test both liveout values.
The file was modifiedllvm/test/Transforms/LoopIdiom/X86/left-shift-until-bittest.ll
Commit 25aebe2ccfb4622b17494c5cfdb2b422c93cee4d by lebedev.ri
[LoopIdiom] 'left-shift-until-bittest': keep no-wrap flags on shift, fix edge-case miscompilation for %x.next

While `%x.curr` is always safe to compute, because `LoopBackedgeTakenCount`
will always be smaller than `bitwidth(X)`, i.e. we never get poison,
rewriting `%x.next` is more complicated, however, because `X << LoopTripCount`
will be poison iff `LoopTripCount == bitwidth(X)` (which will happen
iff `BitPos` is `bitwidth(x) - 1` and `X` is `1`).

So unless we know that isn't the case (as alive2 notes, we know it's safe
to do iff shift had no-wrap flags, or bitpos does not indicate signbit,
or we know that %x is never `1`), we'll need to emit an alternative,
safe IR, by either just shifting the `%x.curr`, or conditionally selecting
between the computed `%x.next` and `0`..
Former IR looks better so let's do that.

While there, ensure that we don't drop no-wrap flags from said shift.
The file was modifiedllvm/test/Transforms/LoopIdiom/X86/left-shift-until-bittest.ll
The file was modifiedllvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp