| Issue |
171884
|
| Summary |
[aarch64] [missed-opt] Irrelevant subtraction pessimizes llvm.uadd/usub.with.overflow
|
| Labels |
new issue
|
| Assignees |
|
| Reporter |
purplesyringa
|
[Godbolt](https://godbolt.org/z/948EWPoqM)
```cpp
#include <stdint.h>
uint64_t f(uint64_t x, uint64_t y) {
uint64_t sum;
if (__builtin_uaddl_overflow(x, y, &sum)) {
return sum - 100;
} else {
return 0;
}
}
uint64_t g(uint64_t x, uint64_t y) {
uint64_t sum;
if (__builtin_uaddl_overflow(x, y, &sum)) {
return sum - 100;
} else {
return sum;
}
}
```
```asm
f(unsigned long, unsigned long):
adds x8, x0, x1
sub x8, x8, #100
cmn x0, x1
csel x0, x8, xzr, hs
ret
g(unsigned long, unsigned long):
adds x8, x0, x1
sub x8, x8, #100
adds x9, x0, x1
csel x0, x8, x9, hs
ret
```
In `f`, note `adds` computing the sum and having its output flag is ignored and recomputed with `cmn`. In `g`, note `adds` being run twice.
This problem affects `__builtin_uaddl_overflow` and `__builtin_usubl_overflow` equally.
Replacing `- 100` with `+ 100` miraculously fixes the lowering, but obviously changes semantics.
_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs