https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85234
--- Comment #4 from Andrew Pinski <pinskia at gcc dot gnu.org> --- Here are some testcases dealing with this and showing what still needs to be done: ``` #define N 3 #define unsigned int #define cmp != _Bool rshift(unsigned x, int t) { return (x << N) cmp 0; } _Bool rshift1(unsigned x, int t) { return (x & (-1u>>N)) cmp 0; } _Bool lshift(unsigned x, int t) { return (x >> N) cmp 0; } _Bool lshift1(unsigned x, int t) { return (x & (-1u<<N)) cmp 0; } _Bool lshift2(unsigned x, int t) { return (x >= (1u<<N)) cmp 0; } ``` GCC handles lshift1 to lshift2 just fine. But not lshift to lshift1 and rshift to rshift1. Note GCC does the correct thing rshift/rshift1 even for riscv32 where forming an constant for the and is hard.