diff mbox series

match.pd handling of three-constant bitops

Message ID 87bmm51s2o.fsf@linaro.org
State New
Headers show
Series match.pd handling of three-constant bitops | expand

Commit Message

Richard Sandiford Sept. 20, 2017, 12:18 p.m. UTC
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?

Richard


2017-09-20  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.

Comments

Richard Biener Sept. 20, 2017, 3:58 p.m. UTC | #1
On Wed, Sep 20, 2017 at 2:18 PM, Richard Sandiford
<richard.sandiford@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?

> Richard
>
>
> 2017-09-20  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.
>
> Index: gcc/match.pd
> ===================================================================
> --- gcc/match.pd        2017-09-16 21:38:21.106513157 +0100
> +++ gcc/match.pd        2017-09-20 13:17:10.552389270 +0100
> @@ -1017,7 +1017,14 @@ 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))
> +   (bitop @0 (bitop @1 @2))
> +   (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.  */
Richard Sandiford Sept. 21, 2017, 11:17 a.m. UTC | #2
Richard Biener <richard.guenther@gmail.com> writes:
> On Wed, Sep 20, 2017 at 2:18 PM, Richard Sandiford
> <richard.sandiford@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.

Thanks,
Richard
Richard Biener Sept. 21, 2017, 11:42 a.m. UTC | #3
On Thu, Sep 21, 2017 at 1:17 PM, Richard Sandiford
<richard.sandiford@linaro.org> wrote:
> Richard Biener <richard.guenther@gmail.com> writes:
>> On Wed, Sep 20, 2017 at 2:18 PM, Richard Sandiford
>> <richard.sandiford@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,
Richard.

>
> Thanks,
> Richard
Richard Sandiford Jan. 3, 2018, 7:25 a.m. UTC | #4
Richard Biener <richard.guenther@gmail.com> writes:
> On Thu, Sep 21, 2017 at 1:17 PM, Richard Sandiford
> <richard.sandiford@linaro.org> wrote:
>> Richard Biener <richard.guenther@gmail.com> writes:
>>> On Wed, Sep 20, 2017 at 2:18 PM, Richard Sandiford
>>> <richard.sandiford@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.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.
------------------------------------------------------------------------------

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.  */
diff mbox series

Patch

Index: gcc/match.pd
===================================================================
--- gcc/match.pd	2017-09-16 21:38:21.106513157 +0100
+++ gcc/match.pd	2017-09-20 13:17:10.552389270 +0100
@@ -1017,7 +1017,14 @@  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))
+   (bitop @0 (bitop @1 @2))
+   (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.  */