Sometimes, DCE fails when multiple if statements are used. For example, GCC detects that the following if statements always evaluate to false and thus removes the dead code: #include <stdio.h> #include <stdbool.h> void DCEMarker0_(); void f(bool s, bool c) { if (!c == !s) { if (s && !c) { DCEMarker0_(); } } } In the next snippet, the if statements are used to set a variable. This variable is then used in the next if statement. However, GCC now fails to detect and eliminate the dead code: #include <stdio.h> #include <stdbool.h> void DCEMarker0_(); void f(bool s, bool c) { int intermediate_result = 0; if (!c == !s) { if (s && !c) { intermediate_result = 1; } } if (((!c == !s) && (s && !c)) || intermediate_result) { DCEMarker0_(); } } This is actually a regression: It works fine until GCC 11.3. This can also be seen via the following Compiler Explorer link: https://godbolt.org/z/n9dKMfqsd
Started with r12-2305-g398572c1544d8b75.
I think this is a duplicate of PR106379 . At the VRP2 stage I see: <bb 2> [local count: 1073741824]: if (c_6(D) == s_7(D)) goto <bb 3>; [34.00%] else goto <bb 5>; [66.00%] <bb 3> [local count: 365072224]: _1 = ~c_6(D); _2 = _1 & s_7(D); if (_2 != 0) goto <bb 4>; [75.00%] else goto <bb 5>; [25.00%] <bb 4> [local count: 628138969]: DCEMarker0_ (); <bb 5> [local count: 1073741824]: return; Which is basically the identical sequence.. it just took longer to get to it :-) We aren't removing this yet with ranger as I need to get to integrate rangers relation oracle with the simplifier so that it will see that _2 = ~s_7 & s_7.
GCC 12.2 is being released, retargeting bugs to GCC 12.3.
Note on the trunk, now the first example fails at -O2 and not just -O3. It might be useful to do a bisect there too. The second example failed for -O2 for GCC 12 too.
(In reply to Andrew Pinski from comment #4) > Note on the trunk, now the first example fails at -O2 and not just -O3. It > might be useful to do a bisect there too. That started with r13-3596-ge7310e24b1c0ca67.
GCC 12.3 is being released, retargeting bugs to GCC 12.4.
I suspect if we optimize: _1 = ~c_6(D); _2 = _1 & s_7(D); to: c < s; VRP will just work now. (that would be PR 107880 ).
GCC 12.4 is being released, retargeting bugs to GCC 12.5.
(In reply to Andrew Macleod from comment #2) > I think this is a duplicate of PR106379 . At the VRP2 stage I see: > > <bb 2> [local count: 1073741824]: > if (c_6(D) == s_7(D)) > goto <bb 3>; [34.00%] > else > goto <bb 5>; [66.00%] > > <bb 3> [local count: 365072224]: > _1 = ~c_6(D); > _2 = _1 & s_7(D); > if (_2 != 0) > goto <bb 4>; [75.00%] > else > goto <bb 5>; [25.00%] > > <bb 4> [local count: 628138969]: > DCEMarker0_ (); > > <bb 5> [local count: 1073741824]: > return; > > Which is basically the identical sequence.. it just took longer to get to it > :-) We aren't removing this yet with ranger as I need to get to integrate > rangers relation oracle with the simplifier so that it will see that _2 = > ~s_7 & s_7. Indeed. Even in EVRP at -O2 I see: c_14(D) [irange] _Bool VARYING s_15(D) [irange] _Bool VARYING Equivalence set : [c_14(D), s_15(D)] <bb 3> : _4 = ~c_14(D); _5 = _4 & s_15(D); if (_5 != 0) goto <bb 6>; [INV] else goto <bb 4>; [INV] so when evaluating _4 & s_15(D), we know c_14 and s_15 are in an equivalence set, so a relation query from simplification would indicate VREL_EQUAL, and _5 could be recognized as (~A & A) set to 0 and everything goes away.