https://gcc.gnu.org/bugzilla/show_bug.cgi?id=121682
Bug ID: 121682
Summary: Optimization: If (x & y) == y then (x - y) == (x xor
y) == (x & ~y)
Product: gcc
Version: 15.1.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: tree-optimization
Assignee: unassigned at gcc dot gnu.org
Reporter: Explorer09 at gmail dot com
Target Milestone: ---
This is an optimization feature request.
For unsigned integers `x` and `y`, if it's checked in a conditional that `(x &
y) == y`, then the three expressions `(x - y)`, `(x xor y)` and `(x & ~y)`
should equal to each other. The compiler should be able to emit any of the
three forms in assembly, looking at which takes the least clock cycles or which
is the smallest in code size.
In GCC, such an optimization is performed on ARM64 target, but not on x86-64,
32-bit ARM, or RISC-V targets according to my testing.
Test code (the three functions should produce identical code if optimization is
on):
```c
#include <stdlib.h>
unsigned int test1(unsigned int x, unsigned int y) {
if ((x & y) == y)
return x - y;
abort();
}
unsigned int test2(unsigned int x, unsigned int y) {
if ((x & y) == y)
return x ^ y;
abort();
}
unsigned int test3(unsigned int x, unsigned int y) {
if ((x & y) == y)
return x & ~y;
abort();
}
```
I've reported the same issue (feature request) in Clang:
https://github.com/llvm/llvm-project/issues/155187
Note that Clang can optimize the condition `(x & y) == y` to `(~x & y) == 0`.
GCC cannot yet (at least not perfectly), which is a separate issue to be
reported.