File nov415378.diff of Package gcc41

Index: gcc/testsuite/gcc.c-torture/compile/20080805-1.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ gcc/testsuite/gcc.c-torture/compile/20080805-1.c	2009-11-20 13:42:35.000000000 +0100
@@ -0,0 +1,33 @@
+int gl2;
+typedef __SIZE_TYPE__ size_t;
+
+extern void *memcpy (void *dest, const void *src, size_t n);
+
+void
+f1 ()
+{
+  int i2;
+  unsigned char bf[64 * 1024 + 4];
+
+  for (i2 = 0; i2 < 3; i2++)
+    {
+      unsigned char *p2 = bf;
+      unsigned char *p3 = ((void *) 0);
+      unsigned short ctf2;
+
+      p2 += sizeof (short);
+
+      for (ctf2 = 0; ctf2 < 3; ctf2++)
+	{
+	  if (ctf2 == 1)
+	    {
+	      unsigned short of = p2 - bf - 6;
+	      unsigned short *ofp = (unsigned short *) &of;
+	      memcpy (p3, ofp, sizeof (short));
+	    }
+
+	  if (gl2 == 1)
+	    p2 += 3;
+	}
+    }
+}
Index: gcc/reload.c
===================================================================
--- gcc/reload.c.orig	2009-11-20 13:42:32.000000000 +0100
+++ gcc/reload.c	2009-11-20 13:42:35.000000000 +0100
@@ -3828,47 +3828,62 @@ find_reloads (rtx insn, int replace, int
 	     ? RELOAD_FOR_INSN : RELOAD_OTHER);
     }
 
-  /* Any constants that aren't allowed and can't be reloaded
-     into registers are here changed into memory references.  */
-  for (i = 0; i < noperands; i++)
-    if (! goal_alternative_win[i]
-	&& CONST_POOL_OK_P (recog_data.operand[i])
-	&& ((PREFERRED_RELOAD_CLASS (recog_data.operand[i],
-				     (enum reg_class) goal_alternative[i])
-	     == NO_REGS)
-	    || no_input_reloads)
-	&& operand_mode[i] != VOIDmode)
-      {
-	substed_operand[i] = recog_data.operand[i]
-	  = find_reloads_toplev (force_const_mem (operand_mode[i],
-						  recog_data.operand[i]),
-				 i, address_type[i], ind_levels, 0, insn,
-				 NULL);
-	if (alternative_allows_memconst (recog_data.constraints[i],
-					 goal_alternative_number))
-	  goal_alternative_win[i] = 1;
-      }
+    /* Any constants that aren't allowed and can't be reloaded
+       into registers are here changed into memory references.  */
+    for (i = 0; i < noperands; i++)
+    if (! goal_alternative_win[i])
+        {
+	rtx op = recog_data.operand[i];
+	rtx subreg = NULL_RTX;
+	rtx plus = NULL_RTX;
+	enum machine_mode mode = operand_mode[i];
+
+	/* Reloads of SUBREGs of CONSTANT RTXs are handled later in
+	   push_reload so we have to let them pass here.  */
+	if (GET_CODE (op) == SUBREG)
+	  {
+	    subreg = op;
+	    op = SUBREG_REG (op);
+	    mode = GET_MODE (op);
+	  }
+
+	if (GET_CODE (op) == PLUS)
+	  {
+	    plus = op;
+	    op = XEXP (op, 1);
+	  }
+
+	if (CONST_POOL_OK_P (op)
+	    && ((PREFERRED_RELOAD_CLASS (op,
+					 (enum reg_class) goal_alternative[i])
+		 == NO_REGS)
+		|| no_input_reloads)
+	    && mode != VOIDmode)
+	  {
+	    int this_address_reloaded;
+	    rtx tem = force_const_mem (mode, op);
 
-  /* Likewise any invalid constants appearing as operand of a PLUS
-     that is to be reloaded.  */
-  for (i = 0; i < noperands; i++)
-    if (! goal_alternative_win[i]
-	&& GET_CODE (recog_data.operand[i]) == PLUS
-	&& CONST_POOL_OK_P (XEXP (recog_data.operand[i], 1))
-	&& (PREFERRED_RELOAD_CLASS (XEXP (recog_data.operand[i], 1),
-				    (enum reg_class) goal_alternative[i])
-	     == NO_REGS)
-	&& operand_mode[i] != VOIDmode)
-      {
-	rtx tem = force_const_mem (operand_mode[i],
-				   XEXP (recog_data.operand[i], 1));
-	tem = gen_rtx_PLUS (operand_mode[i],
-			    XEXP (recog_data.operand[i], 0), tem);
-
-	substed_operand[i] = recog_data.operand[i]
-	  = find_reloads_toplev (tem, i, address_type[i],
-				 ind_levels, 0, insn, NULL);
-      }
+	    /* If we stripped a SUBREG or a PLUS above add it back.  */
+	    if (plus != NULL_RTX)
+	      tem = gen_rtx_PLUS (mode, XEXP (plus, 0), tem);
+
+	    if (subreg != NULL_RTX)
+	      tem = gen_rtx_SUBREG (operand_mode[i], tem, SUBREG_BYTE (subreg));
+
+	    this_address_reloaded = 0;
+	    substed_operand[i] = recog_data.operand[i]
+	      = find_reloads_toplev (tem, i, address_type[i], ind_levels,
+				     0, insn, &this_address_reloaded);
+
+	    /* If the alternative accepts constant pool refs directly
+	       there will be no reload needed at all.  */
+	if (plus == NULL_RTX
+	    && subreg == NULL_RTX
+	    && alternative_allows_memconst (recog_data.constraints[i],
+					 goal_alternative_number))
+	      goal_alternative_win[i] = 1;
+	  }
+        }
 
   /* Record the values of the earlyclobber operands for the caller.  */
   if (goal_earlyclobber)
openSUSE Build Service is sponsored by