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).

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