https://gcc.gnu.org/bugzilla/show_bug.cgi?id=55177
--- Comment #20 from Andrew Pinski <pinskia at gcc dot gnu.org> --- So the original testcase shows there are missing other bitop related optimizations on the tree level and conversions. I have two patches which fix the original issue. The first patch also fixes: unsigned foo(unsigned x, int b) { int a = x; a &= b; x = a; x |= b; return x; } --- CUT --- The problem here is: a_3 = (int) x_2(D); a_5 = a_3 & b_4(D); x_6 = (unsigned int) a_5; is not optimized to: _7 = (unsigned int) b_4(D); x_6 = _6 & x_2(D); Which shows up in testcase in comment #0: _2 = __builtin_bswap32 (x.0_1); a_6 = (int) _2; a_7 = a_6 & 1515936861; a.1_3 = (unsigned int) a_7; _4 = __builtin_bswap32 (a.1_3); Fixing the bitop with convert, we get rid of the two byteswaps in comment #0. diff --git a/gcc/match.pd b/gcc/match.pd index 363006e28fd..d0258a19534 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -1393,7 +1393,12 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) /* Or if the precision of TO is not the same as the precision of its mode. */ || !type_has_mode_precision_p (type))) - (convert (bitop @0 (convert @1)))))) + (convert (bitop @0 (convert @1))))) + (simplify + (convert (bitop:c (nop_convert @0) @1)) + (if (tree_nop_conversion_p (type, TREE_TYPE (@1)) + && types_match (type, TREE_TYPE (@0))) + (bitop @0 (convert @1))))) (for bitop (bit_and bit_ior) rbitop (bit_ior bit_and)