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