When I added the support for __float128 last year, I accidentally broke
returning structures containing a single float or double item using the System
V 32-bit calling sequence.
This patch goes back to using SCALAR_FLOAT_TYPE_P (which looks at the tree
node) instead of SCALAR_FLOAT_MODE_NOT_VECTOR_P (which only looks at the
mode).
I have tested this patch on the trunk on a big endian power7 system, and there
were no regressions. The same patch applies to the GCC-6 branch, and I am
testing it now. Assuming there are no regresions on the GCC-6 branch, can I
check this patch into both the trunk and gcc-6-branch?
[gcc]
2016-07-18 Michael Meissner <[email protected]>
PR target/71493
* config/rs6000/rs6000.c (rs6000_function_value): Fix
unintentional System V.4 structure return breakage for structures
with a single floating point element.
[gcc/testsuite]
2016-07-18 Michael Meissner <[email protected]>
PR target/71493
* gcc.target/powerpc/pr71493-1.c: New test.
* gcc.target/powerpc/pr71493-2.c: Likewise.
Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c (revision 238438)
+++ gcc/config/rs6000/rs6000.c (working copy)
@@ -35467,7 +35467,8 @@ rs6000_function_value (const_tree valtyp
if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
/* _Decimal128 must use an even/odd register pair. */
regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN;
- else if (SCALAR_FLOAT_MODE_NOT_VECTOR_P (mode) && TARGET_HARD_FLOAT &&
TARGET_FPRS
+ else if (SCALAR_FLOAT_TYPE_P (valtype) && TARGET_HARD_FLOAT && TARGET_FPRS
+ && !FLOAT128_VECTOR_P (mode)
&& ((TARGET_SINGLE_FLOAT && (mode == SFmode)) ||
TARGET_DOUBLE_FLOAT))
regno = FP_ARG_RETURN;
else if (TREE_CODE (valtype) == COMPLEX_TYPE
Index: gcc/testsuite/gcc.target/powerpc/pr71493-2.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/pr71493-2.c (revision 0)
+++ gcc/testsuite/gcc.target/powerpc/pr71493-2.c (revision 0)
@@ -0,0 +1,13 @@
+/* { dg-do compile { target { powerpc*-*-linux* && ilp32 } } } */
+/* { dg-options "-O2 -m32 -msvr4-struct-return" } */
+
+struct S2 { double d; };
+
+struct S2 foo2 (void)
+{
+ struct S2 s = { 1.0 };
+ return s;
+}
+
+/* { dg-final { scan-assembler "lwz" } } */
+/* { dg-final { scan-assembler-not "lfd" } } */
Index: gcc/testsuite/gcc.target/powerpc/pr71493-1.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/pr71493-1.c (revision 0)
+++ gcc/testsuite/gcc.target/powerpc/pr71493-1.c (revision 0)
@@ -0,0 +1,13 @@
+/* { dg-do compile { target { powerpc*-*-linux* && ilp32 } } } */
+/* { dg-options "-O2 -m32 -msvr4-struct-return" } */
+
+struct S1 { float f; };
+
+struct S1 foo1 (void)
+{
+ struct S1 s = { 1.0f };
+ return s;
+}
+
+/* { dg-final { scan-assembler "lwz" } } */
+/* { dg-final { scan-assembler-not "lfs" } } */
--
Michael Meissner, IBM
IBM, M/S 2506R, 550 King Street, Littleton, MA 01460-6245, USA
email: [email protected], phone: +1 (978) 899-4797
Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c (revision 238438)
+++ gcc/config/rs6000/rs6000.c (working copy)
@@ -35467,7 +35467,8 @@ rs6000_function_value (const_tree valtyp
if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
/* _Decimal128 must use an even/odd register pair. */
regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN;
- else if (SCALAR_FLOAT_MODE_NOT_VECTOR_P (mode) && TARGET_HARD_FLOAT &&
TARGET_FPRS
+ else if (SCALAR_FLOAT_TYPE_P (valtype) && TARGET_HARD_FLOAT && TARGET_FPRS
+ && !FLOAT128_VECTOR_P (mode)
&& ((TARGET_SINGLE_FLOAT && (mode == SFmode)) ||
TARGET_DOUBLE_FLOAT))
regno = FP_ARG_RETURN;
else if (TREE_CODE (valtype) == COMPLEX_TYPE
Index: gcc/testsuite/gcc.target/powerpc/pr71493-2.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/pr71493-2.c (revision 0)
+++ gcc/testsuite/gcc.target/powerpc/pr71493-2.c (revision 0)
@@ -0,0 +1,13 @@
+/* { dg-do compile { target { powerpc*-*-linux* && ilp32 } } } */
+/* { dg-options "-O2 -m32 -msvr4-struct-return" } */
+
+struct S2 { double d; };
+
+struct S2 foo2 (void)
+{
+ struct S2 s = { 1.0 };
+ return s;
+}
+
+/* { dg-final { scan-assembler "lwz" } } */
+/* { dg-final { scan-assembler-not "lfd" } } */
Index: gcc/testsuite/gcc.target/powerpc/pr71493-1.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/pr71493-1.c (revision 0)
+++ gcc/testsuite/gcc.target/powerpc/pr71493-1.c (revision 0)
@@ -0,0 +1,13 @@
+/* { dg-do compile { target { powerpc*-*-linux* && ilp32 } } } */
+/* { dg-options "-O2 -m32 -msvr4-struct-return" } */
+
+struct S1 { float f; };
+
+struct S1 foo1 (void)
+{
+ struct S1 s = { 1.0f };
+ return s;
+}
+
+/* { dg-final { scan-assembler "lwz" } } */
+/* { dg-final { scan-assembler-not "lfs" } } */