https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94567

--- Comment #2 from Jeffrey A. Law <law at redhat dot com> ---
THanks Martin.  I'm already well into this one :-)

I'm pretty sure the problem is testqi_ext_3 and the code we generate when
splitting it.

Consider (from my own slightly reduced testcase, but I'm sure yours will have
something similar):

(insn 25 22 26 3 (set (reg:CCNO 17 flags)
        (compare:CCNO (zero_extract:SI (reg:HI 104 [ e ])
                (const_int 13 [0xd])
                (const_int 3 [0x3]))
            (const_int 0 [0]))) "j.c":15:17 449 {*testqi_ext_3}
     (expr_list:REG_DEAD (reg:HI 104 [ e ])
        (nil)))

Which gets "split" into:

(insn 124 22 26 3 (set (reg:CCNO 17 flags)
        (compare:CCNO (and:HI (reg:HI 104 [ e ])
                (const_int -8 [0xfffffffffffffff8]))
            (const_int 0 [0]))) "j.c":15:17 444 {*testhi_1}
     (expr_list:REG_DEAD (reg:HI 104 [ e ])
        (nil)))

But consider the affect on the flags, particularly if the HImode sign bit is on
in (reg 104).   In the pre-split we extract a 13 bit field starting at bit 3
and zero extend it to SImode, then compare it against zero.  No matter what the
value in (reg 104) the sign flag bit will be off.

In the post-split version we do a HImode AND and thus the sign flag bit will be
on if bit 16 in (reg 104) is on.

The pr90275 changes indirectly enabled generation of testqi_ext_3, but after a
day of looking at the dumps, I'm confident the 90275 changes are correct/safe
and that we're really dealing with a latent issue in testqi_ext_3.

Reply via email to