Currently, we only deal with the case where we can match
the number of low bits to be kept, i.e.:
x & ((1 << y) - 1)
will extract low y bits of x.
But what will
x & (-1 >> y)
do?
Logically, it will extract bitwidth(x) - y low bits, i.e.:
x & ~(-1 << (bitwidth(x)-y))
... except we can't do such a transformation in IR in general,
because if we wanted to extract all the bits (-1 >> 0) is fine,
but -1 << bitwidth(x) would be poison: https://alive2.llvm.org/ce/z/BKJZfw,
Yet, here with BMI's BEXTR and BMI2's BZHI we don't have any such problems with edge-cases.
So what we can do is: https://alive2.llvm.org/ce/z/gm5M2B
As briefly discussed with @craig.topper, this appears to be not worse than what we'd end up with currently (a pair of shifts):
- https://godbolt.org/z/nsPb8bejs (direct data dependency, sequential execution)
- https://godbolt.org/z/7bj3zeh1d (no direct data dependency, parallel execution)
Can we use Optional::getValueOr here?