diff options
author | Jakub Jelinek <jakub@redhat.com> | 2022-02-25 12:06:52 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@redhat.com> | 2022-02-25 12:06:52 +0100 |
commit | eabf7bbe601f2c0d87bd0a1012d7a602df2037da (patch) | |
tree | 765e23dbe230fa05ff5d72183a021866b8c62b48 /gcc | |
parent | 873b36af995f7f02bb6153320e35649a5d33b5fd (diff) | |
download | gcc-eabf7bbe601f2c0d87bd0a1012d7a602df2037da.zip gcc-eabf7bbe601f2c0d87bd0a1012d7a602df2037da.tar.gz gcc-eabf7bbe601f2c0d87bd0a1012d7a602df2037da.tar.bz2 |
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.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/config/i386/i386.h | 1 | ||||
-rw-r--r-- | gcc/config/i386/i386.md | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/pr104674.c | 31 |
3 files changed, 34 insertions, 3 deletions
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h index f41e090..b37d4a9 100644 --- a/gcc/config/i386/i386.h +++ b/gcc/config/i386/i386.h @@ -2414,6 +2414,7 @@ enum ix86_stack_slot SLOT_CW_FLOOR, SLOT_CW_CEIL, SLOT_STV_TEMP, + SLOT_FLOATxFDI_387, MAX_386_STACK_LOCALS }; diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 8ffa641..e7c5490 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -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; }) diff --git a/gcc/testsuite/gcc.target/i386/pr104674.c b/gcc/testsuite/gcc.target/i386/pr104674.c new file mode 100644 index 0000000..c8f3e9b --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr104674.c @@ -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 (); +} |