Suboptimal code for comparisons between variables extended to 128 bits
- Dominant language
- LLVM
- Stars
- 40.5k
- Forks
- 18.7k
- PR merge metrics
- PR metrics pending
Description
https://godbolt.org/z/4WEbeWP6n
https://alive2.llvm.org/ce/z/4Stvke
```rust
#[unsafe(no_mangle)]
pub fn src1(x: i32, y: u64) -> bool {
i128::from(x) < i128::from(y)
}
#[unsafe(no_mangle)]
pub fn tgt1(x: i32, y: u64) -> bool {
(y.cast_signed() < 0) || i64::from(x) < y.cast_signed()
}
#[unsafe(no_mangle)]
pub fn src2(x: i16, y: u32) -> bool {
i128::from(x) < i128::from(y)
}
#[unsafe(no_mangle)]
pub fn tgt2(x: i16, y: u32) -> bool {
i64::from(x) < i64::from(y)
}
#[unsafe(no_mangle)]
pub fn src3(x: i8, y: u16) -> bool {
i128::from(x) < i128::from(y)
}
#[unsafe(no_mangle)]
pub fn tgt3(x: i8, y: u16) -> bool {
i32::from(x) < i32::from(y)
}
#[unsafe(no_mangle)]
pub fn src4(x: i8, y: u8) -> bool {
i128::from(x) < i128::from(y)
}
#[unsafe(no_mangle)]
pub fn tgt4(x: i8, y: u8) -> bool {
i32::from(x) < i32::from(y)
}
```
# Assembly (AArch64)
```asm
src1:
sxtw x8, w0
asr x9, x8, #63
cmp x8, x1
sbcs xzr, x9, xzr
cset w0, lt
ret
src2:
sxth x8, w0
asr x9, x8, #63
cmp x8, w1, uxtw
sbcs xzr, x9, xzr
cset w0, lt
ret
src3:
sxtb x8, w0
asr x9, x8, #63
cmp x8, w1, uxth
sbcs xzr, x9, xzr
cset w0, lt
ret
src4:
sxtb x8, w0
asr x9, x8, #63
cmp x8, w1, uxtb
sbcs xzr, x9, xzr
cset w0, lt
ret
tgt1:
sxtw x8, w0
cmp x1, #0
ccmp x1, x8, #0, pl
cset w0, gt
ret
tgt2:
mov w8, w1
cmp x8, w0, sxth
cset w0, gt
ret
tgt3:
sxtb w8, w0
cmp w8, w1, uxth
cset w0, lt
ret
tgt4:
sxtb w8, w0
cmp w8, w1, uxtb
cset w0, lt
ret
```
# Assembly (x86_64)
```asm
src1:
movsxd rax, edi
mov rcx, rax
sar rcx, 63
cmp rax, rsi
sbb rcx, 0
setl al
ret
src2:
movsx rax, di
mov rcx, rax
sar rcx, 63
mov edx, esi
cmp rax, rdx
sbb rcx, 0
setl al
ret
src3:
movsx rax, dil
mov rcx, rax
sar rcx, 63
movzx edx, si
cmp rax, rdx
sbb rcx, 0
setl al
ret
src4:
movsx rax, dil
mov rcx, rax
sar rcx, 63
movzx edx, sil
cmp rax, rdx
sbb rcx, 0
setl al
ret
tgt1:
test rsi, rsi
sets cl
movsxd rax, edi
cmp rsi, rax
setg al
or al, cl
ret
tgt2:
movsx rax, di
mov ecx, esi
cmp rax, rcx
setl al
ret
tgt3:
movsx eax, dil
movzx ecx, si
cmp eax, ecx
setl al
ret
tgt4:
movsx eax, dil
movzx ecx, sil
cmp eax, ecx
setl al
ret
```
Contributor guide
Research direction
Start with the Rust functions in the issue and reproduce the AArch64 and x86_64 output using the linked Godbolt example; use the linked Alive2 proof to confirm the proposed comparisons are equivalent. Trace which LLVM optimization stage handles these widened integer comparisons and compare generated assembly before and after. Done means the valid cases avoid unnecessary 128-bit comparison sequences on the affected targets.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- compilers, performance
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100