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 <senthil_kumar.selva...@atmel.com> 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);