The order of the arguments for minmax_from_comparison is wrong for this
pattern. I swapped the 2 CST which in some cases could cause
incorrect code.
Pushed as obvious after a bootstrap/testing on x86_64-linux-gnu.
Note for backporting, minmax-29.c and minmax-30.c will need to be
changed slightly because we don't factor out the min/max before GCC 17.
PR tree-optimization/126456
gcc/ChangeLog:
* match.pd (`a CMP b ? MIN/MAX<a, c> : MIN/MAX<a, d>`): Fix
order of minmax_from_comparison arguments.
gcc/testsuite/ChangeLog:
* gcc.dg/torture/minmax-1.c: New test.
* gcc.dg/tree-ssa/minmax-29.c: New test.
* gcc.dg/tree-ssa/minmax-30.c: New test.
* gcc.dg/tree-ssa/minmax-31.c: New test.
* gcc.dg/tree-ssa/minmax-32.c: New test.
Signed-off-by: Andrea Pinski <[email protected]>
---
gcc/match.pd | 2 +-
gcc/testsuite/gcc.dg/torture/minmax-1.c | 28 ++++++++++++++++++++
gcc/testsuite/gcc.dg/tree-ssa/minmax-29.c | 31 +++++++++++++++++++++++
gcc/testsuite/gcc.dg/tree-ssa/minmax-30.c | 30 ++++++++++++++++++++++
gcc/testsuite/gcc.dg/tree-ssa/minmax-31.c | 30 ++++++++++++++++++++++
gcc/testsuite/gcc.dg/tree-ssa/minmax-32.c | 29 +++++++++++++++++++++
6 files changed, 149 insertions(+), 1 deletion(-)
create mode 100644 gcc/testsuite/gcc.dg/torture/minmax-1.c
create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/minmax-29.c
create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/minmax-30.c
create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/minmax-31.c
create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/minmax-32.c
diff --git a/gcc/match.pd b/gcc/match.pd
index 83418241bd9..9b14a042d05 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -6917,7 +6917,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
(cond (cmp:c @1 @3) (minmax:c @1 @4) (minmax:c @2 @4))
(with
{
- tree_code code = minmax_from_comparison (cmp, @1, @2, @1, @3);
+ tree_code code = minmax_from_comparison (cmp, @1, @3, @1, @2);
}
(if (code == MIN_EXPR)
(minmax (min @1 @2) @4)
diff --git a/gcc/testsuite/gcc.dg/torture/minmax-1.c
b/gcc/testsuite/gcc.dg/torture/minmax-1.c
new file mode 100644
index 00000000000..875f2455365
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/minmax-1.c
@@ -0,0 +1,28 @@
+/* { dg-do run } */
+/* PR tree-optimization/126456 */
+
+/* These should not produce min/max for
+ the outer conditional. */
+
+__attribute__((noipa)) int
+min_le (int a, int c)
+{
+ return (a <= 6) ? (a < c ? a : c) : (5 < c ? 5 : c);
+}
+
+__attribute__((noipa)) int
+max_ge (int a, int c)
+{
+ return (a >= 4) ? (a > c ? a : c) : (5 > c ? 5 : c);
+}
+
+int
+main (void)
+{
+ if (min_le (6, 10) != 6)
+ __builtin_abort ();
+ if (max_ge (4, 0) != 4)
+ __builtin_abort ();
+ return 0;
+}
+
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/minmax-29.c
b/gcc/testsuite/gcc.dg/tree-ssa/minmax-29.c
new file mode 100644
index 00000000000..8779c08a30d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/minmax-29.c
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-optimized" } */
+
+/* These should not produce max, only 3 min and there should be an if left. */
+
+__attribute__((noipa)) int
+min_le (int a, int c)
+{
+ return (a <= 6) ? (a < c ? a : c) : (5 < c ? 5 : c);
+}
+
+int
+min_le_1 (int a, int c)
+{
+ if (a <= 6)
+ return (a < c ? a : c);
+ return (5 < c ? 5 : c);
+}
+
+int
+min_le_2 (int a, int c)
+{
+ int t = (a < c ? a : c);
+ int t1 = (5 < c ? 5 : c);
+ if (a <= 6)
+ return t;
+ return t1;
+}
+/* { dg-final { scan-tree-dump-not "MAX_EXPR " "optimized" } } */
+/* { dg-final { scan-tree-dump-times "MIN_EXPR " 3 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "if " 3 "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/minmax-30.c
b/gcc/testsuite/gcc.dg/tree-ssa/minmax-30.c
new file mode 100644
index 00000000000..eb0c4499001
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/minmax-30.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-optimized" } */
+
+/* These should not produce min, only 3 max and there should be an if left. */
+int
+max_ge (int a, int c)
+{
+ return (a >= 4) ? (a > c ? a : c) : (5 > c ? 5 : c);
+}
+
+int
+max_ge_1 (int a, int c)
+{
+ int t = (a > c ? a : c);
+ int t1 = (5 > c ? 5 : c);
+ return (a >= 4) ? t : t1;
+}
+
+int
+max_ge_2 (int a, int c)
+{
+ if (a >= 4)
+ return (a > c ? a : c);
+ return (5 > c ? 5 : c);
+}
+
+
+/* { dg-final { scan-tree-dump-times "MAX_EXPR " 3 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "if " 3 "optimized" } } */
+/* { dg-final { scan-tree-dump-not "MIN_EXPR " "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/minmax-31.c
b/gcc/testsuite/gcc.dg/tree-ssa/minmax-31.c
new file mode 100644
index 00000000000..95f815e16bc
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/minmax-31.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-optimized" } */
+
+/* These should produce 2x min for each function. */
+
+__attribute__((noipa)) int
+min_le (int a, int c)
+{
+ return (a < 5) ? (a < c ? a : c) : (5 < c ? 5 : c);
+}
+
+int
+min_le_1 (int a, int c)
+{
+ if (a < 5)
+ return (a < c ? a : c);
+ return (5 < c ? 5 : c);
+}
+
+int
+min_le_2 (int a, int c)
+{
+ int t = (a < c ? a : c);
+ int t1 = (5 < c ? 5 : c);
+ if (a < 5)
+ return t;
+ return t1;
+}
+/* { dg-final { scan-tree-dump-not "MAX_EXPR " "optimized" } } */
+/* { dg-final { scan-tree-dump-times "MIN_EXPR " 6 "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/minmax-32.c
b/gcc/testsuite/gcc.dg/tree-ssa/minmax-32.c
new file mode 100644
index 00000000000..390cd874ce8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/minmax-32.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-optimized" } */
+
+/* These should produce 2x max for each function. */
+int
+max_ge (int a, int c)
+{
+ return (a > 4) ? (a > c ? a : c) : (5 > c ? 5 : c);
+}
+
+int
+max_ge_1 (int a, int c)
+{
+ int t = (a > c ? a : c);
+ int t1 = (5 > c ? 5 : c);
+ return (a > 4) ? t : t1;
+}
+
+int
+max_ge_2 (int a, int c)
+{
+ if (a > 4)
+ return (a > c ? a : c);
+ return (5 > c ? 5 : c);
+}
+
+
+/* { dg-final { scan-tree-dump-times "MAX_EXPR " 6 "optimized" } } */
+/* { dg-final { scan-tree-dump-not "MIN_EXPR " "optimized" } } */
--
2.43.0