expand: empty class return optimization [PR88529]
authorJason Merrill <jason@redhat.com>
Sun, 13 Jun 2021 18:00:12 +0000 (14:00 -0400)
committerJason Merrill <jason@redhat.com>
Mon, 21 Jun 2021 14:50:01 +0000 (10:50 -0400)
The x86_64 psABI says that an empty class isn't passed or returned in memory
or registers, so we shouldn't set %eax in this function.

The df-scan hunk catches the case where we look at a 0-length reg and build
a range the length of unsigned int, which happened before I changed
assign_parms to match expand_function_end.

PR target/88529

gcc/ChangeLog:

* df-scan.c (df_ref_record): Check that regno < endregno.
* function.c (assign_parms, expand_function_end): Do nothing with a
TYPE_EMPTY_P result.

gcc/testsuite/ChangeLog:

* g++.target/i386/empty-class1.C: New test.

gcc/df-scan.c
gcc/function.c
gcc/testsuite/g++.target/i386/empty-class1.C [new file with mode: 0644]

index 1268536..e9da64f 100644 (file)
@@ -2595,6 +2595,8 @@ df_ref_record (enum df_ref_class cl,
            ref_flags |= DF_REF_PARTIAL;
          ref_flags |= DF_REF_MW_HARDREG;
 
+         gcc_assert (regno < endregno);
+
          hardreg = problem_data->mw_reg_pool->allocate ();
          hardreg->type = ref_type;
          hardreg->flags = ref_flags;
index 6757695..6abaf3d 100644 (file)
@@ -3821,9 +3821,11 @@ 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))
+      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)))
        {
          rtx real_decl_rtl;
 
@@ -5410,9 +5412,11 @@ expand_function_end (void)
       tree decl_result = DECL_RESULT (current_function_decl);
       rtx decl_rtl = DECL_RTL (decl_result);
 
-      if (REG_P (decl_rtl)
-         ? REGNO (decl_rtl) >= FIRST_PSEUDO_REGISTER
-         : DECL_REGISTER (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)))
        {
          rtx real_decl_rtl = crtl->return_rtx;
          complex_mode cmode;
diff --git a/gcc/testsuite/g++.target/i386/empty-class1.C b/gcc/testsuite/g++.target/i386/empty-class1.C
new file mode 100644 (file)
index 0000000..c199277
--- /dev/null
@@ -0,0 +1,9 @@
+// PR target/88529
+// { dg-do compile { target { c++11 && x86_64-*-* } } }
+// { 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.
+
+class A{};
+
+A f() { return {}; }