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.

Reply via email to