This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
Re: conditional exec verify_live problem after scheduling
- To: Bernd Schmidt <bernds at redhat dot com>, rth at redhat dot com
- Subject: Re: conditional exec verify_live problem after scheduling
- From: Richard Earnshaw <rearnsha at arm dot com>
- Date: Sat, 20 Jan 2001 12:23:08 +0000
- cc: Richard Earnshaw <rearnsha at arm dot com>, gcc-bugs at gcc dot gnu dot org
- Organization: ARM Ltd.
- Reply-To: rearnsha at arm dot com
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.
The following test case should be compiled with arm-elf at -O2
-mhard-float to show the problem.
R.
s_modf.i.bz2