Bug 106570 - [12/13/14/15/16 Regression] DCE sometimes fails with depending if statements since r12-2305-g398572c1544d8b75
Summary: [12/13/14/15/16 Regression] DCE sometimes fails with depending if statements ...
Status: NEW
Alias: None
Product: gcc
Classification: Unclassified
Component: tree-optimization (show other bugs)
Version: 12.1.0
: P2 normal
Target Milestone: 12.5
Assignee: Not yet assigned to anyone
URL:
Keywords: missed-optimization
Depends on:
Blocks: VRP
  Show dependency treegraph
 
Reported: 2022-08-09 11:35 UTC by Thomas Mayerl
Modified: 2025-04-17 12:20 UTC (History)
6 users (show)

See Also:
Host:
Target:
Build:
Known to work: 11.1.0
Known to fail: 12.1.0
Last reconfirmed: 2025-01-27 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Thomas Mayerl 2022-08-09 11:35:38 UTC
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
Comment 1 Martin Liška 2022-08-09 13:15:43 UTC
Started with r12-2305-g398572c1544d8b75.
Comment 2 Andrew Macleod 2022-08-09 13:28:21 UTC
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.
Comment 3 Richard Biener 2022-08-19 08:27:17 UTC
GCC 12.2 is being released, retargeting bugs to GCC 12.3.
Comment 4 Andrew Pinski 2023-03-11 17:07:31 UTC
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.
Comment 5 Martin Liška 2023-03-14 13:16:20 UTC
(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.
Comment 6 Richard Biener 2023-05-08 12:25:14 UTC
GCC 12.3 is being released, retargeting bugs to GCC 12.4.
Comment 7 Andrew Pinski 2023-07-13 18:38:23 UTC
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 ).
Comment 8 Richard Biener 2024-06-20 09:09:35 UTC
GCC 12.4 is being released, retargeting bugs to GCC 12.5.
Comment 9 Andrew Macleod 2025-01-28 15:28:56 UTC
(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.