https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66299
--- Comment #2 from Jakub Jelinek <jakub at gcc dot gnu.org> --- I'd think using a volatile var in the optimization test is highly undesirable, that can mean stopping optimizations differently between different compilers. But, the same thing can be reproduced with: void foo (signed int x) { unsigned int t = ((unsigned int) 1U << x); if (t != 2U) __builtin_abort (); } Perhaps we should have a match.pd simplification of (const1 << var) {==,!=} const2, perhaps something even for {<,<=,>,>=} if they could be simplified to a simple comparison of var and const3; supposedly guarded with single use of the shift. What about >> ? Other arithmetics single use operations (e.g. 2U * var == 16)? For addition of a constant apparently forwprop1 already optimizes that.