This is the mail archive of the gcc@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]
Other format: [Raw text]

Re: A reload failure which I can't figure out


On Tue, May 30, 2006 at 08:23:34PM +0200, Rask Ingemann Lambertsen wrote:
> Hi.
> 
> I have problems figuring out why reload gives up on this:
> 
> reload failure for reload 1
> ../../../cvssrc/gcc/gcc/libgcc2.c: In function '__moddi3':
> ../../../cvssrc/gcc/gcc/libgcc2.c:1101: error: unable to find a register to
> spill in class 'DX_REGS'
> ../../../cvssrc/gcc/gcc/libgcc2.c:1101: error: these are the reloads for
> insn # 425:
> Reload 0: reload_in (HI) = (reg:HI 4 d [+2 ])
>         reload_out (HI) = (reg:HI 0 c [199])
>         AX_REGS, RELOAD_OTHER (opnum = 0)
>         reload_in_reg: (reg:HI 4 d [+2 ])
>         reload_out_reg: (reg:HI 0 c [199])
> Reload 1: reload_out (HI) = (scratch:HI)
>         DX_REGS, RELOAD_FOR_OUTPUT (opnum = 3)
>         reload_out_reg: (scratch:HI)
> ../../../cvssrc/gcc/gcc/libgcc2.c:1101: error: this is the insn:
> (insn 425 422 432 30 ../../../cvssrc/gcc/gcc/libgcc2.c:911 (parallel [
>             (set (reg:HI 0 c [199])
>                 (mult:HI (reg:HI 4 d [+2 ])
>                     (reg:HI 6 b [orig:629 __d0 ] [629])))
>             (clobber (scratch:HI))
>             (clobber (reg:CC 12 cc))
>         ]) 309 {*mulhi3} (nil)
>     (expr_list:REG_UNUSED (reg:CC 12 cc)
>         (expr_list:REG_UNUSED (scratch:HI)
>             (expr_list:REG_DEAD (reg:HI 4 d [+2 ])
>                 (expr_list:REG_UNUSED (reg:CC 12 cc)
>                     (expr_list:REG_UNUSED (scratch:HI)
>                         (nil)))))))
> ../../../cvssrc/gcc/gcc/libgcc2.c:1101: internal compiler error: in
> spill_failure, at reload1.c:1915
> 
> The *mulhi3 pattern is this:
> (define_insn "*mulhi3"
>         [(set (match_operand:HI 0 "single_register_operand" "=a")
>               (mult:HI (match_operand:HI 1 "single_register_operand" "%0")
>                        (match_operand:HI 2 "general_operand" "rm")))
>          (clobber (match_scratch:HI 3 "=d"))
>          (clobber (reg:CC CC_REG))]
>         ""
>         "mulw\t%2"
> )
> 
> where the constraint "a" matches the register class AX_REGS consiting of
> (reg:HI 2 a), the constraint "d" matches the register class DX_REGS
> consiting of (reg:HI 4 d)

What happens is that global.c:reg_dies() sets (reg:HI 4 "d") in
&chain->dead_or_set. Later, reload1.c:order_regs_for_reload() add these
registers to bad_spill_regs. Finally, reload1.c:find_reg() decides that
registers in bad_spill_regs are not usable and registers other than those
of the constraints register class are also not usable. Since both consist of
(reg:HI 4 d), all registers are now marked not usable. So reload fails.

There is at least one fault with the reasoning of global/reload here. Since
(reg:HI 4 d) dies in this instruction, it is perfectly fine to use it for an
output reload. That's different from the case where (reg:HI 4 d) is set and
the value used afterwards. So why are these two cases handled the same way?

Also, since (reg:HI 4 d) doesn't match the constraint "a", it
doesn't really die in this instruction, but in the instruction
(set (reg:HI 2 a) (reg:HI 4 a)) which reload is about to insert before
*mulhi3. Maybe that's ok.

-- 
Rask Ingemann Lambertsen


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