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

--- Comment #40 from Kazumoto Kojima <kkojima at gcc dot gnu.org> ---
I've tried to see what is going on with reload loop on movsf_ie
for gcc.c-torture/compile/20050113-1.c -O1 -m4 -ml.
It looks that the problem starts at reloading

(insn 15 10 18 2 (parallel [
            (set (subreg:SF (reg:SI 173 [ a ]) 0)
                (minus:SF (reg:SF 160 [ D.1385 ])
                    (reg:SF 160 [ D.1385 ])))
            (use (reg/v:PSI 151 ))
        ]) yyy.i:10 443 {subsf3_i}
     (expr_list:REG_DEAD (reg:SF 160 [ D.1385 ])
        (expr_list:REG_DEAD (reg/v:PSI 151 )
            (nil))))

RA inserts

   43: {r179:SF=r160:SF;use :PSI;clobber scratch;}

before that insn and

   44: {r173:SI#0=r179:SF;use :PSI;clobber scratch;}

after that where #0 means subreg:SF 0.
RA assigns register class FP_REGS to r179 here and tries to
reload insn 44 which matches movsf_ie.
SH has no direct move instruction from floating point reg to
general reg and RA chooses the alt 1 in movesf_ie of which operands
are (0) r  (1) r  (2) c  (3) X.  Then RA creates new reg r180
with assigning class GENERAL_REGS to r180 and inserts

   45: {r180:SF=r179:SF;use :PSI;clobber scratch;}

before insn 44 which is now

   44: {r173:SI#0=r180:SF;use :PSI;clobber scratch;}

RA tries to reload insn 45 which is in the same situation with
the original 44, i.e. move from FP_REGS to GENERAL_REGS.
Thus things are looping.

It looks that the problematic cases are corresponding to the cases
which were handled by the secondary reloads in the old reload.
In the above example, if RA choosed the alt 13 in movsf_ie of
which operands are (0) fr  (1) rf  (2) c  (3) y, it didn't loop.
It looks RA doesn't choose it because it requires more numbers
of registers than the alt 1.  The current movsf_ie uses

   (clobber (match_scratch:SI 3
"=X,X,Bsc,Bsc,&z,X,X,X,X,X,X,X,X,y,X,X,X,X,X"))]

and this pattern might be not good for lra.

Reply via email to