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
This commit is contained in:
Mateusz B 2019-03-27 22:17:48 +01:00 committed by Uros Bizjak
parent 1509905e82
commit 303d6cb276
5 changed files with 95 additions and 3 deletions

View file

@ -1,3 +1,10 @@
2019-03-27 Mateusz B <mateuszb@poczta.onet.pl>
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 <ams@codesourcery.com>
* config/gcn/gcn.md (CC_SAVE_REG): New constant.

View file

@ -9272,6 +9272,25 @@ function_value_64 (machine_mode orig_mode, machine_mode mode,
return ret;
}
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

View file

@ -1,3 +1,9 @@
2019-03-27 Mateusz B <mateuszb@poczta.onet.pl>
PR target/85667
* gcc.target/i386/pr85667-5.c: New testcase.
* gcc.target/i386/pr85667-6.c: New testcase.
2019-03-27 Bill Schmidt <wschmidt@linux.ibm.com>
PR testsuite/89834

View file

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

View file

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