[regcprop] Tentative fix for PR 64331

Message ID 20141216133908.GA8604@atmel.com
State New
Headers show

Commit Message

Senthil Kumar Selvaraj Dec. 16, 2014, 1:39 p.m.
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.selvaraj@atmel.com>

	PR rtl-optimization/64331
	* regcprop.c (copyprop_hardreg_forward_1): Kill regs marked REG_DEAD.

Comments

Eric Botcazou Dec. 16, 2014, 4:39 p.m. | #1
>   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.

As explained in the audit trail, it doesn't have to.

>   Killing regs that are marked REG_DEAD fixes the immediate problem.
>   Is that the right approach? What do you guys think?

Nope, consumers of REG_DEAD notes must instead explicitly ask the DF framework 
to recompute them.

Patch

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);