This is PR37603.
https://godbolt.org/g/VCMNpS
https://rise4fun.com/Alive/idM
When doing bit manipulations, it is quite common to calculate some bit mask,
and apply it to some value via and.
The typical C code looks like:
int mask_signed_add(int nbits) { return (1 << nbits) - 1; }
which is translated into (with -O3)
define dso_local i32 @mask_signed_add(int)(i32) local_unnamed_addr #0 { %2 = shl i32 1, %0 %3 = add nsw i32 %2, -1 ret i32 %3 }
But there is a second, less readable variant:
int mask_signed_xor(int nbits) { return ~(-(1 << nbits)); }
which is translated into (with -O3)
define dso_local i32 @mask_signed_xor(int)(i32) local_unnamed_addr #0 { %2 = shl i32 -1, %0 %3 = xor i32 %2, -1 ret i32 %3 }
Since we created such a mask, it is quite likely that we will use it in and next.
And then we may get rid of not op by folding into andn.
But now that i have actually looked:
https://godbolt.org/g/VTUDmU
_some_ backend changes will be needed too.
We clearly loose bzhi recognition.