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.