On February 15, 2020 7:09:51 AM GMT+01:00, Jakub Jelinek <ja...@redhat.com> 
wrote:
>Hi!
>
>As the following testcases show (the first one reported, last two
>found by code inspection), we need to disallow side-effects
>in simplifications that turn some unconditional expression into
>conditional
>one.  From my little understanding of genmatch.c, it is able to
>automatically disallow side effects if the same operand is used
>multiple
>times in the match pattern, maybe if it is used multiple times in the
>replacement pattern, and if it is used in conditional contexts in the
>match
>pattern, could it be taught to handle this case too?  If yes, perhaps
>just the first hunk could be usable for 8/9 backports (+ the
>testcases).

It could possibly be done but then it's only three cases so far. 

OK. 

Richard. 

>Bootstrapped/regtested on x86_64-linux and i686-linux.
>
>2020-02-15  Jakub Jelinek  <ja...@redhat.com>
>
>       PR tree-optimization/93744
>       * match.pd (((m1 >/</>=/<= m2) * d -> (m1 >/</>=/<= m2) ? d : 0,
>       A - ((A - B) & -(C cmp D)) -> (C cmp D) ? B : A,
>       A + ((B - A) & -(C cmp D)) -> (C cmp D) ? B : A): For GENERIC, make
>       sure @2 in the first and @1 in the other patterns has no side-effects.
>
>       * gcc.c-torture/execute/pr93744-1.c: New test.
>       * gcc.c-torture/execute/pr93744-2.c: New test.
>       * gcc.c-torture/execute/pr93744-3.c: New test.
>
>--- gcc/match.pd.jj    2020-02-05 11:12:33.679383217 +0100
>+++ gcc/match.pd       2020-02-14 22:49:22.858771394 +0100
>@@ -1472,7 +1472,8 @@ (define_operator_list COND_TERNARY
> (for cmp (gt lt ge le)
> (simplify
>  (mult (convert (cmp @0 @1)) @2)
>-  (cond (cmp @0 @1) @2 { build_zero_cst (type); })))
>+  (if (GIMPLE || !TREE_SIDE_EFFECTS (@2))
>+   (cond (cmp @0 @1) @2 { build_zero_cst (type); }))))
> 
> /* For integral types with undefined overflow and C != 0 fold
>    x * C EQ/NE y * C into x EQ/NE y.  */
>@@ -2709,7 +2710,8 @@ (define_operator_list COND_TERNARY
>        && TREE_CODE (TREE_TYPE (@4)) != BOOLEAN_TYPE
>        && INTEGRAL_TYPE_P (TREE_TYPE (@5))
>        && (TYPE_PRECISION (TREE_TYPE (@4)) >= TYPE_PRECISION (type)
>-         || !TYPE_UNSIGNED (TREE_TYPE (@4))))
>+         || !TYPE_UNSIGNED (TREE_TYPE (@4)))
>+       && (GIMPLE || !TREE_SIDE_EFFECTS (@1)))
>    (cond (cmp @2 @3) @1 @0)))
>  (simplify
>   (plus:c @0 (bit_and:c (minus @1 @0)
>@@ -2719,7 +2721,8 @@ (define_operator_list COND_TERNARY
>        && TREE_CODE (TREE_TYPE (@4)) != BOOLEAN_TYPE
>        && INTEGRAL_TYPE_P (TREE_TYPE (@5))
>        && (TYPE_PRECISION (TREE_TYPE (@4)) >= TYPE_PRECISION (type)
>-         || !TYPE_UNSIGNED (TREE_TYPE (@4))))
>+         || !TYPE_UNSIGNED (TREE_TYPE (@4)))
>+       && (GIMPLE || !TREE_SIDE_EFFECTS (@1)))
>    (cond (cmp @2 @3) @1 @0))))
> 
> /* Simplifications of shift and rotates.  */
>--- gcc/testsuite/gcc.c-torture/execute/pr93744-1.c.jj 2020-02-14
>22:50:58.993346192 +0100
>+++ gcc/testsuite/gcc.c-torture/execute/pr93744-1.c    2020-02-14
>22:49:57.934251395 +0100
>@@ -0,0 +1,14 @@
>+/* PR tree-optimization/93744 */
>+
>+typedef int I;
>+
>+int
>+main ()
>+{
>+  int a = 0;
>+  I b = 0;
>+  (a > 0) * (b |= 2);
>+  if (b != 2)
>+    __builtin_abort ();
>+  return 0;
>+}
>--- gcc/testsuite/gcc.c-torture/execute/pr93744-2.c.jj 2020-02-14
>22:51:01.100314955 +0100
>+++ gcc/testsuite/gcc.c-torture/execute/pr93744-2.c    2020-02-14
>22:50:18.299949478 +0100
>@@ -0,0 +1,21 @@
>+/* PR tree-optimization/93744 */
>+
>+int w;
>+
>+int
>+foo (int x, int y, int z)
>+{
>+  int r = z - ((z - w++) & -(x < y));
>+  return r;
>+}
>+
>+int
>+main ()
>+{
>+  w = 4;
>+  if (foo (5, 7, 12) != 4 || w != 5)
>+    __builtin_abort ();
>+  if (foo (7, 5, 12) != 12 || w != 6)
>+    __builtin_abort ();
>+  return 0;
>+}
>--- gcc/testsuite/gcc.c-torture/execute/pr93744-3.c.jj 2020-02-14
>22:51:03.415280636 +0100
>+++ gcc/testsuite/gcc.c-torture/execute/pr93744-3.c    2020-02-14
>22:50:25.820837971 +0100
>@@ -0,0 +1,21 @@
>+/* PR tree-optimization/93744 */
>+
>+int w;
>+
>+int
>+foo (int x, int y, int z)
>+{
>+  int r = z + ((w++ - z) & -(x < y));
>+  return r;
>+}
>+
>+int
>+main ()
>+{
>+  w = 4;
>+  if (foo (5, 7, 12) != 4 || w != 5)
>+    __builtin_abort ();
>+  if (foo (7, 5, 12) != 12 || w != 6)
>+    __builtin_abort ();
>+  return 0;
>+}
>
>       Jakub

Reply via email to