From 303d6cb2760304f5e6d00c4419c0dd1144588180 Mon Sep 17 00:00:00 2001 From: Mateusz B Date: Wed, 27 Mar 2019 22:17:48 +0100 Subject: [PATCH] re PR target/85667 (ms_abi rules aren't followed when returning short structs with float values) PR target/85667 * config/i386/i386.c (ix86_function_value_1): Call the newly added function for 32-bit MS_ABI. (function_value_ms_32): New function. testsuite/ChangeLog: PR target/85667 * gcc.target/i386/pr85667-5.c: New testcase. * gcc.target/i386/pr85667-6.c: New testcase. From-SVN: r269979 --- gcc/ChangeLog | 7 +++++++ gcc/config/i386/i386.c | 30 +++++++++++++++++++++++++--- gcc/testsuite/ChangeLog | 6 ++++++ gcc/testsuite/gcc.target/i386/pr85667-5.c | 33 +++++++++++++++++++++++++++++++ gcc/testsuite/gcc.target/i386/pr85667-6.c | 22 +++++++++++++++++++++ 5 files changed, 95 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/gcc.target/i386/pr85667-5.c create mode 100644 gcc/testsuite/gcc.target/i386/pr85667-6.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8801525..a4db0fc 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2019-03-27 Mateusz B + + PR target/85667 + * config/i386/i386.c (ix86_function_value_1): Call the newly added + function for 32-bit MS_ABI. + (function_value_ms_32): New function. + 2019-03-27 Andrew Stubbs * config/gcn/gcn.md (CC_SAVE_REG): New constant. diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 3ea5457..c695fcd 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -9273,6 +9273,25 @@ function_value_64 (machine_mode orig_mode, machine_mode mode, } static rtx +function_value_ms_32 (machine_mode orig_mode, machine_mode mode, + const_tree fntype, const_tree fn, const_tree valtype) +{ + unsigned int regno; + + /* Floating point return values in %st(0) + (unless -mno-fp-ret-in-387 or aggregate type of up to 8 bytes). */ + if (X87_FLOAT_MODE_P (mode) && TARGET_FLOAT_RETURNS_IN_80387 + && (GET_MODE_SIZE (mode) > 8 + || valtype == NULL_TREE || !AGGREGATE_TYPE_P (valtype))) + { + regno = FIRST_FLOAT_REG; + return gen_rtx_REG (orig_mode, regno); + } + else + return function_value_32(orig_mode, mode, fntype,fn); +} + +static rtx function_value_ms_64 (machine_mode orig_mode, machine_mode mode, const_tree valtype) { @@ -9317,9 +9336,14 @@ ix86_function_value_1 (const_tree valtype, const_tree fntype_or_decl, if (fntype_or_decl && DECL_P (fntype_or_decl)) fn = fntype_or_decl; fntype = fn ? TREE_TYPE (fn) : fntype_or_decl; - - if (TARGET_64BIT && ix86_function_type_abi (fntype) == MS_ABI) - return function_value_ms_64 (orig_mode, mode, valtype); + + if (ix86_function_type_abi (fntype) == MS_ABI) + { + if (TARGET_64BIT) + return function_value_ms_64 (orig_mode, mode, valtype); + else + return function_value_ms_32 (orig_mode, mode, fntype, fn, valtype); + } else if (TARGET_64BIT) return function_value_64 (orig_mode, mode, valtype); else diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index a378c4c..97908fe 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2019-03-27 Mateusz B + + PR target/85667 + * gcc.target/i386/pr85667-5.c: New testcase. + * gcc.target/i386/pr85667-6.c: New testcase. + 2019-03-27 Bill Schmidt PR testsuite/89834 diff --git a/gcc/testsuite/gcc.target/i386/pr85667-5.c b/gcc/testsuite/gcc.target/i386/pr85667-5.c new file mode 100644 index 0000000..3cf2162 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr85667-5.c @@ -0,0 +1,33 @@ +/* { dg-do run { target ia32 } } */ +/* { dg-options "-O2" } */ + +void abort (void); + +typedef struct +{ + float x; +} Float; + +Float __attribute__((ms_abi)) fn1 () +{ + Float v; + v.x = 3.145; + return v; +} + +Float fn2 () +{ + Float v; + v.x = 3.145; + return v; +} + +int main () +{ + Float a, b; + a = fn1 (); + b = fn2 (); + if (a.x == 3.145f && b.x == 3.145f) + return 0; + abort (); +} diff --git a/gcc/testsuite/gcc.target/i386/pr85667-6.c b/gcc/testsuite/gcc.target/i386/pr85667-6.c new file mode 100644 index 0000000..5d2c66e --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr85667-6.c @@ -0,0 +1,22 @@ +/* { dg-do compile { target ia32 } } */ +/* { dg-options "-O2" } */ +/* { dg-final { scan-assembler-times "movl\[^\n\r]*, %eax" 1 } } */ +/* { dg-final { scan-assembler-times "flds\[^\n\r]*" 1 } } */ +typedef struct +{ + float x; +} Float; + +Float __attribute__((ms_abi)) fn1 () +{ + Float v; + v.x = 3.145; + return v; +} + +float __attribute__((ms_abi)) fn2 () +{ + float v; + v = 3.145; + return v; +} -- 2.7.4