aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/function.c21
-rw-r--r--gcc/testsuite/g++.target/i386/empty-class1.C2
-rw-r--r--gcc/testsuite/g++.target/i386/empty-class2.C20
3 files changed, 34 insertions, 9 deletions
diff --git a/gcc/function.c b/gcc/function.c
index 6abaf3d116f..00b2fe70c7d 100644
--- a/gcc/function.c
+++ b/gcc/function.c
@@ -3821,17 +3821,22 @@ assign_parms (tree fndecl)
tree decl_result = DECL_RESULT (fndecl);
rtx decl_rtl = DECL_RTL (decl_result);
- if ((REG_P (decl_rtl)
- ? REGNO (decl_rtl) >= FIRST_PSEUDO_REGISTER
- : DECL_REGISTER (decl_result))
- /* Unless the psABI says not to. */
- && !TYPE_EMPTY_P (TREE_TYPE (decl_result)))
+ if (REG_P (decl_rtl)
+ ? REGNO (decl_rtl) >= FIRST_PSEUDO_REGISTER
+ : DECL_REGISTER (decl_result))
{
rtx real_decl_rtl;
- real_decl_rtl = targetm.calls.function_value (TREE_TYPE (decl_result),
- fndecl, true);
- REG_FUNCTION_VALUE_P (real_decl_rtl) = 1;
+ /* Unless the psABI says not to. */
+ if (TYPE_EMPTY_P (TREE_TYPE (decl_result)))
+ real_decl_rtl = NULL_RTX;
+ else
+ {
+ real_decl_rtl
+ = targetm.calls.function_value (TREE_TYPE (decl_result),
+ fndecl, true);
+ REG_FUNCTION_VALUE_P (real_decl_rtl) = 1;
+ }
/* The delay slot scheduler assumes that crtl->return_rtx
holds the hard register containing the return value, not a
temporary pseudo. */
diff --git a/gcc/testsuite/g++.target/i386/empty-class1.C b/gcc/testsuite/g++.target/i386/empty-class1.C
index c1992772d26..96a1fad5046 100644
--- a/gcc/testsuite/g++.target/i386/empty-class1.C
+++ b/gcc/testsuite/g++.target/i386/empty-class1.C
@@ -1,5 +1,5 @@
// PR target/88529
-// { dg-do compile { target { c++11 && x86_64-*-* } } }
+// { dg-do compile { target { c++11 && lp64 } } }
// { dg-additional-options -fdump-rtl-expand }
// { dg-final { scan-rtl-dump-not "set" "expand" } }
// The x86_64 psABI says that f() doesn't put the return value anywhere.
diff --git a/gcc/testsuite/g++.target/i386/empty-class2.C b/gcc/testsuite/g++.target/i386/empty-class2.C
new file mode 100644
index 00000000000..b9317c56706
--- /dev/null
+++ b/gcc/testsuite/g++.target/i386/empty-class2.C
@@ -0,0 +1,20 @@
+// PR middle-end/101160
+// Test passing aligned empty aggregate
+// { dg-do compile }
+// { dg-options "-O2" }
+// { dg-additional-options "-Wno-psabi" { target { { i?86-*-* x86_64-*-* } && ilp32 } } }
+
+struct S { union {} a; } __attribute__((aligned));
+
+S
+foo (S arg)
+{
+ return arg;
+}
+
+void
+bar (void)
+{
+ S arg;
+ foo (arg);
+}