[Bug tree-optimization/126698] Fold ceil (X / 2^C) ==/!= 0 -> X ==/!= 0

"pinskia at gcc dot gnu.org via Gcc-bugs" <[email protected]>
Newsgroups gmane.comp.gcc.bugs
Message-ID <[email protected]/bugzilla/>
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=126698

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

           What    |Removed                     |Added
----------------------------------------------------------------------------
   Last reconfirmed|                            |2026-08-06
     Ever confirmed|0                           |1
             Status|UNCONFIRMED                 |NEW

--- Comment #1 from Drea Pinski <pinskia at gcc dot gnu.org> ---
The generic version is:
```
int f2 (unsigned x, unsigned t1)
{
    unsigned t = (x & ((1u<<t1) - 1)) != 0;
    return ((x >> t1) + t) == 0;
}
```

That is (x>>y + ((x&mask)!=0)) == 0
where mask is ((1u<<y) - 1) or rather the lower y bits.

The reason is when x is 0, then x&mask will be zero then x&mask will be 0 also.
And then x>>y will not overflow when adding 1 or 0. When y is 0 then it is just
`x == 0`. And (x>>y<<y)|((x&mask)!=0) is the same as x.

Note LLVM only handles the constant case. I don't see why we can't handle the
non-constant case.

Note it might be the case where LLVM actually turns (a+b) == 0 into a == 0 && b
== 0 and then optimizes that; I have not looked fully.

Because LLVM is able to optimize:
```
int f2 (unsigned x, unsigned t1)
{
    t1 = 4;
    unsigned t = (x & ((1u<<t1) - 1)) != 0;
    return (x >> t1) == 0 && t == 0;
}
```

But LLVM is not able to optimize:
```
int f2 (unsigned x, unsigned t1)
{
    t1 = 4;
    return ((x >> t1)|(x & ((1u<<t1) - 1))) == 0;
}
```
So I am not sure how LLVM optimizes it fully; maybe it is just matching the !=
case.
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.