aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorUros Bizjak <ubizjak@gmail.com>2009-08-05 16:41:54 +0200
committerUros Bizjak <uros@gcc.gnu.org>2009-08-05 16:41:54 +0200
commit2c4389d869152d94510dd52de9382c22d196d4ed (patch)
treea9533d423017e5d47fab676ef1ee7b0a66b1ecbb /gcc
parent403c752036db9af05c6d40804df668d3f3cbaf52 (diff)
downloadgcc-2c4389d869152d94510dd52de9382c22d196d4ed.zip
gcc-2c4389d869152d94510dd52de9382c22d196d4ed.tar.gz
gcc-2c4389d869152d94510dd52de9382c22d196d4ed.tar.bz2
re PR target/40906 (Wrong code generated for push of long double)
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: r150486
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/config/i386/i386.c21
-rw-r--r--gcc/testsuite/ChangeLog8
-rw-r--r--gcc/testsuite/gcc.target/i386/pr40906-1.c26
-rw-r--r--gcc/testsuite/gcc.target/i386/pr40906-2.c26
-rw-r--r--gcc/testsuite/gcc.target/i386/pr40906-3.c25
6 files changed, 108 insertions, 5 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 7fec758..42dc431 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index ff6373e..d0a8ba6 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -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)
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index e34aa8d..050d1df 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..c14bbfa
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr40906-1.c
@@ -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
index 0000000..66e146b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr40906-2.c
@@ -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
index 0000000..f95308d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr40906-3.c
@@ -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);
+}