re PR middle-end/28651 (signed compare incorrectly false for (int)(U+4)<(int)U where...
authorRichard Guenther <rguenther@suse.de>
Fri, 11 Aug 2006 07:44:45 +0000 (07:44 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Fri, 11 Aug 2006 07:44:45 +0000 (07:44 +0000)
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

gcc/ChangeLog
gcc/simplify-rtx.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/execute/pr28651.c [new file with mode: 0644]

index d42b0aa3f4aa84155ff0b569bdf5f8353f3c0e90..92fd1fe42f7b2e4cf4be3e1c5f29521e932c2f54 100644 (file)
@@ -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
index 3f627e5308a5ec265bd3e5b940605cb920da2717..8c437e483dfe4b38217c2f861e265a7fe65b14d9 100644 (file)
@@ -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);
 
index 44a48940b8911e7d8ea6e0852ab48e5c9b952c9a..3bc320f9690f38798908d8631b6cc7d204536207 100644 (file)
@@ -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 (file)
index 0000000..1262f9f
--- /dev/null
@@ -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;
+}
+