From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 48) id 955E4385E836; Wed, 15 May 2024 07:24:44 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 955E4385E836 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1715757884; bh=vXZr64rLAcZ/jxgtJUW5wg/tj/1Zj8pcBNDiKUgNQaM=; h=From:To:Subject:Date:In-Reply-To:References:From; b=O1a3Ogpn4QbnG1GpHCl2ZDKRnu6k4kXFFKObKX8wRdOtwyacDxVFdL1kv+b4OhuWI N+SO02ApiASr5c+m/tM18F/0C1JlMrRkQRInRonv/rhTd5oU+hvbsZO9uIERdRROwU lK362K3nJ9KhmGN2dtrpYWT4abvoy9Tfkk8mZIAE= From: "rguenth at gcc dot gnu.org" To: gcc-bugs@gcc.gnu.org Subject: [Bug ipa/115097] Strange suboptimal codegen specifically at -O2 when copying struct type Date: Wed, 15 May 2024 07:24:44 +0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: changed X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: gcc X-Bugzilla-Component: ipa X-Bugzilla-Version: 15.0 X-Bugzilla-Keywords: missed-optimization X-Bugzilla-Severity: normal X-Bugzilla-Who: rguenth at gcc dot gnu.org X-Bugzilla-Status: RESOLVED X-Bugzilla-Resolution: DUPLICATE X-Bugzilla-Priority: P3 X-Bugzilla-Assigned-To: unassigned at gcc dot gnu.org X-Bugzilla-Target-Milestone: --- X-Bugzilla-Flags: X-Bugzilla-Changed-Fields: Message-ID: In-Reply-To: References: Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Bugzilla-URL: http://gcc.gnu.org/bugzilla/ Auto-Submitted: auto-generated MIME-Version: 1.0 List-Id: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=3D115097 --- Comment #5 from Richard Biener --- Testcase for the inliner issue: struct A { int a; short b; }; A test(A& a) { return a; } A test1(A& a) { return test(a); } where the issue is that test() doesn't use DECL_RESULT for its return and t= hus declare_return_variable setting up DECL_RESULT mapped to the call LHS doesn= 't help. And the reason why we don't use DECL_RESULT is that we have > side-effects arg:0 unit-size align:32 warn_if_not_align:0 symtab:0 alias-set -1 canonical-ty= pe 0x7ffff6bbdbd0 fields context full-name "struct A" X() X(constX&) this=3D(X&) n_parents=3D0 use_template=3D0 interface-unknown pointer_to_this reference_to_this chain > side-effects arg:0 ignored DI t2.ii:2:1 size unit-= size align:32 warn_if_not_align:0 context > arg:1 side-effects tree_3 arg:0 ... and gimplification changes the RESULT_DECL return because /* If aggregate_value_p is true, then we can return the bare RESULT_DECL. Recall that aggregate_value_p is FALSE for any aggregate type that is returned in registers. If we're returning values in registers, then we don't want to extend the lifetime of the RESULT_DECL, particularly across another call. In addition, for those aggregates for which hard_function_value generates a PARALLEL, we'll die during normal expansion of structure assignments; there's special code in expand_ret= urn to handle this case that does not exist in expand_expr. */ but the code does something else, using a new temporary register (here !aggregate_value_p). The following fixes that. diff --git a/gcc/gimplify.cc b/gcc/gimplify.cc index b0ed58ed0f9..e4cf5438e39 100644 --- a/gcc/gimplify.cc +++ b/gcc/gimplify.cc @@ -1873,7 +1873,8 @@ gimplify_return_expr (tree stmt, gimple_seq *pre_p) to handle this case that does not exist in expand_expr. */ if (!result_decl) result =3D NULL_TREE; - else if (aggregate_value_p (result_decl, TREE_TYPE (current_function_dec= l))) + else if (aggregate_value_p (result_decl, TREE_TYPE (current_function_dec= l)) + || !is_gimple_reg_type (TREE_TYPE (result_decl))) { if (!poly_int_tree_p (DECL_SIZE (result_decl))) {=