This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

inherited reloads bug



I've been having some reload problems with the C4x target that have
appeared with egcs in the last month or so.  The symptom is that
invalid insns are being output with address displacements too large.

>From the lreg dump I have the following snippet.  

(insn 12 10 13 (parallel[ 
            (set (reg:CC 21 st)
                (compare:CC (reg:QI 10 ar2)
                    (const_int 0)))
            (set (reg/v:QI 37)
                (reg:QI 10 ar2))
        ] ) 7 {*movqi_set} (nil)
    (expr_list:REG_DEAD (reg:QI 10 ar2)
        (nil)))

(jump_insn 13 12 16 (set (pc)
        (if_then_else (ne (reg:CC 21 st)
                (const_int 0))
            (label_ref 20)
            (pc))) 198 {*b} (insn_list 12 (nil))
    (expr_list:REG_DEAD (reg:CC 21 st)
        (nil)))
;; End of basic block 0

;; Start of basic block 1, registers live: 11 [ar3] 20 [sp] 37
(insn 16 13 18 (set (reg/i:QI 0 r0)
        (reg/v:QI 37)) 5 {movqi_noclobber} (nil)
    (expr_list:REG_DEAD (reg/v:QI 37)
        (expr_list:REG_EQUAL (const_int 0)
            (nil))))


insn 12 requires two reloads:
1. RELOAD_FOR_OUTPUT_ADDRESS (plus:QI (reg:QI 11 ar3) (const_int 289))
(this is the address of the stack slot corresponding to pseudo reg 37
that has too large a displacment).
2. RELOAD_FOR_OUTPUT (mem:QI (plus:QI (reg:QI 11 ar3) (const_int 289)))

Similarly, insn 16 requires two reloads:
1. RELOAD_FOR_INPUT_ADDRESS (plus:QI (reg:QI 11 ar3) (const_int 289))
2. RELOAD_FOR_INPUT (mem:QI (plus:QI (reg:QI 11 ar3) (const_int 289)))
(note this is an optional reload).

On the second pass, reload_as_needed calls find_reloads with replace=1
and pseudo register 37 is replaced with the stack slot location
(mem:QI (plus:QI (reg:QI 11 ar3) (const_int 289))).  Insn 12 thus
becomes:

(insn 12 10 13 (parallel[ 
            (set (reg:CC 21 st)
                (compare:CC (reg:QI 10 ar2)
                    (const_int 0)))
            (set (mem:QI (plus:QI (reg:QI 11 ar3) (const_int 289)) 0)
                (reg:QI 10 ar2))
        ] ) 7 {*movqi_set} (nil)
    (expr_list:REG_DEAD (reg:QI 10 ar2)
        (nil)))

choose_reload_regs requires two reload registers for insn 12 and
chooses r0 for the output reload and ar0 for the output address
reload.  So far so good.

Similarly, insn 16 gets modified to:

(insn 16 13 18 (set (reg/i:QI 0 r0)
        (mem:QI (plus:QI (reg:QI 11 ar3) 
                (const_int 289)) 0)) 5 {movqi_noclobber} (nil)
    (expr_list:REG_DEAD (reg/v:QI 37)
        (expr_list:REG_EQUAL (const_int 0)
            (nil))))

When choose_reload_regs is called for insn 16, it correctly determines
that the input address can be inherited from the output address
calculated for insn 12.  Thus ar0 can be reused for the input address.

Now, after some machinations that I've yet to work out,
choose_reload_regs decides that no reload registers are required since
r0 contains the desired value anyway.  However, the stack slot address
is still invalid for this insn.  Instead of making the substitution of
the stack slot address with ar0 or deleting this insn, this invalid
insn gets emitted....

Does this make any sense to someone more familiar with reload?


Michael.



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]