Blob Blame History Raw
2014-07-02  Jakub Jelinek  <jakub@redhat.com>

	PR rtl-optimization/61673
	* combine.c (simplify_comparison): Test just mode's sign bit
	in tmode rather than the sign bit and any bits above it.

	* gcc.c-torture/execute/pr61673.c: New test.

--- gcc/combine.c.jj	2014-03-28 20:49:52.892077022 +0100
+++ gcc/combine.c	2014-07-02 16:56:02.260456040 +0200
@@ -11987,7 +11987,7 @@ simplify_comparison (enum rtx_code code,
 		= (unsigned HOST_WIDE_INT) 1 << (GET_MODE_BITSIZE (mode) - 1);
 	      op0 = simplify_gen_binary (AND, tmode,
 					 gen_lowpart (tmode, op0),
-					 gen_int_mode (sign, mode));
+					 gen_int_mode (sign, tmode));
 	      code = (code == LT) ? NE : EQ;
 	      break;
 	    }
--- gcc/testsuite/gcc.c-torture/execute/pr61673.c.jj	2014-07-02 17:17:01.398908630 +0200
+++ gcc/testsuite/gcc.c-torture/execute/pr61673.c	2014-07-02 17:12:36.000000000 +0200
@@ -0,0 +1,50 @@
+/* PR rtl-optimization/61673 */
+
+char e;
+
+__attribute__((noinline, noclone)) void
+bar (char x)
+{
+  if (x != 0x54 && x != (char) 0x87)
+    __builtin_abort ();
+}
+
+__attribute__((noinline, noclone)) void
+foo (const char *x)
+{
+  char d = x[0];
+  int c = d;
+  if ((c >= 0 && c <= 0x7f) == 0)
+    e = d;
+  bar (d);
+}
+
+__attribute__((noinline, noclone)) void
+baz (const char *x)
+{
+  char d = x[0];
+  int c = d;
+  if ((c >= 0 && c <= 0x7f) == 0)
+    e = d;
+}
+
+int
+main ()
+{
+  const char c[] = { 0x54, 0x87 };
+  e = 0x21;
+  foo (c);
+  if (e != 0x21)
+    __builtin_abort ();
+  foo (c + 1);
+  if (e != 0x87)
+    __builtin_abort ();
+  e = 0x21;
+  baz (c);
+  if (e != 0x21)
+    __builtin_abort ();
+  baz (c + 1);
+  if (e != 0x87)
+    __builtin_abort ();
+  return 0;
+}