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]

post-inc & duplicate reloads



On stormy16, execute/920428-1.c and execute/920429-1.c fail because
combine creates

(insn 16 15 17 (parallel[ 
            (set (reg:HI 30)
                (ashift:HI (subreg:HI (mem:QI (post_inc:HI (reg/v/f:HI 25)) 0) 0)
                    (const_int 8 [0x8])))
            (clobber (scratch:BI))
        ] ) 13 {ashlhi3} (nil)
    (expr_list:REG_INC (reg/v/f:HI 25)
        (expr_list:REG_UNUSED (scratch:BI)
            (nil))))

This gets reloaded as:

Reloads for insn # 16
Reload 0: reload_in (QI) = (mem:QI (post_inc:HI (reg/v/f:HI 2 r2 [25])) 0)
        EIGHT_REGS, RELOAD_FOR_OTHER_ADDRESS (opnum = 0)
        reload_in_reg: (mem:QI (post_inc:HI (reg/v/f:HI 2 r2 [25])) 0)
        reload_reg_rtx: (reg:QI 5 r5)
Reload 1: reload_in (QI) = (mem:QI (post_inc:HI (reg/v/f:HI 2 r2 [25])) 0)
        reload_out (HI) = (reg:HI 9 r9 [30])
        EIGHT_REGS, RELOAD_OTHER (opnum = 0)
        reload_in_reg: (mem:QI (post_inc:HI (reg/v/f:HI 2 r2 [25])) 0)
        reload_out_reg: (reg:HI 9 r9 [30])
        reload_reg_rtx: (reg:HI 5 r5)
Reload 2: reload_out (BI) = (scratch:BI)
        CARRY_REGS, RELOAD_FOR_OUTPUT (opnum = 3)
        reload_out_reg: (scratch:BI)
        reload_reg_rtx: (reg:BI 16 carry)

which is wrong.  Reload 0 and reload 1 both increment r2, with the
result that r2 gets incremented by 4 instead of by 2.  Reload 0 is the
incorrect one.  Reload 0 is generated by the code introduced by this
patch:

http://gcc.gnu.org/ml/gcc-patches/2000-04/msg00328.html

There is already code in push_reloads which detects in-out operands
with side-effects and ensures that the side-effects happen only once,
under the comment

  /* If we have a read-write operand with an address side-effect,
     change either IN or OUT so the side-effect happens only once.  */

I believe that the patch is wrong.  I'd like to try to work out what
the right patch is, but the CRIS port never got contributed, so I'm
kind of stuck.

Reverting this patch fixed 21 testsuite failures on stormy16-elf, and
introduced no new ones (plus the bug causes atoi() to be miscompiled).
This is slightly unfortunate, because if it had introduced new
failures, that'd probably be the same bug that Hans saw.

Anyway, this seems to be the best I can do.  If anyone can reproduce
the problem that this patch originally fixed on a contributed port,
please contact me!  I will commit this in a day or two, to give Hans a
chance to respond.

-- 
- Geoffrey Keating <geoffk@geoffk.org>

===File ~/patches/cygnus/gcc-postincreload.patch============
2001-08-25  Geoffrey Keating  <geoffk@redhat.com>

	* reload.c (find_reloads_toplev): Back out this change:

	Wed Jul 26 19:44:05 2000   Hans-Peter Nilsson  <hp@axis.com>

	* reload.c (find_reloads_toplev): Reload a paradoxical subreg of a
	mem if the address is a mode_dependent_address_p.

Index: reload.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/reload.c,v
retrieving revision 1.156
diff -p -u -p -r1.156 reload.c
--- reload.c	2001/08/22 14:35:33	1.156
+++ reload.c	2001/08/25 19:28:42
@@ -4419,30 +4419,6 @@ find_reloads_toplev (x, opnum, type, ind
 	x = find_reloads_subreg_address (x, 1, opnum, type, ind_levels,
 					 insn);
     }
-  else if (code == SUBREG && GET_CODE (SUBREG_REG (x)) == MEM
-	   && (GET_MODE_SIZE (GET_MODE (x))
-	       > GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))))
-	   && mode_dependent_address_p (XEXP (SUBREG_REG (x), 0)))
-    {
-      /* A paradoxical subreg will simply have the mode of the access
-	 changed, so we need to reload such a memory operand to stabilize
-	 the meaning of the memory access.  */
-      enum machine_mode subreg_mode = GET_MODE (SUBREG_REG (x));
-
-      /* SUBREG_REG (x) is a MEM, so we cant take the offset, instead we 
-         calculate the register number as : 
-	 SUBREG_BYTE (x) / GET_MODE_SIZE (subreg_mode) */
-      if (is_set_dest)
-	push_reload (NULL_RTX, SUBREG_REG (x), (rtx*)0, &SUBREG_REG (x),
-		     find_valid_class (subreg_mode, 
-		     		SUBREG_BYTE (x) / GET_MODE_SIZE (subreg_mode)),
-		     VOIDmode, subreg_mode, 0, 0, opnum, type);
-      else
-	push_reload (SUBREG_REG (x), NULL_RTX, &SUBREG_REG (x), (rtx*)0,
-		     find_valid_class (subreg_mode,
-		     		SUBREG_BYTE (x) / GET_MODE_SIZE (subreg_mode)),
-		     subreg_mode, VOIDmode, 0, 0, opnum, type);
-    }
 
   for (copied = 0, i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
     {
============================================================


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