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)

Reply via email to