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

Reply via email to