i386: Use a new temp slot kind for splitter to floatdi<mode>2_i387_with_xmm [PR104674]
As mentioned in the PR, the following testcase is miscompiled for similar reasons as the already fixed PR78791 - we use SLOT_TEMP slots in various places during expansion and during expansion we can guarantee that the lifetime of those temporary slot doesn't overlap. But the following splitter uses SLOT_TEMP too and in between expansion and split1 there is a possibility that something extends the lifetime of SLOT_TEMP created slots across an instruction that will be split by this splitter. The following patch fixes it by using a new temp slot kind to make sure it doesn't reuse a SLOT_TEMP that could be live across the instruction. 2022-02-25 Jakub Jelinek <jakub@redhat.com> PR target/104674 * config/i386/i386.h (enum ix86_stack_slot): Add SLOT_FLOATxFDI_387. * config/i386/i386.md (splitter to floatdi<mode>2_i387_with_xmm): Use SLOT_FLOATxFDI_387 rather than SLOT_TEMP. * gcc.target/i386/pr104674.c: New test.
This commit is contained in:
parent
873b36af99
commit
eabf7bbe60
@ -2414,6 +2414,7 @@ enum ix86_stack_slot
|
||||
SLOT_CW_FLOOR,
|
||||
SLOT_CW_CEIL,
|
||||
SLOT_STV_TEMP,
|
||||
SLOT_FLOATxFDI_387,
|
||||
MAX_386_STACK_LOCALS
|
||||
};
|
||||
|
||||
|
@ -5412,9 +5412,8 @@
|
||||
&& can_create_pseudo_p ()"
|
||||
[(const_int 0)]
|
||||
{
|
||||
emit_insn (gen_floatdi<mode>2_i387_with_xmm
|
||||
(operands[0], operands[1],
|
||||
assign_386_stack_local (DImode, SLOT_TEMP)));
|
||||
rtx s = assign_386_stack_local (DImode, SLOT_FLOATxFDI_387);
|
||||
emit_insn (gen_floatdi<mode>2_i387_with_xmm (operands[0], operands[1], s));
|
||||
DONE;
|
||||
})
|
||||
|
||||
|
31
gcc/testsuite/gcc.target/i386/pr104674.c
Normal file
31
gcc/testsuite/gcc.target/i386/pr104674.c
Normal file
@ -0,0 +1,31 @@
|
||||
/* PR target/104674 */
|
||||
/* { dg-do run { target sse2_runtime } } */
|
||||
/* { dg-options "-O2 -msse2 -mfpmath=sse" } */
|
||||
|
||||
__attribute__((noipa)) double
|
||||
bar (double x, double y)
|
||||
{
|
||||
return x + y;
|
||||
}
|
||||
|
||||
__attribute__((noipa)) double
|
||||
foo (long long x)
|
||||
{
|
||||
long long a = x / 10000000;
|
||||
int b = x % 10000000;
|
||||
double s = (double) a;
|
||||
double n = (double) b / 1e7;
|
||||
double t = s + n;
|
||||
if (t == s + 1.0)
|
||||
t = bar (t, s);
|
||||
return t;
|
||||
}
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
long long n = 888888;
|
||||
n = n * 10000000;
|
||||
if (foo (n) != 888888.0)
|
||||
__builtin_abort ();
|
||||
}
|
Loading…
Reference in New Issue
Block a user