If we have a pattern (x & (-1 >> maskNbits)) << shiftNbits,
we already know (have a fold) that will drop the & (-1 >> maskNbits)
mask iff (shiftNbits-maskNbits) s>= 0 (i.e. shiftNbits u>= maskNbits).
So even if (shiftNbits-maskNbits) s< 0, we can still
fold, we will just need to apply a constant mask afterwards:
Name: c, normal+mask %t0 = lshr i32 -1, C1 %t1 = and i32 %t0, %x %r = shl i32 %t1, C2 => %n0 = shl i32 %x, C2 %n1 = i32 ((-(C2-C1))+32) %n2 = zext i32 %n1 to i64 %n3 = lshr i64 -1, %n2 %n4 = trunc i64 %n3 to i32 %r = and i32 %n0, %n4
https://rise4fun.com/Alive/gslRa
Naturally, old %masked will have to be one-use.
This is not valid for pattern f - where "masking" is done via ashr.
Did we ensure that Masked is not a ConstantExpr? If so, add an assert that Masked must be an Instruction here or somewhere above here?