Richard Biener <richard.guent...@gmail.com> writes:
> On Thu, Sep 21, 2017 at 1:17 PM, Richard Sandiford
> <richard.sandif...@linaro.org> wrote:
>> Richard Biener <richard.guent...@gmail.com> writes:
>>> On Wed, Sep 20, 2017 at 2:18 PM, Richard Sandiford
>>> <richard.sandif...@linaro.org> wrote:
>>>> 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.
>>>>
>>>> Tested on aarch64-linux-gnu, x86_64-linux-gnu and powerpc64le-linus-gnu.
>>>> OK to install?
>>>
>>> Hmm, is the complication with trying variants necessary or could we simply 
>>> do
>>>
>>>  if (!CONSTANT_CLASS_P (@0))
>>>   (bitop @0 (bitop @1 @2))
>>>
>>> and be done with it?
>>
>> That's enough to fix the oscillation, but there are cases that benefit
>> from trying the other combinations.  E.g. if @1 and @2 are both
>> INTEGER_CSTs, it's still worth folding them.  POLY_CST | INTEGER_CST
>> is supported for some values, so if @0 | @1 doesn't fold, it's worth
>> trying @0 | @2 instead.
>
> Hmm, ok.
>
> The patch is ok then if you add a comment reflecting the above.

Thanks.  For the record, here's what I installed after retesting.

Richard


2018-01-03  Richard Sandiford  <richard.sandif...@linaro.org>
            Alan Hayward  <alan.hayw...@arm.com>
            David Sherwood  <david.sherw...@arm.com>

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

Index: gcc/match.pd
===================================================================
--- gcc/match.pd        2018-01-02 16:55:03.498204314 +0000
+++ gcc/match.pd        2018-01-03 07:10:06.993953631 +0000
@@ -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.  */

Reply via email to