From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 48) id E05B23858C54; Wed, 7 Jun 2023 20:27:29 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org E05B23858C54 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1686169649; bh=S46QYsXGMSgaW7pYiDSEKnszFi1oN0L+O2lAHnOWbC8=; h=From:To:Subject:Date:In-Reply-To:References:From; b=YXjj91T9lehRDBvZ9THK0LjIF9nJjCWsTOqeHjJS637UY7jPamzmE9B8elWaWccwO nzJN52FkZ1jzGu8eAswScT+ehQub0yfvRN8galCXwicd0E0ANEjuDE077xOvLvXW3j vDWDj8oW2RQwyKJnDJKpcnRomsfYQ5svVjIcGyhM= From: "amacleod at redhat dot com" To: gcc-bugs@gcc.gnu.org Subject: [Bug tree-optimization/94566] conversion between std::strong_ordering and int Date: Wed, 07 Jun 2023 20:27:28 +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: 10.0 X-Bugzilla-Keywords: missed-optimization X-Bugzilla-Severity: enhancement X-Bugzilla-Who: amacleod at redhat dot com 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=3D94566 --- Comment #13 from Andrew Macleod --- (In reply to Andrew Pinski from comment #12) > Aldy or Andrew, why in conv1 we don't get a range for=20 > SR.4_4 =3D sD.8798._M_valueD.7665; >=20 > Even though the range we have is [-1,1] according to the > __builtin_unreachable()? > It seems like we should get that range. Once we do get that the code work= s. > E.g. If we add: > signed char *t =3D (signed char*)&s; > signed char tt =3D *t; > if (tt < -1 || tt > 1) __builtin_unreachable(); >=20 > In the front before the other ifs, we get the code we are expecting. >=20 > conv2 has a similar issue too, though it has also a different issue of > ordering for the comparisons. its because the unreachable is after the branches, and we have multiple use= s of SR.4_4 before the unreachable. [local count: 1073741824]: SR.4_4 =3D s._M_value; if (SR.4_4 =3D=3D -1) goto ; [50.00%] else goto ; [50.00%] [local count: 536870913]: if (SR.4_4 =3D=3D 0) goto ; [50.00%] else goto ; [50.00%] [local count: 268435456]: if (SR.4_4 =3D=3D 1) goto ; [100.00%] else goto ; [0.00%] [count: 0]: __builtin_unreachable (); [local count: 1073741824]: # _1 =3D PHI <-1(2), 0(3), 1(4)> We know when we get to bb5 that SR.4_4 is [-1, 1] for sure. But we dont know that before we reach that spot. if there was a call to=20 foo(SR.4_4) in bb 3 for instance, we wouldn't be able to propagate [-1,1] to the call= to foo because it happens before we know for sure. and foo may go and do something if it has a value of 6 and exit the compilation, thus never returning. So we can only provide a range of [-1, 1] AFTER the unreachable, or if ther= e is only a single use of it.. the multiples uses are what tricks it. This has come up before. we need some sort of backwards propagation that c= an propagate discovered values earlier into the IL to a point where it is know= n to be safe (ie, it wouldnt be able to propagate it past a call to foo() for instance) In cases like this, we could discover it is safe to propagate that range ba= ck to the def point, and then we could set the global. Until we add some smarts, either to the builtin unreachable elimination cod= e, or elsewhere, which is aware of how to handle such side effects, we can't s= et the global because we dont know if it is safe at each use before the unreachable call.=