%ret = add nuw i8 %x, C
From langref:
nuw and nsw stand for “No Unsigned Wrap” and “No Signed Wrap”, respectively. If the nuw and/or nsw keywords are present, the result value of the add is a poison value if unsigned and/or signed overflow, respectively, occurs.
So if C is -1, %x can only be 0, and the result is always -1.
I'm not sure we want to use KnownBits/LVI here, because there is
exactly one possible value (all bits set, -1), so some other pass
should take care of replacing the known-all-ones with constant -1.
The test/Transforms/InstCombine/set-lowbits-mask-canonicalize.ll change *is* confusing.
What happening is, before this: (omitting nuw for simplicity)
- First, InstCombine D47428/rL334127 folds shl i32 1, %NBits) to shl nuw i32 -1, %NBits
- Then, InstSimplify D47883/rL334222 folds shl nuw i32 -1, %NBits to -1,
- -1 is inverted to 0.
But now:
- *This* InstSimplify fold %ret = add nuw i32 %setbit, -1 -> -1 happens first, before InstCombine D47428/rL334127 fold could happen.
Thus we now end up with the opposite constant,
and it is all good: https://rise4fun.com/Alive/OA9
https://rise4fun.com/Alive/sldC
Was mentioned in D47428 review.
Follow-up for D47883.