OSDN Git Service

PR target/40906
authoruros <uros@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 5 Aug 2009 14:41:54 +0000 (14:41 +0000)
committeruros <uros@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 5 Aug 2009 14:41:54 +0000 (14:41 +0000)
* config/i386/i386.c (ix86_split_long_move): Fix push of multi-part
source operand.

testsuite/ChangeLog:

PR target/40906
* gcc.target/i386/pr40906-1.c: New test.
* gcc.target/i386/pr40906-2.c: Ditto.
* gcc.target/i386/pr40906-3.c: Ditto.

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

gcc/ChangeLog
gcc/config/i386/i386.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/i386/pr40906-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/pr40906-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/pr40906-3.c [new file with mode: 0644]

index 7fec758..42dc431 100644 (file)
@@ -1,3 +1,10 @@
+2009-08-05  Uros Bizjak  <ubizjak@gmail.com>
+           Mikulas Patocka  <mikulas@artax.karlin.mff.cuni.cz>
+
+       PR target/40906
+       * config/i386/i386.c (ix86_split_long_move): Fix push of multi-part
+       source operand.
+
 2009-08-05  Jakub Jelinek  <jakub@redhat.com>
 
        PR rtl-optimization/40924
index ff6373e..d0a8ba6 100644 (file)
@@ -16764,10 +16764,20 @@ ix86_split_long_move (rtx operands[])
   /* When emitting push, take care for source operands on the stack.  */
   if (push && MEM_P (operands[1])
       && reg_overlap_mentioned_p (stack_pointer_rtx, operands[1]))
-    for (i = 0; i < nparts - 1; i++)
-      part[1][i] = change_address (part[1][i],
-                                  GET_MODE (part[1][i]),
-                                  XEXP (part[1][i + 1], 0));
+    {
+      rtx src_base = XEXP (part[1][nparts - 1], 0);
+
+      /* Compensate for the stack decrement by 4.  */
+      if (!TARGET_64BIT && nparts == 3
+         && mode == XFmode && TARGET_128BIT_LONG_DOUBLE)
+       src_base = plus_constant (src_base, 4);
+
+      /* src_base refers to the stack pointer and is
+        automatically decreased by emitted push.  */
+      for (i = 0; i < nparts; i++)
+       part[1][i] = change_address (part[1][i],
+                                    GET_MODE (part[1][i]), src_base);
+    }
 
   /* We need to do copy in the right order in case an address register
      of the source overlaps the destination.  */
@@ -16837,7 +16847,8 @@ ix86_split_long_move (rtx operands[])
          if (nparts == 3)
            {
              if (TARGET_128BIT_LONG_DOUBLE && mode == XFmode)
-                emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx, GEN_INT (-4)));
+                emit_insn (gen_addsi3 (stack_pointer_rtx,
+                                      stack_pointer_rtx, GEN_INT (-4)));
              emit_move_insn (part[0][2], part[1][2]);
            }
          else if (nparts == 4)
index e34aa8d..050d1df 100644 (file)
@@ -1,3 +1,11 @@
+2009-08-05  Uros Bizjak  <ubizjak@gmail.com>
+           Mikulas Patocka  <mikulas@artax.karlin.mff.cuni.cz>
+
+       PR target/40906
+       * gcc.target/i386/pr40906-1.c: New test.
+       * gcc.target/i386/pr40906-2.c: Ditto.
+       * gcc.target/i386/pr40906-3.c: Ditto.
+
 2009-08-05  Jakub Jelinek  <jakub@redhat.com>
 
        PR rtl-optimization/40924
diff --git a/gcc/testsuite/gcc.target/i386/pr40906-1.c b/gcc/testsuite/gcc.target/i386/pr40906-1.c
new file mode 100644 (file)
index 0000000..c14bbfa
--- /dev/null
@@ -0,0 +1,26 @@
+/* { dg-do run } */
+/* { dg-require-effective-target ilp32 } */
+/* { dg-options "-O2 -fomit-frame-pointer -mpush-args -mno-accumulate-outgoing-args" } */
+
+void abort (void);
+
+void __attribute__((noinline))
+f (long double a)
+{
+  if (a != 1.23L)
+    abort ();
+}
+
+int __attribute__((noinline))
+g (long double b)
+{
+  f (b);
+  return 0;
+}
+
+int
+main (void)
+{
+  g (1.23L);
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr40906-2.c b/gcc/testsuite/gcc.target/i386/pr40906-2.c
new file mode 100644 (file)
index 0000000..66e146b
--- /dev/null
@@ -0,0 +1,26 @@
+/* { dg-do run } */
+/* { dg-require-effective-target ilp32 } */
+/* { dg-options "-O2 -fomit-frame-pointer -mpush-args -mno-accumulate-outgoing-args -m128bit-long-double" } */
+
+void abort (void);
+
+void __attribute__((noinline))
+f (long double a)
+{
+  if (a != 1.23L)
+    abort ();
+}
+
+int __attribute__((noinline))
+g (long double b)
+{
+  f (b);
+  return 0;
+}
+
+int
+main (void)
+{
+  g (1.23L);
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr40906-3.c b/gcc/testsuite/gcc.target/i386/pr40906-3.c
new file mode 100644 (file)
index 0000000..f95308d
--- /dev/null
@@ -0,0 +1,25 @@
+/* { dg-do run } */
+/* { dg-require-effective-target ilp32 } */
+/* { dg-options "-O2 -fomit-frame-pointer -msse2 -mpush-args -mno-accumulate-outgoing-args" } */
+
+#include "sse2-check.h"
+
+void __attribute__((noinline))
+f (__float128 a)
+{
+  if (a != 1.23Q)
+    abort ();
+}
+
+int __attribute__((noinline))
+g (__float128 b)
+{
+  f (b);
+  return 0;
+}
+
+static void
+sse2_test (void)
+{
+  g (1.23Q);
+}