This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[RFC] Fix PR rtl-optimization/33732


This is the failure of gcc.c-torture/execute/longlong.c in 4.3 on the PA.
The reload pass generates wrong code in the form of a SET clobbering a
live register.


In .lreg:

(insn 73 72 70 4 longlong.c:19 (set (reg:SI 154 [+4 ])
        (lshiftrt:SI (reg:SI 141)
            (subreg:SI (reg:DI 116) 4))) 190 {lshrsi3} (expr_list:REG_DEAD 
(reg:SI 141)
        (expr_list:REG_DEAD (reg:DI 116)
            (nil))))

(insn 70 73 71 4 longlong.c:19 (set (reg:SI 140)
        (minus:SI (const_int 31 [0x1f])
            (subreg:SI (reg:DI 137) 4))) 119 {*pa.md:5698} (expr_list:REG_DEAD 
(reg:DI 137)
        (nil)))

[...]

(insn 74 71 77 4 longlong.c:19 (set (reg:SI 154 [+4 ])
        (ior:SI (reg:SI 139)
            (reg:SI 154 [+4 ]))) 135 {*pa.md:6217} (expr_list:REG_DEAD (reg:SI 
139)
        (nil)))


In .greg:

;; 5 regs to allocate: 116 (2) 154 95 156 94

Reloads for insn # 70
Reload 0: reload_out (SI) = (reg:SI 88 SAR [140])
	GENERAL_REGS, RELOAD_FOR_OUTPUT (opnum = 0)
	reload_out_reg: (reg:SI 88 SAR [140])
	reload_reg_rtx: (reg:SI 21 %r21)

;; Register dispositions:
[...}
154 in 21  155 in 1  156 in 31  

(insn 73 133 70 4 longlong.c:19 (set (reg:SI 21 %r21 [orig:154+4 ] [154])
        (lshiftrt:SI (reg:SI 28 %r28 [141])
            (reg:SI 88 SAR))) 190 {lshrsi3} (nil))

(insn 70 73 134 4 longlong.c:19 (set (reg:SI 21 %r21)
        (minus:SI (const_int 31 [0x1f])
            (reg:SI 22 %r22 [orig:137+4 ] [137]))) 119 {*pa.md:5698} (nil))

[...]

(insn 74 71 77 4 longlong.c:19 (set (reg:SI 21 %r21 [orig:154+4 ] [154])
        (ior:SI (reg:SI 19 %r19 [139])
            (reg:SI 21 %r21 [orig:154+4 ] [154]))) 135 {*pa.md:6217} (nil))


So the problem is that (reg:SI 21 %r21) is used as reload register for insn 70
and simultaneously assigned to pseudo 154, whose live range covers insn 70.

This stems from the REG_DEAD note on insn 70.  Right after global alloc:

(insn 70 73 71 4 longlong.c:19 (set (reg:SI 88 SAR [140])
        (minus:SI (const_int 31 [0x1f])
            (subreg:SI (reg:DI 21 %r21 [137]) 4))) 119 {*pa.md:5698} 
(expr_list:REG_DEAD (reg:DI 21 %r21 [137])
        (nil)))

is not correct anymore because only (subreg:SI (reg:DI 21 %r21 [137]) 4) is
dead, not (reg:SI 21 %r21), which fools the optimization in combine_reloads

  /* See if some hard register that dies in this insn and is not used in
     the output is the right class.  Only works if the register we pick
     up can fully hold our output reload.  */
  for (note = REG_NOTES (this_insn); note; note = XEXP (note, 1))
    if (REG_NOTE_KIND (note) == REG_DEAD
	&& REG_P (XEXP (note, 0))
	&& ! reg_overlap_mentioned_for_reload_p (XEXP (note, 0),
						 rld[output_reload].out)
	&& REGNO (XEXP (note, 0)) < FIRST_PSEUDO_REGISTER
	&& HARD_REGNO_MODE_OK (REGNO (XEXP (note, 0)), rld[output_reload].outmode)
	&& TEST_HARD_REG_BIT (reg_class_contents[(int) rld[output_reload].class],
			      REGNO (XEXP (note, 0)))
	&& (hard_regno_nregs[REGNO (XEXP (note, 0))][rld[output_reload].outmode]
	    <= hard_regno_nregs[REGNO (XEXP (note, 0))][GET_MODE (XEXP (note, 0))])
[...]
      {
	rld[output_reload].reg_rtx
	  = gen_rtx_REG (rld[output_reload].outmode,
			 REGNO (XEXP (note, 0)));
	return;
      }

into thinking that it can use (reg:SI 21 %r21) as reload register.

A similar issue was reported as PR middle-end/20973 for uninitialized pseudos.
But this one is probably a consequence of the more precise handling of SUBREGs
in the new ra-conflict.c code.

I'm not sure what the best approach to fixing this is.  Should we disregard
notes referencing former pseudo-registers that have been assigned more than
one hard register, between global alloc and reload?

	    && (ORIGINAL_REGNO (XEXP (note, 0)) < FIRST_PSEUDO_REGISTER
		|| hard_regno_nregs [XEXP (note, 0)] == 1)

Would this pessimize much in practice?

-- 
Eric Botcazou


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]