From: Uros Bizjak Date: Wed, 5 Aug 2009 21:16:52 +0000 (+0200) Subject: re PR target/40906 (Wrong code generated for push of long double) X-Git-Tag: releases/gcc-4.3.5~447 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=deecf5c1d5c95a760d8e04797bdded159406ad1b;p=thirdparty%2Fgcc.git 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 From-SVN: r150501 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3dbb47506882..ae1673f4dc0d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2009-08-05 Uros Bizjak + Mikulas Patocka + + PR target/40906 + * config/i386/i386.c (ix86_split_long_move): Fix push of multi-part + source operand. + 2009-08-04 Uros Bizjak Backport from mainline: diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 2b66975cc455..a759028b1c8a 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -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 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index a8543d14776f..b75f6a336fe9 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2009-08-05 Uros Bizjak + Mikulas Patocka + + 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 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 index 000000000000..c14bbfa3a4fa --- /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 000000000000..66e146b0ca01 --- /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 000000000000..4a233b60ed1f --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr40906-3.c @@ -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); +}