GCC reload problem

Eric Botcazou ebotcazou@libertysurf.fr
Thu Apr 10 21:36:00 GMT 2003


Hello again David,

We have recently run into a problem with the reload pass of GCC. The thread 
starts here: http://gcc.gnu.org/ml/gcc/2003-04/msg00320.html

The problem is related to invalid subregs of hard regs produced by the 
register allocator, for example on x86

	(subreg:SI (reg/v:DI 29 rmm0 [68]) 4)


The reload pass knows how to "fix" these invalid subregs, i.e to reload the 
whole reg, but the machinery triggers _only_ when reloading is required 
because of the constraints of the insn.

We have a testcase: PR target/10286.

We pass

(insn 33 30 35 (set (subreg:SI (reg/v:DI 67) 4)
        (mem/f:SI (plus:SI (reg/f:SI 16 argp)
                (const_int 4 [0x4])) [0 hi+0 S4 A32])) 45 {*movsi_1} 
(insn_list 30 (nil))

to reload, which produces

(insn 33 30 35 (set (reg:SI 29 emm0)
        (mem/f:SI (plus:SI (reg/f:SI 6 ebp)
                (const_int 12 [0xc])) [0 hi+0 S4 A32])) 45 {*movsi_1} 
(insn_list 30 (nil))
    (nil))

that is, the only reload for insn 33 is

Reloads for insn # 33
Reload 0: reload_in (SI) = (mem/f:SI (plus:SI (reg/f:SI 6 ebp)
                                                        (const_int 12 [0xc])) 
[0 hi+0 S4 A32])
        GENERAL_REGS, RELOAD_FOR_INPUT (opnum = 1), optional
        reload_in_reg: (mem/f:SI (plus:SI (reg/f:SI 6 ebp)
                                                        (const_int 12 [0xc])) 
[0 hi+0 S4 A32])

while we must have reloaded the invalid subreg.


Now the machinery used to trigger for these invalid subregs, independently of 
the constraints of the insn. But it appears that you have disabled it: from 
reload.c:find_reloads()

		  /* This following hunk of code should no longer be
		     needed at all with SUBREG_BYTE.  If you need this
		     code back, please explain to me why so I can
		     fix the real problem.  -DaveM */
#if 0
		  /* Subreg of a hard reg which can't handle the subreg's mode
		     or which would handle that mode in the wrong number of
		     registers for subregging to work.  */
		  || (GET_CODE (operand) == REG
		      && REGNO (operand) < FIRST_PSEUDO_REGISTER
		      && ((GET_MODE_SIZE (operand_mode[i]) <= UNITS_PER_WORD
			   && (GET_MODE_SIZE (GET_MODE (operand))
			       > UNITS_PER_WORD)
			   && ((GET_MODE_SIZE (GET_MODE (operand))
				/ UNITS_PER_WORD)
			       != HARD_REGNO_NREGS (REGNO (operand),
						    GET_MODE (operand))))
			  || ! HARD_REGNO_MODE_OK (REGNO (operand) + offset,
						   operand_mode[i])))
#endif


Re-enabling it fix PR target/10286.

Hence the question: what is the replacement machinery that is supposed to be 
doing the work?

-- 
Eric Botcazou



More information about the Gcc mailing list