Hi! This code dates back to 1994, and as the testcase shows, is broken if mask contains some bits outside of mode (as ASHIFTRT is signed, I think it is fine if it is sign extended from mode to the HWI). On this particular testcase, mode is SImode, trueop1 is (const_int 2), count is 31, so we get mask 0x100000000, and mask & nonzero_bits (something, SImode) will be always 0, because nonzero_bits won't have any bits beyond those in SImode set. But that means we haven't actually verified that the optimization is correct.
Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk/4.8? 2013-07-05 Jakub Jelinek <ja...@redhat.com> PR rtl-optimization/57829 * simplify-rtx.c (simplify_binary_operation_1) <case IOR>: Ensure that mask bits outside of mode are just sign-extension from mode to HWI. * gcc.c-torture/execute/pr57829.c: New test. --- gcc/simplify-rtx.c.jj 2013-07-04 16:55:19.000000000 +0200 +++ gcc/simplify-rtx.c 2013-07-05 16:37:50.100920805 +0200 @@ -2818,6 +2818,7 @@ simplify_binary_operation_1 (enum rtx_co HOST_WIDE_INT mask = INTVAL (trueop1) << count; if (mask >> count == INTVAL (trueop1) + && trunc_int_for_mode (mask, mode) == mask && (mask & nonzero_bits (XEXP (op0, 0), mode)) == 0) return simplify_gen_binary (ASHIFTRT, mode, plus_constant (mode, XEXP (op0, 0), --- gcc/testsuite/gcc.c-torture/execute/pr57829.c.jj 2013-07-05 16:27:12.167405677 +0200 +++ gcc/testsuite/gcc.c-torture/execute/pr57829.c 2013-07-05 16:28:28.000000000 +0200 @@ -0,0 +1,31 @@ +/* PR rtl-optimization/57829 */ + +__attribute__((noinline, noclone)) +int +f1 (int k) +{ + return 2 | ((k - 1) >> ((int) sizeof (int) * __CHAR_BIT__ - 1)); +} + +__attribute__((noinline, noclone)) +long int +f2 (long int k) +{ + return 2L | ((k - 1L) >> ((int) sizeof (long int) * __CHAR_BIT__ - 1)); +} + +__attribute__((noinline, noclone)) +int +f3 (int k) +{ + k &= 63; + return 4 | ((k + 2) >> 5); +} + +int +main () +{ + if (f1 (1) != 2 || f2 (1L) != 2L || f3 (63) != 6 || f3 (1) != 4) + __builtin_abort (); + return 0; +} Jakub