OSDN Git Service

PR rtl-optimization/25703
authorsayle <sayle@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 26 Jan 2006 02:48:01 +0000 (02:48 +0000)
committersayle <sayle@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 26 Jan 2006 02:48:01 +0000 (02:48 +0000)
* combine.c (try_combine): Handle zero_extract and strict_low_part
of non-lowpart SUBREGs for constant reg_subword_p set optimization.

* gcc.target/i386/20060125-1.c: New test case.
* gcc.target/i386/20060125-2.c: New test case.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@110242 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/combine.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/i386/20060125-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/20060125-2.c [new file with mode: 0644]

index 370f701..df995ab 100644 (file)
@@ -1,3 +1,9 @@
+2006-01-25  Roger Sayle  <roger@eyesopen.com>
+
+       PR rtl-optimization/25703
+       * combine.c (try_combine): Handle zero_extract and strict_low_part
+       of non-lowpart SUBREGs for constant reg_subword_p set optimization.
+
 2006-01-25  Peter Bergner  <bergner@vnet.ibm.com>
 
        * global.c: Fix comment typos.
index 0ec4580..2c90be5 100644 (file)
@@ -1951,40 +1951,38 @@ try_combine (rtx i3, rtx i2, rtx i1, int *new_direct_jump_p)
       int offset = -1;
       int width = 0;
 
-      if (GET_CODE (dest) == STRICT_LOW_PART)
-       {
-         width = GET_MODE_BITSIZE (GET_MODE (XEXP (dest, 0)));
-         offset = 0;
-       }
-      else if (GET_CODE (dest) == ZERO_EXTRACT)
+      if (GET_CODE (dest) == ZERO_EXTRACT)
        {
          if (GET_CODE (XEXP (dest, 1)) == CONST_INT
              && GET_CODE (XEXP (dest, 2)) == CONST_INT)
            {
              width = INTVAL (XEXP (dest, 1));
              offset = INTVAL (XEXP (dest, 2));
-
+             dest = XEXP (dest, 0);
              if (BITS_BIG_ENDIAN)
-               offset = GET_MODE_BITSIZE (GET_MODE (XEXP (dest, 0)))
-                        - width - offset;
+               offset = GET_MODE_BITSIZE (GET_MODE (dest)) - width - offset;
            }
        }
-      else if (subreg_lowpart_p (dest))
+      else
        {
+         if (GET_CODE (dest) == STRICT_LOW_PART)
+           dest = XEXP (dest, 0);
          width = GET_MODE_BITSIZE (GET_MODE (dest));
          offset = 0;
        }
-      /* ??? Preserve the original logic to handle setting the high word
-        of double-word pseudos, where inner is half the size of outer
-        but not the lowpart.  This could be generalized by handling
-        SUBREG_BYTE, WORDS_BIG_ENDIAN and BYTES_BIG_ENDIAN ourselves.
-        Unfortunately this logic is tricky to get right and probably
-        not worth the effort.  */
-      else if (GET_MODE_BITSIZE (GET_MODE (SET_DEST (temp)))
-              == 2 * GET_MODE_BITSIZE (GET_MODE (dest)))
+
+      if (offset >= 0)
        {
-         width = GET_MODE_BITSIZE (GET_MODE (dest));
-         offset = width;
+         /* If this is the low part, we're done.  */
+         if (subreg_lowpart_p (dest))
+           ;
+         /* Handle the case where inner is twice the size of outer.  */
+         else if (GET_MODE_BITSIZE (GET_MODE (SET_DEST (temp)))
+                  == 2 * GET_MODE_BITSIZE (GET_MODE (dest)))
+           offset += GET_MODE_BITSIZE (GET_MODE (dest));
+         /* Otherwise give up for now.  */
+         else
+           offset = -1;
        }
 
       if (offset >= 0)
index 28d3297..075def5 100644 (file)
@@ -1,3 +1,10 @@
+2006-01-25  Jan Hubicka  <jh@suse.cz>
+           Roger Sayle  <roger@eyesopen.com>
+
+       PR rtl-optimization/25703
+       * gcc.target/i386/20060125-1.c: New test case.
+       * gcc.target/i386/20060125-2.c: New test case.
+
 2006-01-25  Tobias Schlüter  <tobias.schlueter@physik.uni-muenchen.de>
 
        PR fortran/18540
diff --git a/gcc/testsuite/gcc.target/i386/20060125-1.c b/gcc/testsuite/gcc.target/i386/20060125-1.c
new file mode 100644 (file)
index 0000000..cbb4e65
--- /dev/null
@@ -0,0 +1,30 @@
+/* PR rtl-optimization/25703 */
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
+/* { dg-require-effective-target ilp32 } */
+/* { dg-options "-O2 -mtune=i486" } */
+
+extern void abort (void);
+
+struct a
+{
+        int a;
+        char b,c,d,e;
+};
+
+__attribute__ ((noinline))
+__attribute__ ((regparm(1))) t(struct a a)
+{
+        if (a.a!=1 || a.b!=1 || a.c!=1)
+                        abort();
+}
+
+int main()
+{
+        struct a a;
+        a.c=1;
+        a.a=1;
+        a.b=1;
+        t(a);
+        return 0;
+}
+
diff --git a/gcc/testsuite/gcc.target/i386/20060125-2.c b/gcc/testsuite/gcc.target/i386/20060125-2.c
new file mode 100644 (file)
index 0000000..7964ca1
--- /dev/null
@@ -0,0 +1,30 @@
+/* PR rtl-optimization/25703 */
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
+/* { dg-require-effective-target ilp32 } */
+/* { dg-options "-O2 -mtune=pentiumpro" } */
+
+extern void abort (void);
+
+struct a
+{
+        int a;
+        char b,c,d,e;
+};
+
+__attribute__ ((noinline))
+__attribute__ ((regparm(1))) t(struct a a)
+{
+        if (a.a!=1 || a.b!=1 || a.c!=1)
+                        abort();
+}
+
+int main()
+{
+        struct a a;
+        a.c=1;
+        a.a=1;
+        a.b=1;
+        t(a);
+        return 0;
+}
+