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

Reply via email to