match.pd handling of three-constant bitops
authorRichard Sandiford <richard.sandiford@linaro.org>
Wed, 3 Jan 2018 07:13:57 +0000 (07:13 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Wed, 3 Jan 2018 07:13:57 +0000 (07:13 +0000)
natch.pd tries to reassociate two bit operations if both of them have
constant operands.  However, with the polynomial integers added later,
there's no guarantee that a bit operation on two integers can be folded
at compile time.  This means that the pattern can trigger for operations
on three constants, and as things stood could endlessly oscillate
between the two associations.

This patch keeps the existing pattern for the normal case of a
non-constant first operand.  When all three operands are constant it
tries to find a pair of constants that do fold.  If none do, it keeps
the original expression as-was.

2018-01-03  Richard Sandiford  <richard.sandiford@linaro.org>
    Alan Hayward  <alan.hayward@arm.com>
    David Sherwood  <david.sherwood@arm.com>

gcc/
* match.pd: Handle bit operations involving three constants
and try to fold one pair.

Co-Authored-By: Alan Hayward <alan.hayward@arm.com>
Co-Authored-By: David Sherwood <david.sherwood@arm.com>
From-SVN: r256125

gcc/ChangeLog
gcc/match.pd

index e0a2f3c0cc7ff154b7aae82e4f63235300bbb966..d3d6fff62e92c385e27ba37223347be00f5a277d 100644 (file)
@@ -1,3 +1,10 @@
+2018-01-03  Richard Sandiford  <richard.sandiford@linaro.org>
+           Alan Hayward  <alan.hayward@arm.com>
+           David Sherwood  <david.sherwood@arm.com>
+
+       * match.pd: Handle bit operations involving three constants
+       and try to fold one pair.
+
 2018-01-03  Richard Sandiford  <richard.sandiford@linaro.org>
 
        * tree-vect-loop-manip.c: Include gimple-fold.h.
index 87012a243191e23e719a0e2766447c83d7adba91..06af2a72213316b8fe31d7a1ea8c0d658ef96e84 100644 (file)
@@ -1111,7 +1111,24 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
 (for bitop (bit_and bit_ior bit_xor)
  (simplify
   (bitop (bitop @0 CONSTANT_CLASS_P@1) CONSTANT_CLASS_P@2)
-  (bitop @0 (bitop @1 @2))))
+  (if (!CONSTANT_CLASS_P (@0))
+   /* This is the canonical form regardless of whether (bitop @1 @2) can be
+      folded to a constant.  */
+   (bitop @0 (bitop @1 @2))
+   /* In this case we have three constants and (bitop @0 @1) doesn't fold
+      to a constant.  This can happen if @0 or @1 is a POLY_INT_CST and if
+      the values involved are such that the operation can't be decided at
+      compile time.  Try folding one of @0 or @1 with @2 to see whether
+      that combination can be decided at compile time.
+
+      Keep the existing form if both folds fail, to avoid endless
+      oscillation.  */
+   (with { tree cst1 = const_binop (bitop, type, @0, @2); }
+    (if (cst1)
+     (bitop @1 { cst1; })
+     (with { tree cst2 = const_binop (bitop, type, @1, @2); }
+      (if (cst2)
+       (bitop @0 { cst2; }))))))))
 
 /* Try simple folding for X op !X, and X op X with the help
    of the truth_valued_p and logical_inverted_value predicates.  */