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

--- Comment #2 from Jeffrey A. Law <law at gcc dot gnu.org> ---
Very interesting little testcase.  This may be the loongarch bug that was
recently reported.

It appears the root cause is this insn (from a hacked up version, so the insn
#s may not match up perfectly):

(insn 82 79 83 4 (set (reg:DI 246 [ _123 ])
        (sign_extend:DI (subreg/s/u:QI (reg:DI 260) 0))) "j.c":11:11 128
{*extendqidi2}
     (expr_list:REG_DEAD (reg:DI 260)
        (expr_list:REG_EQUAL (sign_extend:DI (mem/c:QI (const:DI (plus:DI
(symbol_ref:DI ("*.LANCHOR0") [flags 0x182])
                            (const_int 57 [0x39]))) [0 d[9]+0 S1 A8]))


Note the /s/u flags on the SUBREG.  Those tell the optimizers that the value is
actually a sign extended object already and the optimizers can drop the
extraneous extension.   In a subtle way those flags essentially mean that bits
outside the subreg's mode are live.  So we really should have marked additional
groups in (reg 260) as live.  That in turn would have kept key bit groups live
in a different register and inhibited extension removal.

There's a nonzero chance this is also the loongarch bug that just got reported.

Reply via email to