Hi,
The cprop_hardreg pass does not consider REG_DEAD notes when
propagating, and this causes issues if target specific code uses
dead_or_set_regno_p to know if it can clobber registers.
For example, regcrop transforms
(insn 7 4 8 2 (set (reg:SI 16 r16 [orig:43 D.1617 ] [43])
(reg/v:SI 20 r20 [orig:46 x ] [46])) reduced.c:12 94 {*movsi}
(nil))
...
(insn 13 12 14 3 (parallel [
(set (cc0)
(compare (reg/v:SI 20 r20 [orig:46 x ] [46])
(const_int 0 [0])))
(clobber (scratch:QI))
]) reduced.c:17 413 {*cmpsi}
(expr_list:REG_DEAD (reg/v:SI 20 r20 [orig:46 x ] [46])
(nil)))
...
(insn 17 16 18 4 (parallel [
(set (cc0)
(compare (reg:SI 16 r16 [orig:43 D.1617 ] [43])
(reg:SI 24 r24 [orig:48 t_3(D)->b ] [48])))
(clobber (scratch:QI))
]) reduced.c:20 413 {*cmpsi}
(expr_list:REG_DEAD (reg:SI 24 r24 [orig:48 t_3(D)->b ] [48])
(expr_list:REG_DEAD (reg:SI 16 r16 [orig:43 D.1617 ] [43])
(nil))))
into
(insn 17 16 18 4 (parallel [
(set (cc0)
(compare (reg:SI 20 r20 [orig:43 D.1617 ] [43])
(reg:SI 24 r24 [orig:48 t_3(D)->b ] [48])))
(clobber (scratch:QI))
]) reduced.c:20 413 {*cmpsi}
(expr_list:REG_DEAD (reg:SI 24 r24 [orig:48 t_3(D)->b ] [48])
(expr_list:REG_DEAD (reg:SI 16 r16 [orig:43 D.1617 ] [43])
(nil))))
replacing r16 in insn 17 with r20, which was marked REG_DEAD in insn 13.
The AVR backend, when emitting code for insn 13, figures that R20 is
dead and therefore happily clobbers it.
Killing regs that are marked REG_DEAD fixes the immediate problem.
Is that the right approach? What do you guys think?
Regards
Senthil
ChangeLog
2014-12-16 Senthil Kumar Selvaraj <[email protected]>
PR rtl-optimization/64331
* regcprop.c (copyprop_hardreg_forward_1): Kill regs marked REG_DEAD.
diff --git gcc/regcprop.c gcc/regcprop.c
index daeb980..4f00fc4 100644
--- gcc/regcprop.c
+++ gcc/regcprop.c
@@ -815,6 +815,9 @@ copyprop_hardreg_forward_1 (basic_block bb, struct
value_data *vd)
would clobbers. */
for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
{
+ if (REG_NOTE_KIND (link) == REG_DEAD)
+ kill_value (XEXP (link, 0), vd);
+
if (REG_NOTE_KIND (link) == REG_UNUSED)
{
kill_value (XEXP (link, 0), vd);