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

            Bug ID: 122385
           Summary: (x == 0 || y == 0) can optimize to (x * y == 0) for
                    small integers in -Oz mode
           Product: gcc
           Version: 15.1.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: target
          Assignee: unassigned at gcc dot gnu.org
          Reporter: Explorer09 at gmail dot com
  Target Milestone: ---

This is an optimization feature request.

If the integers a and b are so small that (a * b) (the multiplication) cannot
overflow, then (a == 0 || b == 0) can convert to (a * b == 0) for smaller code
size.

Because it's significantly slower to use multiplication in place of logical
checks, I expect this optimization be performed only in -Oz mode.

Architectures that I know can benefit from this optimization include: x86-64
and RISCV64.

```c
#include <stdbool.h>
#include <stdint.h>

bool func1(uint8_t a, uint8_t b, uint8_t c, uint8_t d) {
    return a == 0 || b == 0 || c == 0 || d == 0;
}

bool func2(uint8_t a, uint8_t b, uint8_t c, uint8_t d) {
    if (a == 0)
        return true;
    if (b == 0)
        return true;
    if (c == 0)
        return true;
    return d == 0;
}

bool func3(uint8_t a, uint8_t b, uint8_t c, uint8_t d) {
    return ((uint32_t)a * b * c * d) == 0;
}
```

https://godbolt.org/z/sWYK89W1W

(This feature request was originally reported in Clang, but I think GCC could
also implement this feature.)

Reply via email to