2013-11-05 Jakub Jelinek PR rtl-optimization/58997 * loop-iv.c (iv_subreg): For IV_UNKNOWN_EXTEND, expect get_iv_value to be in iv->mode rather than iv->extend_mode. (iv_extend): Likewise. Otherwise, if iv->extend != extend, use lowpart_subreg on get_iv_value before calling simplify_gen_unary. * loop-unswitch.c (may_unswitch_on): Make sure op[i] is in the right mode. * gcc.c-torture/compile/pr58997.c: New test. --- gcc/loop-unswitch.c (revision 204412) +++ gcc/loop-unswitch.c (revision 204413) @@ -191,6 +191,7 @@ may_unswitch_on (basic_block bb, struct if (!test) return NULL_RTX; + mode = VOIDmode; for (i = 0; i < 2; i++) { op[i] = XEXP (test, i); @@ -205,11 +206,15 @@ may_unswitch_on (basic_block bb, struct return NULL_RTX; op[i] = get_iv_value (&iv, const0_rtx); + if (iv.extend != IV_UNKNOWN_EXTEND + && iv.mode != iv.extend_mode) + op[i] = lowpart_subreg (iv.mode, op[i], iv.extend_mode); + if (mode == VOIDmode) + mode = iv.mode; + else + gcc_assert (mode == iv.mode); } - mode = GET_MODE (op[0]); - if (mode == VOIDmode) - mode = GET_MODE (op[1]); if (GET_MODE_CLASS (mode) == MODE_CC) { if (at != BB_END (bb)) --- gcc/loop-iv.c (revision 204412) +++ gcc/loop-iv.c (revision 204413) @@ -436,7 +436,9 @@ iv_subreg (struct rtx_iv *iv, enum machi && !iv->first_special) { rtx val = get_iv_value (iv, const0_rtx); - val = lowpart_subreg (mode, val, iv->extend_mode); + val = lowpart_subreg (mode, val, + iv->extend == IV_UNKNOWN_EXTEND + ? iv->mode : iv->extend_mode); iv->base = val; iv->extend = IV_UNKNOWN_EXTEND; @@ -476,8 +478,14 @@ iv_extend (struct rtx_iv *iv, enum iv_ex && !iv->first_special) { rtx val = get_iv_value (iv, const0_rtx); + if (iv->extend_mode != iv->mode + && iv->extend != IV_UNKNOWN_EXTEND + && iv->extend != extend) + val = lowpart_subreg (iv->mode, val, iv->extend_mode); val = simplify_gen_unary (iv_extend_to_rtx_code (extend), mode, - val, iv->extend_mode); + val, + iv->extend == extend + ? iv->extend_mode : iv->mode); iv->base = val; iv->extend = IV_UNKNOWN_EXTEND; iv->mode = iv->extend_mode = mode; --- gcc/testsuite/gcc.c-torture/compile/pr58997.c (revision 0) +++ gcc/testsuite/gcc.c-torture/compile/pr58997.c (revision 204413) @@ -0,0 +1,19 @@ +/* PR rtl-optimization/58997 */ + +int a, b, c, e; +short d; +char h; + +void +foo () +{ + while (b) + { + d = a ? c : 1 % a; + c = d; + h = d; + if (!h) + while (e) + ; + } +}