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]

[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


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