2014-07-02 Jakub Jelinek 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; +}