]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Fix PR 111331: wrong code for `a > 28 ? MIN<a, 28> : 29`
authorAndrew Pinski <apinski@marvell.com>
Fri, 8 Sep 2023 05:13:31 +0000 (22:13 -0700)
committerAndrew Pinski <pinskia@gmail.com>
Sun, 1 Oct 2023 19:48:24 +0000 (12:48 -0700)
The problem here is after r6-7425-ga9fee7cdc3c62d0e51730,
the comparison to see if the transformation could be done was using the
wrong value. Instead of see if the inner was LE (for MIN and GE for MAX)
the outer value, it was comparing the inner to the value used in the comparison
which was wrong.

Committed to GCC 13 branch after bootstrapped and tested on x86_64-linux-gnu.

gcc/ChangeLog:

PR tree-optimization/111331
* tree-ssa-phiopt.cc (minmax_replacement):
Fix the LE/GE comparison for the
`(a CMP CST1) ? max<a,CST2> : a` optimization.

gcc/testsuite/ChangeLog:

PR tree-optimization/111331
* gcc.c-torture/execute/pr111331-1.c: New test.
* gcc.c-torture/execute/pr111331-2.c: New test.
* gcc.c-torture/execute/pr111331-3.c: New test.

(cherry picked from commit 30e6ee074588bacefd2dfe745b188bb20c81fe5e)

gcc/testsuite/gcc.c-torture/execute/pr111331-1.c [new file with mode: 0644]
gcc/testsuite/gcc.c-torture/execute/pr111331-2.c [new file with mode: 0644]
gcc/testsuite/gcc.c-torture/execute/pr111331-3.c [new file with mode: 0644]
gcc/tree-ssa-phiopt.cc

diff --git a/gcc/testsuite/gcc.c-torture/execute/pr111331-1.c b/gcc/testsuite/gcc.c-torture/execute/pr111331-1.c
new file mode 100644 (file)
index 0000000..4c7f4fd
--- /dev/null
@@ -0,0 +1,17 @@
+int a;
+int b;
+int c(int d, int e, int f) {
+  if (d < e)
+    return e;
+  if (d > f)
+    return f;
+  return d;
+}
+int main() {
+  int g = -1;
+  a = c(b + 30, 29, g + 29);
+  volatile t = a;
+  if (t != 28)
+    __builtin_abort();
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr111331-2.c b/gcc/testsuite/gcc.c-torture/execute/pr111331-2.c
new file mode 100644 (file)
index 0000000..5c677f2
--- /dev/null
@@ -0,0 +1,19 @@
+
+int a;
+int b;
+
+int main() {
+  int d = b+30;
+  {
+        int t;
+        if (d < 29)
+          t =  29;
+        else
+          t = (d > 28) ? 28 : d;
+    a = t;
+  }
+  volatile int t = a;
+  if (a != 28)
+    __builtin_abort();
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr111331-3.c b/gcc/testsuite/gcc.c-torture/execute/pr111331-3.c
new file mode 100644 (file)
index 0000000..213d9bd
--- /dev/null
@@ -0,0 +1,15 @@
+int a;
+int b;
+
+int main() {
+  int d = b+30;
+  {
+    int t;
+    t = d < 29 ? 29 : ((d > 28) ? 28 : d);
+    a = t;
+  }
+  volatile int t = a;
+  if (a != 28)
+    __builtin_abort();
+  return 0;
+}
index a7ab6ce4ad90b4088b942ea6ad6430beb0c5dcd9..c3d78d1400bb2d029ead6e2eb9929dd35a09d3cf 100644 (file)
@@ -2270,7 +2270,7 @@ minmax_replacement (basic_block cond_bb, basic_block middle_bb, basic_block alt_
 
              /* We need BOUND <= LARGER.  */
              if (!integer_nonzerop (fold_build2 (LE_EXPR, boolean_type_node,
-                                                 bound, larger)))
+                                                 bound, arg_false)))
                return false;
            }
          else if (operand_equal_for_phi_arg_p (arg_false, smaller)
@@ -2301,7 +2301,7 @@ minmax_replacement (basic_block cond_bb, basic_block middle_bb, basic_block alt_
 
              /* We need BOUND >= SMALLER.  */
              if (!integer_nonzerop (fold_build2 (GE_EXPR, boolean_type_node,
-                                                 bound, smaller)))
+                                                 bound, arg_false)))
                return false;
            }
          else
@@ -2341,7 +2341,7 @@ minmax_replacement (basic_block cond_bb, basic_block middle_bb, basic_block alt_
 
              /* We need BOUND >= LARGER.  */
              if (!integer_nonzerop (fold_build2 (GE_EXPR, boolean_type_node,
-                                                 bound, larger)))
+                                                 bound, arg_true)))
                return false;
            }
          else if (operand_equal_for_phi_arg_p (arg_true, smaller)
@@ -2368,7 +2368,7 @@ minmax_replacement (basic_block cond_bb, basic_block middle_bb, basic_block alt_
 
              /* We need BOUND <= SMALLER.  */
              if (!integer_nonzerop (fold_build2 (LE_EXPR, boolean_type_node,
-                                                 bound, smaller)))
+                                                 bound, arg_true)))
                return false;
            }
          else