From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 48) id AF8AB3858D39; Mon, 24 Jan 2022 16:12:48 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org AF8AB3858D39 From: "jakub at gcc dot gnu.org" To: gcc-bugs@gcc.gnu.org Subject: [Bug tree-optimization/104196] [12 Regression] wrong code at -O2 and above on x86_64-linux-gnu Date: Mon, 24 Jan 2022 16:12:48 +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: 12.0 X-Bugzilla-Keywords: wrong-code X-Bugzilla-Severity: normal X-Bugzilla-Who: jakub at gcc dot gnu.org X-Bugzilla-Status: NEW X-Bugzilla-Resolution: X-Bugzilla-Priority: P1 X-Bugzilla-Assigned-To: unassigned at gcc dot gnu.org X-Bugzilla-Target-Milestone: 12.0 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 X-BeenThere: gcc-bugs@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-bugs mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 24 Jan 2022 16:12:48 -0000 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=3D104196 --- Comment #8 from Jakub Jelinek --- So, to me this doesn't look like a recent reassoc1 regression, but rather something that been there since ~ r0-119920-gd578e863b08e64789f767c95f85acd10dc477bdf The inter-bb range optimization pass uses no_side_effect_bb as a test for t= he bbs in between, which makes sure that no statements have side-effects, there are only gimple assignments except for the last GIMPLE_COND and those statements can't trap and their lhs is consumed within the same bb. if (a.1_1 >=3D 0) goto ; [59.00%] else goto ; [41.00%] [local count: 440234144]: _3 =3D -2147483647 - a.1_1; _9 =3D a.1_1 !=3D -2147479551; _4 =3D _3 =3D=3D 1; _8 =3D _4 | _9; if (_8 !=3D 0) goto ; [34.51%] else goto ; [65.49%] is then treated as if ((a.1_1 >=3D 0) | (-2147483647 - a.1_1 =3D=3D 1) | (a= .1_1 !=3D -2147479551)) goto bb5; else goto bb3; and in there we optimize from there the (a.1_1 >=3D 0) | (a.1_1 !=3D -21474= 79551) part of it into (a.1_1 !=3D -2147479551). That is all fine, but we have ch= osen to put the merged condition into the place of the old _9 test and make the the a.1_1 >=3D 0 test (which has been replaced by false). Usually that doe= sn't really matter where we stick it, when merging multiple "ops" into one, one simply wins (that is the range in update_range_test) and the other(s) are marked as true/false (otherrange ... otherrange + count - 1). The problem above is that the _3 =3D -2147483647 - a.1_1; stmt is done in undefined overflow type and thus can trigger UB where there wasn't one befo= re for certain values. One possibility to fix this would be to punt on statements like that in no_side_effect_bb (e.g. the normal way to encode a range is using unsigned arithmetics). But I'd be afraid we could easily regress on what the optimization can handle. Another possibility is try to be smarter in update_range_test. Instead of always picking range->idx as the winner and otherrange*->idx as the stmts replaced by false or true, perhaps we should try to be smarter, go through = them all first and pick the one from the first bb (one dominating all the other = ops) and if the merge is successful, swap range->idx with the most dominating otherrange->idx. So, instead of the problematic [local count: 118111598]: [local count: 1073741824]: a.1_1 =3D a; _3 =3D -2147483647 - a.1_1; _10 =3D a.1_1 !=3D -2147479551; _9 =3D a.1_1 !=3D -2147479551; _4 =3D _3 =3D=3D 1; _2 =3D _4 | _10; if (_2 !=3D 0) goto ; [34.51%] else goto ; [65.49%] we'd get a.1_1 =3D a; if (a.1_1 !=3D -2147479551) goto ; [59.00%] else goto ; [41.00%] [local count: 440234144]: _3 =3D -2147483647 - a.1_1; _9 =3D 0; _4 =3D _3 =3D=3D 1; _8 =3D _4 | _9; if (_8 !=3D 0) goto ; [34.51%] else goto ; [65.49%] Another question but that is GCC 13 material is why we don't optimize int foo (int x) { return -2147483647 - x <=3D 0; } into: return x >=3D -2147483647 during GIMPLE (we optimize it during expansion it seems).=