aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorAndrew Pinski <apinski@marvell.com>2023-09-07 22:13:31 -0700
committerAndrew Pinski <apinski@marvell.com>2023-09-10 08:46:44 -0700
commit30e6ee074588bacefd2dfe745b188bb20c81fe5e (patch)
tree26d08fd3bac30811c0b63a4d2bc16b66cedfaba7 /gcc
parent5b33b364652866165431aef1810af1e890229c5e (diff)
downloadgcc-30e6ee074588bacefd2dfe745b188bb20c81fe5e.zip
gcc-30e6ee074588bacefd2dfe745b188bb20c81fe5e.tar.gz
gcc-30e6ee074588bacefd2dfe745b188bb20c81fe5e.tar.bz2
Fix PR 111331: wrong code for `a > 28 ? MIN<a, 28> : 29`
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. The match pattern copied the same logic mistake when they were added in r14-1411-g17cca3c43e2f49 . OK? Bootstrapped and tested on x86_64-linux-gnu. gcc/ChangeLog: PR tree-optimization/111331 * match.pd (`(a CMP CST1) ? max<a,CST2> : a`): Fix the LE/GE comparison to the correct value. * 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.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/match.pd4
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/pr111331-1.c17
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/pr111331-2.c19
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/pr111331-3.c15
-rw-r--r--gcc/tree-ssa-phiopt.cc8
5 files changed, 57 insertions, 6 deletions
diff --git a/gcc/match.pd b/gcc/match.pd
index 8c24dae..c7b6db4 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -5438,11 +5438,11 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
}
(if ((cmp == LT_EXPR || cmp == LE_EXPR)
&& code == MIN_EXPR
- && integer_nonzerop (fold_build2 (LE_EXPR, boolean_type_node, @3, @1)))
+ && integer_nonzerop (fold_build2 (LE_EXPR, boolean_type_node, @3, @4)))
(min @2 @4)
(if ((cmp == GT_EXPR || cmp == GE_EXPR)
&& code == MAX_EXPR
- && integer_nonzerop (fold_build2 (GE_EXPR, boolean_type_node, @3, @1)))
+ && integer_nonzerop (fold_build2 (GE_EXPR, boolean_type_node, @3, @4)))
(max @2 @4))))))
#if GIMPLE
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
index 0000000..4c7f4fd
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/pr111331-1.c
@@ -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
index 0000000..5c677f2
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/pr111331-2.c
@@ -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
index 0000000..213d9bd
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/pr111331-3.c
@@ -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;
+}
diff --git a/gcc/tree-ssa-phiopt.cc b/gcc/tree-ssa-phiopt.cc
index 3148ad3..3835d25 100644
--- a/gcc/tree-ssa-phiopt.cc
+++ b/gcc/tree-ssa-phiopt.cc
@@ -2070,7 +2070,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)
@@ -2101,7 +2101,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
@@ -2141,7 +2141,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)
@@ -2168,7 +2168,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