diff options
author | H.J. Lu <hjl.tools@gmail.com> | 2020-02-07 03:37:46 -0800 |
---|---|---|
committer | H.J. Lu <hjl.tools@gmail.com> | 2020-02-07 03:37:58 -0800 |
commit | ea5ca698dca15dc86b823661ac357a30b49dd0f6 (patch) | |
tree | 9256b62d37d28fa39734359195992333b67026cf | |
parent | c006911de91ca9e23d7d2df069499c768d215eac (diff) | |
download | gcc-ea5ca698dca15dc86b823661ac357a30b49dd0f6.zip gcc-ea5ca698dca15dc86b823661ac357a30b49dd0f6.tar.gz gcc-ea5ca698dca15dc86b823661ac357a30b49dd0f6.tar.bz2 |
x86-64: Pass aggregates with only float/double in GPRs for MS_ABI
MS_ABI requires passing aggregates with only float/double in integer
registers as shown in the output from MSVC v19.10 at:
https://godbolt.org/z/2NPygd
This patch fixed:
FAIL: libffi.bhaible/test-callback.c -W -Wall -Wno-psabi -DDGTEST=54 -Wno-unused-variable -Wno-unused-parameter -Wno-unused-but-set-variable -Wno-uninitialized -O0 -DABI_NUM=FFI_GNUW64 -DABI_ATTR=MSABI execution test
FAIL: libffi.bhaible/test-callback.c -W -Wall -Wno-psabi -DDGTEST=54 -Wno-unused-variable -Wno-unused-parameter -Wno-unused-but-set-variable -Wno-uninitialized -O2 -DABI_NUM=FFI_GNUW64 -DABI_ATTR=MSABI execution test
FAIL: libffi.bhaible/test-callback.c -W -Wall -Wno-psabi -DDGTEST=55 -Wno-unused-variable -Wno-unused-parameter -Wno-unused-but-set-variable -Wno-uninitialized -O0 -DABI_NUM=FFI_GNUW64 -DABI_ATTR=MSABI execution test
FAIL: libffi.bhaible/test-callback.c -W -Wall -Wno-psabi -DDGTEST=55 -Wno-unused-variable -Wno-unused-parameter -Wno-unused-but-set-variable -Wno-uninitialized -O2 -DABI_NUM=FFI_GNUW64 -DABI_ATTR=MSABI execution test
FAIL: libffi.bhaible/test-callback.c -W -Wall -Wno-psabi -DDGTEST=56 -Wno-unused-variable -Wno-unused-parameter -Wno-unused-but-set-variable -Wno-uninitialized -O0 -DABI_NUM=FFI_GNUW64 -DABI_ATTR=MSABI execution test
FAIL: libffi.bhaible/test-callback.c -W -Wall -Wno-psabi -DDGTEST=56 -Wno-unused-variable -Wno-unused-parameter -Wno-unused-but-set-variable -Wno-uninitialized -O2 -DABI_NUM=FFI_GNUW64 -DABI_ATTR=MSABI execution test
in libffi testsuite.
gcc/
PR target/85667
* config/i386/i386.c (function_arg_ms_64): Add a type argument.
Don't return aggregates with only SFmode and DFmode in SSE
register.
(ix86_function_arg): Pass arg.type to function_arg_ms_64.
gcc/testsuite/
PR target/85667
* gcc.target/i386/pr85667-10.c: New test.
* gcc.target/i386/pr85667-7.c: Likewise.
* gcc.target/i386/pr85667-8.c: Likewise.
* gcc.target/i386/pr85667-9.c: Likewise.
-rw-r--r-- | gcc/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/config/i386/i386.c | 10 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/pr85667-10.c | 21 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/pr85667-7.c | 36 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/pr85667-8.c | 21 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/pr85667-9.c | 36 |
7 files changed, 137 insertions, 3 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a7babd2..21ecb2c 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2020-02-07 H.J. Lu <hongjiu.lu@intel.com> + + PR target/85667 + * config/i386/i386.c (function_arg_ms_64): Add a type argument. + Don't return aggregates with only SFmode and DFmode in SSE + register. + (ix86_function_arg): Pass arg.type to function_arg_ms_64. + 2020-02-07 Jakub Jelinek <jakub@redhat.com> PR target/93122 diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 556ca82..498cbb5 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -3153,7 +3153,7 @@ function_arg_64 (const CUMULATIVE_ARGS *cum, machine_mode mode, static rtx function_arg_ms_64 (const CUMULATIVE_ARGS *cum, machine_mode mode, - machine_mode orig_mode, bool named, + machine_mode orig_mode, bool named, const_tree type, HOST_WIDE_INT bytes) { unsigned int regno; @@ -3173,7 +3173,10 @@ function_arg_ms_64 (const CUMULATIVE_ARGS *cum, machine_mode mode, if (TARGET_SSE && (mode == SFmode || mode == DFmode)) { if (named) - regno = cum->regno + FIRST_SSE_REG; + { + if (type == NULL_TREE || !AGGREGATE_TYPE_P (type)) + regno = cum->regno + FIRST_SSE_REG; + } else { rtx t1, t2; @@ -3253,7 +3256,8 @@ ix86_function_arg (cumulative_args_t cum_v, const function_arg_info &arg) enum calling_abi call_abi = cum ? cum->call_abi : ix86_abi; if (call_abi == MS_ABI) - reg = function_arg_ms_64 (cum, mode, arg.mode, arg.named, bytes); + reg = function_arg_ms_64 (cum, mode, arg.mode, arg.named, + arg.type, bytes); else reg = function_arg_64 (cum, mode, arg.mode, arg.type, arg.named); } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 0c21d75..bd6610f 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2020-02-07 H.J. Lu <hongjiu.lu@intel.com> + + PR target/85667 + * gcc.target/i386/pr85667-10.c: New test. + * gcc.target/i386/pr85667-7.c: Likewise. + * gcc.target/i386/pr85667-8.c: Likewise. + * gcc.target/i386/pr85667-9.c: Likewise. + 2020-02-07 Jakub Jelinek <jakub@redhat.com> PR target/93122 diff --git a/gcc/testsuite/gcc.target/i386/pr85667-10.c b/gcc/testsuite/gcc.target/i386/pr85667-10.c new file mode 100644 index 0000000..e8f3026 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr85667-10.c @@ -0,0 +1,21 @@ +/* { dg-do compile { target lp64 } } */ +/* { dg-options "-O2 -masm=att" } */ +/* { dg-final { scan-assembler-times "movq\[ \t\]*%rcx, .*" 1 } } */ +/* { dg-final { scan-assembler-times "movq\[ \t\]*%rdx, .*" 1 } } */ +/* { dg-final { scan-assembler-times "movq\[ \t\]*%r8, .*" 1 } } */ +/* { dg-final { scan-assembler-times "movq\[ \t\]*%r9, .*" 1 } } */ +/* { dg-final { scan-assembler-times "addsd\[ \t]*40\\\(%rsp\\\), .*" 1 } } */ +/* { dg-final { scan-assembler-times "movq\[^\n\r\]*, %rax" 1 } } */ + +typedef struct +{ + double x; +} Double; + +Double __attribute__((ms_abi)) +fn1 (Double x1, Double x2, Double x3, Double x4, Double x5) +{ + Double v; + v.x = x1.x + x2.x + x3.x + x4.x + x5.x; + return v; +} diff --git a/gcc/testsuite/gcc.target/i386/pr85667-7.c b/gcc/testsuite/gcc.target/i386/pr85667-7.c new file mode 100644 index 0000000..6bd8609 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr85667-7.c @@ -0,0 +1,36 @@ +/* { dg-do run { target lp64 } } */ +/* { dg-options "-O2" } */ + +void abort (void); + +typedef struct +{ + float x; +} Float; + +Float __attribute__((ms_abi, noinline, noclone)) +fn1 (Float x1, Float x2, Float x3, Float x4, Float x5) +{ + Float v; + v.x = x1.x + x2.x + x3.x + x4.x + x5.x; + return v; +} +int main () +{ + Float a, a1, a2, a3, a4, a5; + float x1 = 1.1; + float x2 = 3.1; + float x3 = 4.2; + float x4 = 14.2; + float x5 = -7.2; + float x = x1 + x2 + x3 + x4 + x5; + a1.x = x1; + a2.x = x2; + a3.x = x3; + a4.x = x4; + a5.x = x5; + a = fn1 (a1, a2, a3, a4, a5); + if (a.x == x); + return 0; + abort (); +} diff --git a/gcc/testsuite/gcc.target/i386/pr85667-8.c b/gcc/testsuite/gcc.target/i386/pr85667-8.c new file mode 100644 index 0000000..09a7593 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr85667-8.c @@ -0,0 +1,21 @@ +/* { dg-do compile { target lp64 } } */ +/* { dg-options "-O2 -masm=att" } */ +/* { dg-final { scan-assembler-times "movd\[ \t\]*%ecx, .*" 1 } } */ +/* { dg-final { scan-assembler-times "movd\[ \t\]*%edx, .*" 1 } } */ +/* { dg-final { scan-assembler-times "movd\[ \t\]*%r8d, .*" 1 } } */ +/* { dg-final { scan-assembler-times "movd\[ \t\]*%r9d, .*" 1 } } */ +/* { dg-final { scan-assembler-times "addss\[ \t]*40\\\(%rsp\\\), .*" 1 } } */ +/* { dg-final { scan-assembler-times "movd\[^\n\r\]*, %eax" 1 } } */ + +typedef struct +{ + float x; +} Float; + +Float __attribute__((ms_abi)) +fn1 (Float x1, Float x2, Float x3, Float x4, Float x5) +{ + Float v; + v.x = x1.x + x2.x + x3.x + x4.x + x5.x; + return v; +} diff --git a/gcc/testsuite/gcc.target/i386/pr85667-9.c b/gcc/testsuite/gcc.target/i386/pr85667-9.c new file mode 100644 index 0000000..8c9279a --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr85667-9.c @@ -0,0 +1,36 @@ +/* { dg-do run { target lp64 } } */ +/* { dg-options "-O2" } */ + +void abort (void); + +typedef struct +{ + double x; +} Double; + +Double __attribute__((ms_abi, noinline, noclone)) +fn1 (Double x1, Double x2, Double x3, Double x4, Double x5) +{ + Double v; + v.x = x1.x + x2.x + x3.x + x4.x + x5.x; + return v; +} +int main () +{ + Double a, a1, a2, a3, a4, a5; + double x1 = 1.1; + double x2 = 3.1; + double x3 = 4.2; + double x4 = 14.2; + double x5 = -7.2; + double x = x1 + x2 + x3 + x4 + x5; + a1.x = x1; + a2.x = x2; + a3.x = x3; + a4.x = x4; + a5.x = x5; + a = fn1 (a1, a2, a3, a4, a5); + if (a.x == x); + return 0; + abort (); +} |