2016-03-14 Jakub Jelinek PR rtl-optimization/70222 * combine.c (simplify_shift_const_1): Force simplify_and_const_int for LSHIFTRT if result_mode != mode && count == 0. * gcc.c-torture/execute/pr70222.c: New test. --- gcc/combine.c.jj 2016-02-11 23:52:57.000000000 +0100 +++ gcc/combine.c 2016-03-14 14:00:24.576657458 +0100 @@ -10835,8 +10835,12 @@ simplify_shift_const_1 (enum rtx_code co x = simplify_gen_binary (code, shift_mode, varop, GEN_INT (count)); /* If we were doing an LSHIFTRT in a wider mode than it was originally, - turn off all the bits that the shift would have turned off. */ - if (orig_code == LSHIFTRT && result_mode != shift_mode) + turn off all the bits that the shift would have turned off. + Similarly do this if if we've optimized varop so that we don't perform + any shift. */ + if (orig_code == LSHIFTRT + && (result_mode != shift_mode + || (result_mode != mode && count == 0))) x = simplify_and_const_int (NULL_RTX, shift_mode, x, GET_MODE_MASK (result_mode) >> orig_count); --- gcc/testsuite/gcc.c-torture/execute/pr70222.c.jj 2016-03-14 14:03:27.998140364 +0100 +++ gcc/testsuite/gcc.c-torture/execute/pr70222.c 2016-03-14 14:03:12.000000000 +0100 @@ -0,0 +1,30 @@ +/* PR rtl-optimization/70222 */ + +int a = 1; +unsigned int b = 2; +int c = 0; +int d = 0; + +void +foo () +{ + int e = ((-(c >= c)) < b) > ((int) (-1ULL >> ((a / a) * 15))); + d = -e; +} + +__attribute__((noinline, noclone)) void +bar (int x) +{ + if (x != -1) + __builtin_abort (); +} + +int +main () +{ +#if __CHAR_BIT__ == 8 && __SIZEOF_INT__ == 4 && __SIZEOF_LONG_LONG__ == 8 + foo (); + bar (d); +#endif + return 0; +}