>From: Ulrich Weigand > >Erwin Unruh wrote: > >> I have a problem with delete_output_reload. It sometimes deletes >> instructions which are needed. Here an analysis of a recent >case (In a >> private version of the S390 port). The original S390 shows >almost the >> same reloads, but chooses different registers. > >What GCC version your compiler based on?
GCC 4.1.0 >> Reloads for insn # 1598 >> Reload 0: reload_in (SI) =3D (const_int 4080 [0xff0]) >> ADDR_REGS, RELOAD_FOR_OUTPUT_ADDRESS (opnum =3D 0) >> reload_in_reg: (const_int 4080 [0xff0]) >> reload_reg_rtx: (reg:SI 2 2) >> Reload 1: reload_in (SI) =3D (const_int 4080 [0xff0]) >> ADDR_REGS, RELOAD_FOR_OTHER_ADDRESS (opnum =3D 0) >> reload_in_reg: (const_int 4080 [0xff0]) >> reload_reg_rtx: (reg:SI 2 2) >> Reload 2: reload_in (SI) =3D (const_int 4080 [0xff0]) >> ADDR_REGS, RELOAD_FOR_INPUT_ADDRESS (opnum =3D 2) >> reload_in_reg: (const_int 4080 [0xff0]) >> reload_reg_rtx: (reg:SI 2 2) >> Reload 3: reload_in (DI) =3D (mem/c:DI (plus:SI (plus:SI >(reg/f:SI 15 15) >> >(const_int >> 4080 [0xff0])) >> (const_int >> 3144 >> [0xc48])) [0 S8 A8]) >> reload_out (DI) =3D (mem/c:DI (plus:SI (plus:SI (reg/f:SI 15 15) >> >(const_int >> 4080 [0xff0])) >> (const_int >> 3136 >> [0xc40])) [0 S8 A8]) >> GENERAL_REGS, RELOAD_OTHER (opnum =3D 0), can't combine >> reload_in_reg: (reg:DI 1391) >> reload_out_reg: (reg:DI 1393) >> reload_reg_rtx: (reg:DI 0 0) >> Reload 4: ADDR_REGS, RELOAD_FOR_INPUT_ADDRESS (opnum =3D 2), can't >> combine, secondary_reload_p >> reload_reg_rtx: (reg:SI 3 3) >> Reload 5: reload_in (SI) =3D (plus:SI (plus:SI (reg/f:SI 15 15) >> (const_int >> 4080 >> [0xff0])) >> (const_int 3136 >> [0xc40])) >> ADDR_REGS, RELOAD_FOR_INPUT (opnum =3D 2), inc by 8 >> reload_in_reg: (plus:SI (plus:SI (reg/f:SI 15 15) >> (const_int >> 4080 >> [0xff0])) >> (const_int 3136 >> [0xc40])) >> reload_reg_rtx: (reg:SI 2 2) >> secondary_in_reload =3D 4 >> secondary_in_icode =3D reload_insi >> >> These reloads are ok. In do_output_reload it is noted that both >> insn_1597.Reload_2 and insn_1598.Reload_3 write to the same >stack slot. >> So the compiler decides to remove the first reload and use register >> (reg:DI 2) > directly. In this analysis it misses the fact that >> (reg:SI 2) is used for input reloads of insn 1598. > >This should actually be caught by the free_for_value_p check >in choose_reload_regs. You cannot inherit a value for a >RELOAD_OTHER reload (3) in a register that is already in use >for a RELOAD_FOR_INPUT_ ADDRESS reload (2). > >Could you try to find out why this doesn't work correctly? Sorry, I mislead you. Somehow I did confuse (mem/c:DI (reg:SI 2 2) [0 S8 A8]) with (reg:DI 2). Register 2 is used correctly. I do not think any reload is inherited in this case. I did find something which might be the real problem. Within delete_output_reload there are two calls to count_occurrences. The second one will be called with parameters (parallel [ (set (mem/c:DI (plus:SI (plus:SI (reg/f:SI 15 15) (const_int 4080 [0xff0])) (const_int 3136 [0xc40])) [0 S8 A8]) (plus:DI (mem/c:DI (plus:SI (plus:SI (reg/f:SI 15 15) (const_int 4080 [0xff0])) (const_int 3144 [0xc48])) [0 S8 A8]) (mem/c:DI (plus:SI (plus:SI (reg/f:SI 15 15) (const_int 4080 [0xff0])) (const_int 3136 [0xc40])) [0 S8 A8]))) (clobber (reg:CC 33 %cc)) ]) (mem/c:DI (plus:SI (reg/f:SI 15 15) (const_int 7216 [0x1c30])) [0 S8 A8]) The offset from register 15 is represented in two different ways. In the first parameter it is split in two constants, in the second it is kept as a single constant. Due to this difference, no occurence is found. So the second operand of the (plus:DI ...) is not counted. So the output reload for insn 1597 is deleted, although the memory is read within insn 1598. Erwin