This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Fix simplify_const_relational_operation unsigned comparisons of sign-extended values (PR rtl-optimization/34490)


Hi!

The attached testcase distilled from glibc is miscompiled on x86_64-linux,
simplify_const_relational_operation (LEU, DImode, (sign_extend:DI (reg:SI 59)), (const_int -4096))
returns (const_int 1), eventhough for unsigned comparisons nothing like that
can be deduced from the arguments.  If op0 is sign extended and the
comparison is unsigned (GTU, GEU, LTU, LEU), then all we know is that
op0 falls into one of two disjunct ranges, in the above case for DImode
and num_sign_bit_copies == 33
0 ... 0x7fffffff and 0xffffffff80000000 ... -1ULL
so all we can deduce is that for op0 >= 0 and op0 <= -1ULL, nothing else.

This is a recent regression (on the trunk only), introduced by
http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=128833

Bootstrapped/regtested on x86_64-linux, ok for trunk?

2007-12-16  Jakub Jelinek  <jakub@redhat.com>

	PR rtl-optimization/34490
	* simplify-rtx.c (simplify_const_relational_operation): If !sign,
	don't reduce mmin/mmax using num_sign_bit_copies.

	* gcc.c-torture/execute/20071216-1.c: New test.

--- gcc/simplify-rtx.c.jj	2007-10-08 10:45:03.000000000 +0200
+++ gcc/simplify-rtx.c	2007-12-16 12:22:04.000000000 +0100
@@ -4233,15 +4233,17 @@ simplify_const_relational_operation (enu
       else
 	{
 	  rtx mmin_rtx, mmax_rtx;
-	  unsigned int sign_copies = num_sign_bit_copies (trueop0, mode);
 	  get_mode_bounds (mode, sign, mode, &mmin_rtx, &mmax_rtx);
 
-	  /* Since unsigned mmin will never be interpreted as negative, use
-	     INTVAL (and an arithmetic right shift).  */
-	  mmin = INTVAL (mmin_rtx) >> (sign_copies - 1);
-	  /* Since signed mmax will always be positive, use UINTVAL (and
-	     a logical right shift).  */
-	  mmax = UINTVAL (mmax_rtx) >> (sign_copies - 1);
+	  mmin = INTVAL (mmin_rtx);
+	  mmax = INTVAL (mmax_rtx);
+	  if (sign)
+	    {
+	      unsigned int sign_copies = num_sign_bit_copies (trueop0, mode);
+
+	      mmin >>= (sign_copies - 1);
+	      mmax >>= (sign_copies - 1);
+	    }
 	}
 
       switch (code)
--- gcc/testsuite/gcc.c-torture/execute/20071216-1.c.jj	2007-12-16 12:25:58.000000000 +0100
+++ gcc/testsuite/gcc.c-torture/execute/20071216-1.c	2007-12-16 10:38:34.000000000 +0100
@@ -0,0 +1,38 @@
+/* PR rtl-optimization/34490 */
+
+extern void abort (void);
+
+static int x;
+
+int
+__attribute__((noinline))
+bar (void)
+{
+  return x;
+}
+
+int
+foo (void)
+{
+  long int b = bar ();
+  if ((unsigned long) b < -4095L)
+    return b;
+  if (-b != 38)
+    b = -2;
+  return b + 1;
+}
+
+int
+main (void)
+{
+  x = 26;
+  if (foo () != 26)
+    abort ();
+  x = -39;
+  if (foo () != -1)
+    abort ();
+  x = -38;
+  if (foo () != -37)
+    abort ();
+  return 0;
+}

	Jakub


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]