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  <meiss...@linux.vnet.ibm.com>

        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  <meiss...@linux.vnet.ibm.com>

        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: meiss...@linux.vnet.ibm.com, 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" } } */

Reply via email to