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