llvm / llvm/llvm-project

[InstCombine] Missed scmp fold with an offset-form range

Open
#221,129 1 comment 0 reactions 0 assignees View on GitHub
llvm:optimizations missed-optimization
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.