From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 48) id D31F93858C30; Thu, 2 Feb 2023 10:15:14 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org D31F93858C30 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1675332914; bh=wvUpQtaMYaAvgGq0AiqkLj8hyep5wSHXtqQUmm/gRhA=; h=From:To:Subject:Date:In-Reply-To:References:From; b=lgyWU27EUWMrpE8u7luH6RwCC0/yAG5egdZpMPkymV3FnV684qf2KCyUDnRrISGoZ D5RFBvaZ//S7/tTF2Yzbi3t0Z9mJZeHY0KzpoXwUPWnpa5pZitrJyo2o2rTSRVtt/c 39mNG0fAZg85maeToVkAtKVB3VN3n95JyF2pDZDI= From: "redi at gcc dot gnu.org" To: gcc-bugs@gcc.gnu.org Subject: [Bug tree-optimization/45115] pure functions returning structs are not optimized. Date: Thu, 02 Feb 2023 10:15:13 +0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: changed X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: gcc X-Bugzilla-Component: tree-optimization X-Bugzilla-Version: unknown X-Bugzilla-Keywords: missed-optimization X-Bugzilla-Severity: enhancement X-Bugzilla-Who: redi at gcc dot gnu.org X-Bugzilla-Status: NEW X-Bugzilla-Resolution: 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=3D45115 --- Comment #4 from Jonathan Wakely --- This affects C++20 three-way comparisons, which return trivial structs wrap= ping an integer. >From PR 108635: #include struct S { std::weak_ordering operator<=3D>(const S&) const __attribute__((con= st)); }; int compare3way(S& a, S& b) { return (a < b) ? -1 : (a > b) ? 1 : 0; } I expect operator<=3D> to be called once, but it is called twice. This can= be a major missed optimization if operator<=3D> is expensive. It happens regard= less of: 1. Using attribute((const)) or attribute((pure)). 2. Making operator<=3D> a free function or a member. 3. Comparing (a > b) or (a < b) in the second ternary expression. This is especially strange, because it's really calling the same pure function twic= e, and that's optimized correctly when the function being called is operator< instead of operator<=3D>. Clang optimizes it as expected. Demo: https://godbolt.org/z/jP51E6xaz=