| Issue |
164501
|
| Summary |
`(x == 0 || y == 0)` can fold to `(x * y == 0)` for small integers in `-Oz` mode
|
| Labels |
new issue
|
| Assignees |
|
| Reporter |
Explorer09
|
This is an optimization feature request. (And a follow-up of #160612)
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.
Note that Clang is already able to transform `(a * b == 0)` into `(a == 0 || b == 0)` if the result never overflows. This request is about the doing the opposite transformation for an aggressive code size reduction.
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;
}
```
[Compiler Explorer link](https://godbolt.org/z/43Y37cqGc)
```assembly
func2:
testl %edi, %edi
sete %al
testl %esi, %esi
sete %sil
orb %al, %sil
testl %edx, %edx
sete %dl
testl %ecx, %ecx
sete %al
orb %dl, %al
orb %sil, %al
retq
func3:
imull %esi, %edi
imull %ecx, %edx
imull %edi, %edx
testl %edx, %edx
sete %al
retq
```
_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs