diff options
author | Jason Merrill <jason@redhat.com> | 2021-06-13 14:00:12 -0400 |
---|---|---|
committer | Jason Merrill <jason@redhat.com> | 2021-06-21 10:50:01 -0400 |
commit | 7232f7c4c2d727431096a7ecfcf4ad4db71dcf2a (patch) | |
tree | 2705e5c36221bf19624c09c493ee9bd193a4cc94 | |
parent | 12bdd39755a25d237b7776153cbe03e171396fc5 (diff) | |
download | gcc-7232f7c4c2d727431096a7ecfcf4ad4db71dcf2a.zip gcc-7232f7c4c2d727431096a7ecfcf4ad4db71dcf2a.tar.gz gcc-7232f7c4c2d727431096a7ecfcf4ad4db71dcf2a.tar.bz2 |
expand: empty class return optimization [PR88529]
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.
-rw-r--r-- | gcc/df-scan.c | 2 | ||||
-rw-r--r-- | gcc/function.c | 16 | ||||
-rw-r--r-- | gcc/testsuite/g++.target/i386/empty-class1.C | 9 |
3 files changed, 21 insertions, 6 deletions
diff --git a/gcc/df-scan.c b/gcc/df-scan.c index 1268536..e9da64f 100644 --- a/gcc/df-scan.c +++ b/gcc/df-scan.c @@ -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; diff --git a/gcc/function.c b/gcc/function.c index 6757695..6abaf3d 100644 --- a/gcc/function.c +++ b/gcc/function.c @@ -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 index 0000000..c199277 --- /dev/null +++ b/gcc/testsuite/g++.target/i386/empty-class1.C @@ -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 {}; } |