This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[RFA:] function.c: fix MMIX f90-intrinsic-bit.f compilation,paradoxical subreg addressof
- From: Hans-Peter Nilsson <hp at bitrange dot com>
- To: <gcc-patches at gcc dot gnu dot org>
- Date: Wed, 10 Apr 2002 18:36:38 -0400 (EDT)
- Subject: [RFA:] function.c: fix MMIX f90-intrinsic-bit.f compilation,paradoxical subreg addressof
It seems this can only happen for front-ends like fortran that
don't do whole-functions-as-trees. People who see ICE:s in
fixup_memory_subreg in fortran tests might be interested,
supposedly on WORD_REGISTER_OPERATIONS machines.
It all happens during initial rtx generation. Insn 430 starts
out as:
(insn 430 429 431 (set (reg:SI 390)
(subreg:SI (reg/v:HI 271) 0)) -1 (nil)
(nil))
Then a wicked address reference for that variable comes along (I
think; still being fortran illiterate) and reg 271 is replaced
through ffe_mark_addressable -> put_var_on_stack ->
gen_addressof:
(insn 430 429 431 (set (reg:SI 390)
(subreg:SI (mem/f:HI (addressof:DI (reg/v:HI 1041) 271
0x40181258) [0 j+0 S2 A16]) 0)) -1 (nil)
(nil))
Then gcc iterates over all insns to fix up the replacement. We
get to fixup_var_refs_1 and the code below, since VAR in SET_SRC
is special-cased. The function fixup_memory_subreg is called.
Oops. A paradoxical subreg is not to its taste, and
fixup_memory_subreg aborts.
For a while I considered changing fixup_memory_subreg to handle
paradoxical subregs of addressof:s, but thought this being
better. Replacing the inside of the subreg is right anyway,
otherwise we'll just get the same thing again when loading new
register in the replacement list: (set (new-reg) (subreg:SI
(mem:HI addressof))).
Bootstrapped and checked on i686-pc-linux-gnu; built and tested
cross to mmix-knuth-mmixware, cris-axis-elf, v850-unknown-elf,
arm-unknown-elf, m32r-unknown-elf, i960-unknown-coff (others in
progress; note the patch really just fixes a case that
previously ICE:d).
Ok for trunk and 3.1 branch?
* function.c (fixup_var_refs_1) <SET, handling VAR in SET_SRC>:
For paradoxical (subreg VAR), replace VAR, don't try the subreg.
Index: function.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/function.c,v
retrieving revision 1.353
diff -p -c -r1.353 function.c
*** function.c 3 Apr 2002 03:41:40 -0000 1.353
--- function.c 10 Apr 2002 05:33:22 -0000
*************** fixup_var_refs_1 (var, promoted_mode, lo
*** 2370,2384 ****
{
rtx pat, last;
! replacement = find_fixup_replacement (replacements, SET_SRC (x));
! if (replacement->new)
! SET_SRC (x) = replacement->new;
! else if (GET_CODE (SET_SRC (x)) == SUBREG)
! SET_SRC (x) = replacement->new
! = fixup_memory_subreg (SET_SRC (x), insn, 0);
else
! SET_SRC (x) = replacement->new
! = fixup_stack_1 (SET_SRC (x), insn);
if (recog_memoized (insn) >= 0)
return;
--- 2370,2398 ----
{
rtx pat, last;
! if (GET_CODE (SET_SRC (x)) == SUBREG
! && (GET_MODE_SIZE (GET_MODE (SET_SRC (x)))
! > GET_MODE_SIZE (GET_MODE (var))))
! {
! /* This (subreg VAR) is now a paradoxical subreg. We need
! to replace VAR instead of the subreg. */
! replacement = find_fixup_replacement (replacements, var);
! if (replacement->new == NULL_RTX)
! replacement->new = gen_reg_rtx (GET_MODE (var));
! SUBREG_REG (SET_SRC (x)) = replacement->new;
! }
else
! {
! replacement = find_fixup_replacement (replacements, SET_SRC (x));
! if (replacement->new)
! SET_SRC (x) = replacement->new;
! else if (GET_CODE (SET_SRC (x)) == SUBREG)
! SET_SRC (x) = replacement->new
! = fixup_memory_subreg (SET_SRC (x), insn, 0);
! else
! SET_SRC (x) = replacement->new
! = fixup_stack_1 (SET_SRC (x), insn);
! }
if (recog_memoized (insn) >= 0)
return;
brgds, H-P