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
This commit is contained in:
Uros Bizjak 2009-08-05 16:41:54 +02:00 committed by Uros Bizjak
parent 403c752036
commit 2c4389d869
6 changed files with 108 additions and 5 deletions

View 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

View 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)

View 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

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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);
}