[InstCombine] Fold `and(shl(zext(x), width(SIGNMASK) - width(%x)), SIGNMASK)` to...
authorRoman Lebedev <lebedev.ri@gmail.com>
Thu, 19 Nov 2020 21:07:48 +0000 (00:07 +0300)
committerRoman Lebedev <lebedev.ri@gmail.com>
Thu, 19 Nov 2020 21:31:27 +0000 (00:31 +0300)
commita91e96702a3b8ef19afc5b7d2e51ce6b6a7fded9
tree10af092acb7c7f42a3f415947f0f72232f705a79
parentbcd469a9912b63ae912af4e693ad5c9d317fbdbb
[InstCombine] Fold `and(shl(zext(x), width(SIGNMASK) - width(%x)), SIGNMASK)` to `and(sext(%x), SIGNMASK)`

One less instruction and reducing use count of zext.
As alive2 confirms, we're fine with all the weird combinations of
undef elts in constants, but unless the shift amount was undef
for a lane, we must sanitize undef mask to zero, since sign bits
are no longer zeros.

https://rise4fun.com/Alive/d7r
```
----------------------------------------
Optimization: zz
Precondition: ((C1 == (width(%r) - width(%x))) && isSignBit(C2))
  %o0 = zext %x
  %o1 = shl %o0, C1
  %r = and %o1, C2
=>
  %n0 = sext %x
  %r = and %n0, C2

Done: 2016
Optimization is correct!
```
llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
llvm/test/Transforms/InstCombine/signmask-of-sext-vs-of-shl-of-zext.ll