On 11/05/13 06:09, Jakub Jelinek wrote:
Hi!
Apparently, for iv->extend == IV_UNKNOWN_EXTEND if iv->mode !=
iv->extend_mode get_iv_value returns a value in iv->mode mode, while
otherwise in iv->extend_mode. This makes some sense, because with
IV_UNKNOWN_EXTEND the upper bits are unknown, so there is nothing reasonable
to return in the extended mode. But e.g. iv_subreg when it calls assumed
unconditionally the value would be in iv->extend_mode (the reason for the
ICE on the attached testcase). Furthermore, for iv_extend, IMHO if
iv->extend isn't IV_UNKNOWN_EXTEND, but is different from the new extend,
the middle bits might be incorrect. And, lastly, I think may_unswitch_on
assumes the returned values will be in the expected mode (iv->mode), but
they can be wider and that can result in invalid RTL (say comparing of
SImode with DImode rtl), or wrong code.
Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux, ok for
trunk and for 4.8 later?
2013-11-05 Jakub Jelinek <ja...@redhat.com>
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.
OK for the trunk. Your call on if/when to backport to the 4.8 branch.
Thanks,
Jeff