Issue |
159578
|
Summary |
Compare against signed minimum/signed maximum by checking for overflow
|
Labels |
backend:AArch64,
backend:X86,
missed-optimization
|
Assignees |
|
Reporter |
Kmeakin
|
Instead of comparing against the constant, which may take more instructions (AArch64) or more bytes to encode (x86_64), add/subtract 1 and check for overflow:
https://godbolt.org/z/1scGEndG1
```c++
#include <limits>
template <typename T, typename V>
auto add_with_overflow(T x, V y) -> bool {
T sum;
return __builtin_add_overflow(x, y, &sum);
}
auto src1(int x) { return x == std::numeric_limits<int>::max(); }
auto tgt1(int x) { return add_with_overflow(x, 1); }
auto src2(int x) { return x == std::numeric_limits<int>::min(); }
auto tgt2(int x) { return add_with_overflow(x, -1); }
auto src3(long x) { return x == std::numeric_limits<long>::max(); }
auto tgt3(long x) { return add_with_overflow(x, 1); }
auto src4(long x) { return x == std::numeric_limits<long>::min(); }
auto tgt4(long x) { return add_with_overflow(x, -1); }
```
# Assembly (AArch64)
```asm
src1(int):
mov w1, 2147483647
cmp w0, w1
cset w0, eq
ret
tgt1(int):
cmn w0, 1
cset w0, vs
ret
src2(int):
mov w1, -2147483648
cmp w0, w1
cset w0, eq
ret
tgt2(int):
cmp w0, #1
cset w0, vs
ret
src3(long):
mov x1, 9223372036854775807
cmp x0, x1
cset w0, eq
ret
tgt3(long):
cmn x0, 1
cset w0, vs
ret
src4(long):
mov x1, -9223372036854775808
cmp x0, x1
cset w0, eq
ret
tgt4(long):
cmp x0, #1
cset w0, vs
ret
```
# Assembly (x86_64)
```asm
"src1(int)":
cmp edi, 2147483647
sete al
ret
"tgt1(int)":
add edi, 1
seto al
ret
"src2(int)":
cmp edi, -2147483648
sete al
ret
"tgt2(int)":
add edi, -1
seto al
ret
"src3(long)":
movabs rax, 9223372036854775807
cmp rdi, rax
sete al
ret
"tgt3(long)":
add rdi, 1
seto al
ret
"src4(long)":
movabs rax, -9223372036854775808
cmp rdi, rax
sete al
ret
"tgt4(long)":
add rdi, -1
seto al
ret
```
_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs