https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115499

Andrew Pinski <pinskia at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |NEW
           Severity|normal                      |enhancement
     Ever confirmed|0                           |1
   Last reconfirmed|                            |2024-06-15

--- Comment #1 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
What happens is fold simplifies `(b || c)` into `!!b | !!c` too early. 

In fn1 jump threading and ifcombine (and phiopt) together provides:
  if (m.2_2 != 0)
    goto <bb 4>; [50.00%]
  else
    goto <bb 3>; [50.00%]

  <bb 3> [local count: 536870912]:
  _11 = _1 != 1;
  _12 = c_9(D) != 0;
  _6 = _11 & _12;
  goto <bb 5>; [100.00%]

  <bb 4> [local count: 536870912]:
  _3 = c_9(D) != 0;
  _13 = _1 != 1;
  _14 = _3 & _13;

  <bb 5> [local count: 1073741824]:
  # iftmp.0_5 = PHI <_14(4), _6(3)>
...

And then see that iftmp.0_5 is the same on both branches and removes the whole
branch.

In the other cases we have:
```
  _1 = (int) a_8(D);
  _2 = b_9(D) != 0;
  _3 = c_10(D) != 0;
  _4 = _2 | _3;
  _5 = (int) _4;
  _14 = _1 != _5;
  _15 = _3 & _14;
  _6 = (long long unsigned int) _15;
```
Or simplier: ((cast)((b != 0) | (c != 0)) != a) & (c != 0)

Or c & ((cast)(b | c) != a) which can be just folded into c & (1 != a).


So maybe something like:

(simplify
 (bit_and:c @0
  (cmp:c (convert (bit_ior:c @0 @1)) @2)
 (bit_and @0 (cmp { build_one_cst (TREE_TYPE (@2)); } @2)))


We also don't handle even simplier:
```
bool f(bool a, bool b, int d, int e)
{
  a = e != 0;
  return a & ((int)a != d);
}

bool f1(bool a, bool b, int d, int e)
{
  a = e != 0;
  return a & (1 != d);
}
```

Nor (clang/LLVM does not handle this one either):
```
bool f(bool a, bool b, int d, int e)
{
  return a & ((int)(a|b) != d);
}

bool f1(bool a, bool b, int d, int e)
{
  return a & (1 != d);
}
```

It can get even more complex if `(a|b)` is a much more complex expression.

Maybe this requires some pass to do this rather than a simple match and
simplify pattern.

Reply via email to