llvm / llvm/llvm-project

Compare against signed minimum/signed maximum by checking for overflow

Open
#159,578 5 comments 0 reactions 0 assignees View on GitHub
backend:AArch64 backend:X86 missed-optimization
Dominant language
LLVM
Stars
40.5k
Forks
18.7k
PR merge metrics
PR metrics pending

Description

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

template
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::max(); }
auto tgt1(int x) { return add_with_overflow(x, 1); }

auto src2(int x) { return x == std::numeric_limits::min(); }
auto tgt2(int x) { return add_with_overflow(x, -1); }

auto src3(long x) { return x == std::numeric_limits::max(); }
auto tgt3(long x) { return add_with_overflow(x, 1); }

auto src4(long x) { return x == std::numeric_limits::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
```

Contributor guide

Open the contributing guide

Research direction

Start with the Godbolt example and the signed-bound comparisons described in the issue, then locate the LLVM compiler entry point that handles these comparisons for AArch64 and x86_64. Compare generated assembly before and after; done means preserving the minimum and maximum checks while using overflow checks where beneficial, with regression coverage for both targets.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
compilers, performance
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.