aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Guenther <rguenther@suse.de>2006-08-11 07:44:45 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2006-08-11 07:44:45 +0000
commite0d0c1939bb8267a7b1dac0aedaa8e8c22ef2cad (patch)
treeab98ba9561a282ffc55741231132e99c53814c2a /gcc
parent9b514d4c6553c0f113a46949db4776788f5bfba5 (diff)
downloadgcc-e0d0c1939bb8267a7b1dac0aedaa8e8c22ef2cad.zip
gcc-e0d0c1939bb8267a7b1dac0aedaa8e8c22ef2cad.tar.gz
gcc-e0d0c1939bb8267a7b1dac0aedaa8e8c22ef2cad.tar.bz2
re PR middle-end/28651 (signed compare incorrectly false for (int)(U+4)<(int)U where U is unsigned INT_MAX (for optimized x86))
2006-08-11 Richard Guenther <rguenther@suse.de> PR middle-end/28651 * simplify-rtx.c (simplify_const_relational_operation): Simplify A CMP B to A - B CMP 0 only for EQ and NE comparison codes. * gcc.c-torture/execute/pr28651.c: New testcase. From-SVN: r116079
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/simplify-rtx.c17
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/pr28651.c24
4 files changed, 44 insertions, 9 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index d42b0aa..92fd1fe 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2006-08-11 Richard Guenther <rguenther@suse.de>
+
+ PR middle-end/28651
+ * simplify-rtx.c (simplify_const_relational_operation):
+ Simplify A CMP B to A - B CMP 0 only for EQ and NE comparison
+ codes.
+
2006-08-10 Eric Botcazou <ebotcazou@adacore.com>
* tree.c (build1_stat): Also propagate the TREE_CONSTANT and
diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c
index 3f627e5..8c437e4 100644
--- a/gcc/simplify-rtx.c
+++ b/gcc/simplify-rtx.c
@@ -3733,19 +3733,18 @@ simplify_const_relational_operation (enum rtx_code code,
a register or a CONST_INT, this can't help; testing for these cases will
prevent infinite recursion here and speed things up.
- If CODE is an unsigned comparison, then we can never do this optimization,
- because it gives an incorrect result if the subtraction wraps around zero.
- ANSI C defines unsigned operations such that they never overflow, and
- thus such cases can not be ignored; but we cannot do it even for
- signed comparisons for languages such as Java, so test flag_wrapv. */
+ We can only do this for EQ and NE comparisons as otherwise we may
+ lose or introduce overflow which we cannot disregard as undefined as
+ we do not know the signedness of the operation on either the left or
+ the right hand side of the comparison. */
- if (!flag_wrapv && INTEGRAL_MODE_P (mode) && trueop1 != const0_rtx
+ if (INTEGRAL_MODE_P (mode) && trueop1 != const0_rtx
+ && (code == EQ || code == NE)
&& ! ((REG_P (op0) || GET_CODE (trueop0) == CONST_INT)
&& (REG_P (op1) || GET_CODE (trueop1) == CONST_INT))
&& 0 != (tem = simplify_binary_operation (MINUS, mode, op0, op1))
- /* We cannot do this for == or != if tem is a nonzero address. */
- && ((code != EQ && code != NE) || ! nonzero_address_p (tem))
- && code != GTU && code != GEU && code != LTU && code != LEU)
+ /* We cannot do this if tem is a nonzero address. */
+ && ! nonzero_address_p (tem))
return simplify_const_relational_operation (signed_condition (code),
mode, tem, const0_rtx);
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 44a4894..3bc320f 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2006-08-11 Richard Guenther <rguenther@suse.de>
+
+ PR middle-end/28651
+ * gcc.c-torture/execute/pr28651.c: New testcase.
+
2006-08-10 Eric Botcazou <ebotcazou@adacore.com>
* gnat.dg/specs/static_initializer.ads: New test.
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr28651.c b/gcc/testsuite/gcc.c-torture/execute/pr28651.c
new file mode 100644
index 0000000..1262f9f
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/pr28651.c
@@ -0,0 +1,24 @@
+extern void abort (void);
+int
+foo (unsigned int u)
+{
+ return (int)(u + 4) < (int)u;
+}
+
+int
+main (int argc, char *argv[])
+{
+ unsigned int u;
+
+ /* Run with no arguments so u will be MAX_INT and the optimizers
+ won't know its value. */
+ if (argc > 1)
+ u = 1;
+ else
+ u = 0x7fffffff;
+
+ if (foo (u) == 0)
+ abort();
+ return 0;
+}
+