]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR target/40906 (Wrong code generated for push of long double)
authorUros Bizjak <ubizjak@gmail.com>
Wed, 5 Aug 2009 21:16:52 +0000 (23:16 +0200)
committerUros Bizjak <uros@gcc.gnu.org>
Wed, 5 Aug 2009 21:16:52 +0000 (23:16 +0200)
PR target/40906
* 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.

Co-Authored-By: Mikulas Patocka <mikulas@artax.karlin.mff.cuni.cz>
From-SVN: r150501

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 3dbb47506882baddc872d8fae0583616d65fd20b..ae1673f4dc0d61ef007ff7e1c5242fb1a54e160e 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-04  Uros Bizjak  <ubizjak@gmail.com>
 
        Backport from mainline:
index 2b66975cc45593f39d32f1c164cca05097f56b26..a759028b1c8a75235a9688144d80fbaa3b9b7e60 100644 (file)
@@ -14052,11 +14052,19 @@ ix86_split_long_move (rtx operands[])
   if (push && MEM_P (operands[1])
       && reg_overlap_mentioned_p (stack_pointer_rtx, operands[1]))
     {
-      if (nparts == 3)
-       part[1][1] = change_address (part[1][1], GET_MODE (part[1][1]),
-                                    XEXP (part[1][2], 0));
-      part[1][0] = change_address (part[1][0], GET_MODE (part[1][0]),
-                                  XEXP (part[1][1], 0));
+      rtx src_base = XEXP (part[1][nparts - 1], 0);
+      int i;
+
+      /* 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
index a8543d14776fecc98f6a580438d28e334e541852..b75f6a336fe9932d73e04332796b413e5b90f226 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-04  Dodji Seketeli  <dodji@redhat.com>
 
        PR debug/39706
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..4a233b6
--- /dev/null
@@ -0,0 +1,25 @@
+/* { dg-do run { target *-*-linux* } } */
+/* { 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.23L)
+    abort ();
+}
+
+int __attribute__((noinline))
+g (__float128 b)
+{
+  f (b);
+  return 0;
+}
+
+static void
+sse2_test (void)
+{
+  g (1.23L);
+}