Hi! The following testcase ICEs on powerpc-linux, because we merge SImode constants 0x7fffffff and 1 into 0x80000000, which is not valid SImode CONST_INT - -0x80000000 is. Fixed by calling trunc_int_for_mode, and to avoid UB in the compiler do the addition in unsigned type.
Bootstrapped/regtested on x86_64-linux and i686-linux and tested on the testcase with powerpc64-linux cross with -m32, ok for trunk? 2018-03-16 Jakub Jelinek <ja...@redhat.com> PR target/84899 * postreload.c (reload_combine_recognize_pattern): Perform INTVAL addition in unsigned HOST_WIDE_INT type to avoid UB and truncate_int_for_mode the result for the destination's mode. * gcc.dg/pr84899.c: New test. --- gcc/postreload.c.jj 2018-01-03 10:19:55.572534024 +0100 +++ gcc/postreload.c 2018-03-16 18:19:17.819417570 +0100 @@ -1157,11 +1157,13 @@ reload_combine_recognize_pattern (rtx_in value in PREV, the constant loading instruction. */ validate_change (prev, &SET_DEST (prev_set), index_reg, 1); if (reg_state[regno].offset != const0_rtx) - validate_change (prev, - &SET_SRC (prev_set), - GEN_INT (INTVAL (SET_SRC (prev_set)) - + INTVAL (reg_state[regno].offset)), - 1); + { + HOST_WIDE_INT c + = trunc_int_for_mode (UINTVAL (SET_SRC (prev_set)) + + UINTVAL (reg_state[regno].offset), + GET_MODE (index_reg)); + validate_change (prev, &SET_SRC (prev_set), GEN_INT (c), 1); + } /* Now for every use of REG that we have recorded, replace REG with REG_SUM. */ --- gcc/testsuite/gcc.dg/pr84899.c.jj 2018-03-16 18:22:39.243512333 +0100 +++ gcc/testsuite/gcc.dg/pr84899.c 2018-03-16 18:22:22.353504390 +0100 @@ -0,0 +1,12 @@ +/* PR target/84899 */ +/* { dg-do compile } */ +/* { dg-options "-O -funroll-all-loops -fno-move-loop-invariants" } */ + +void +foo (int x) +{ + int a = 1 / x, b = 0; + + while ((a + b + 1) < x) + b = __INT_MAX__; +} Jakub