[InstCombine] Missed scmp fold with an offset-form range
- Dominant language
- LLVM
- Stars
- 40.5k
- Forks
- 18.7k
- PR merge metrics
- PR metrics pending
Description
`llvm.scmp(x, 0)` returns `-1`, `0`, or `1` according to the sign of `x`. If `x` is known to be one of `-1`, `0`, and `1`, the result is `x` itself, adjusted only to the result width by truncation or sign extension.
For the following LLVM IR:
```llvm
define i64 @src(i32 %x) {
entry:
%offset = add i32 %x, 1
%range = icmp ult i32 %offset, 3
call void @llvm.assume(i1 %range)
%r = call i64 @llvm.scmp.i64.i32(i32 %x, i32 0)
ret i64 %r
}
```
On current LLVM trunk, `opt -O3` keeps the intrinsic call (Godbolt: https://godbolt.org/z/1jThj6he3):
```llvm
define i64 @src(i32 %x) {
entry:
%offset = add i32 %x, 1
%range = icmp ult i32 %offset, 3
call void @llvm.assume(i1 %range)
%r = call i64 @llvm.scmp.i64.i32(i32 %x, i32 0)
ret i64 %r
}
```
The condition `(x + 1)
Contributor guide
Research direction
Start with the InstCombine scmp(x, 0) combine and its computeConstantRange() call using SQ.getWithInstruction(II). Reproduce the offset-form example with opt -O3, then verify that the contextual range is translated back to %x and the result becomes a sign extension, while preserving the existing direct range behavior.
Written by the indexing model from the issue text.
Assessment
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 55/100