]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
reload.c (find_reloads): Force constants into literal pool also if they are wrapped...
authorAndreas Krebbel <krebbel1@de.ibm.com>
Wed, 6 Aug 2008 06:51:11 +0000 (06:51 +0000)
committerAndreas Krebbel <krebbel@gcc.gnu.org>
Wed, 6 Aug 2008 06:51:11 +0000 (06:51 +0000)
2008-08-06  Andreas Krebbel  <krebbel1@de.ibm.com>

* reload.c (find_reloads): Force constants into literal pool
also if they are wrapped in a SUBREG.

2008-08-06  Andreas Krebbel  <krebbel1@de.ibm.com>

  * gcc.c-torture/compile/20080806-1.c: New testcase.

From-SVN: r138763

gcc/ChangeLog
gcc/reload.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/compile/20080806-1.c [new file with mode: 0644]

index 7b50bdf77ad0e312283d622ad4133b0cbfb799dd..5ec9a6e1ad40a0ac43fc5f39075362d93032307e 100644 (file)
@@ -1,3 +1,8 @@
+2008-08-06  Andreas Krebbel  <krebbel1@de.ibm.com>
+
+       * reload.c (find_reloads): Force constants into literal pool
+       also if they are wrapped in a SUBREG.
+
 2008-08-06  Maxim Kuvyrkov  <maxim@codesourcery.com>
 
        PR target/35659
index a6ea4ff4e5a2c73c47b0f7e800ffea15cb113853..93fff40456985e8d35fb91e7800909682405d75a 100644 (file)
@@ -3843,49 +3843,61 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known,
   /* 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)
+    if (! goal_alternative_win[i])
       {
-       int this_address_reloaded;
+       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);
+         }
 
-       this_address_reloaded = 0;
-       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,
-                                &this_address_reloaded);
-       if (alternative_allows_const_pool_ref (this_address_reloaded == 0
-                                              ? substed_operand[i]
-                                              : NULL,
-                                              recog_data.constraints[i],
-                                              goal_alternative_number))
-         goal_alternative_win[i] = 1;
-      }
+       if (GET_CODE (op) == PLUS)
+         {
+           plus = op;
+           op = XEXP (op, 1);
+         }
 
-  /* 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);
+       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);
 
-       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_const_pool_ref (this_address_reloaded == 0
+                                                     ? substed_operand[i]
+                                                     : NULL,
+                                                     recog_data.constraints[i],
+                                                     goal_alternative_number))
+             goal_alternative_win[i] = 1;
+         }
       }
 
   /* Record the values of the earlyclobber operands for the caller.  */
index 0a3088ba8cc6d137131e75d736055feecbef85c6..92c95cc547bbbce8e94da6b0379570c66f332f94 100644 (file)
@@ -1,3 +1,7 @@
+2008-08-06  Andreas Krebbel  <krebbel1@de.ibm.com>
+
+       * gcc.c-torture/compile/20080806-1.c: New testcase.
+
 2008-08-06  Maxim Kuvyrkov  <maxim@codesourcery.com>
 
        * gcc.target/ia64/20080802-1.c: New test.
diff --git a/gcc/testsuite/gcc.c-torture/compile/20080806-1.c b/gcc/testsuite/gcc.c-torture/compile/20080806-1.c
new file mode 100644 (file)
index 0000000..33f0857
--- /dev/null
@@ -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;
+       }
+    }
+}