diff options
author | Uros Bizjak <ubizjak@gmail.com> | 2009-08-05 16:41:54 +0200 |
---|---|---|
committer | Uros Bizjak <uros@gcc.gnu.org> | 2009-08-05 16:41:54 +0200 |
commit | 2c4389d869152d94510dd52de9382c22d196d4ed (patch) | |
tree | a9533d423017e5d47fab676ef1ee7b0a66b1ecbb | |
parent | 403c752036db9af05c6d40804df668d3f3cbaf52 (diff) | |
download | gcc-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
-rw-r--r-- | gcc/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/config/i386/i386.c | 21 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/pr40906-1.c | 26 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/pr40906-2.c | 26 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/pr40906-3.c | 25 |
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); +} |