conditional exec verify_live problem after scheduling
Richard Earnshaw
rearnsha@arm.com
Wed Feb 7 07:25:00 GMT 2001
>
> rearnsha@arm.com said:
> > I've come across the following problem which I think is probably
> > related to your recent conditional-execution scheduling changes
> > (though it may be just uncovering an underlying problem from before).
> > The problem is in newlib/libm/common/s_modf.c when compiling arm-elf
> > and -mhard-float.
>
>
> I've finally had chance to look into this. It isn't the cond_exec
> scheduling changes per-say, but revealing a latent bug in mark_set_1. The
> problem is that the variable not_dead is calculated as the OR of the
> result of all the calls to mark_regno_cond_dead for each real reg of a
> multi-reg value. Why does this make a difference? Well, before
> scheduling we have
>
> (insn 96 94 104 (cond_exec (eq (reg:CC_NOOV 24 cc)
> (const_int 0 [0x0]))
> (set (reg:DF 3 r3 [54])
> (reg/v:DF 16 f0 [32]))) 604 {ffssi2+104} (nil)
> (nil))
> ...
> (insn 136 142 138 (cond_exec (ne (reg:CC_NOOV 24 cc)
> (const_int 0 [0x0]))
> (set (reg:SI 4 r4 [58])
> (and:SI (not:SI (reg/v:SI 3 r3 [37]))
> (reg/v:SI 12 ip [34])))) 544 {ffssi2+44} (nil)
> (expr_list:REG_DEAD (reg/v:SI 3 r3 [37])
> (expr_list:REG_DEAD (reg/v:SI 12 ip [34])
> (nil))))
>
> and since at the point of processing insn 96 the hard reg r3 is not dead,
> not_dead is set to 1 even though hard reg r4 (the upper half of (reg:DI
> r3)) is really dead at this point. This means that we erroneously leave
> r4 live at the start of the block. After scheduling the order of these
> two insns is reversed, so the liveness of r4 is calculated from a single
> call to mark_regno_cond_dead which this time tells us that the register is
> dead. Hence we get different liveness information at the start of the
> block.
I believe the following patch should fix this problem. By treating
not_dead as a bitmask of the registers that don't die we can correctly
handle partial deaths of registers that live in multi hard regs.
Bootstrapped on arm-netbsd and confirmed that it can now build the newlib
cases that previously failed.
<date> Richard Earnshaw (rearnsha@arm.com)
* flow.c (mark_set_1): Make not_dead unsigned long. For
non-pseudos, use it as a bitmask of the hard regs that
don't die.
More information about the Gcc-bugs
mailing list