llvm / llvm/llvm-project

[InstCombine] Narrow masked integer comparisons to the mask's active bit width

Open
#216,443 4 comments 0 reactions 1 assignee Claimed by @rohan11235813 View on GitHub
llvm:instcombine missed-optimization
Dominant language
LLVM
Stars
40.5k
Forks
18.7k
PR merge metrics
PR metrics pending

Description

InstCombine appears to miss opportunities to narrow masked integer equality comparisons to the minimum integer width required by the mask.

https://alive2.llvm.org/ce/z/SiCL-q

A slightly wider example is:

https://alive2.llvm.org/ce/z/ADPj3u

The general form seems to be roughly:

```text
icmp eq/ne (and X, (1 << N) - 1), C
=>
icmp eq/ne (trunc X to iN), trunc(C)
```

when the constant/mask conditions make the narrowing valid.

This is distinct from the existing `icmp ne X, 0 -> trunc X to i1` optimization for values known to be in `{0,1}`. Here the comparison itself remains, but its operands are narrowed.

I encountered this as a recurring missed optimization while searching equivalent LLVM IR forms. In one minimized example:

```llvm
define i1 @source(i32 %x) {
%m = and i32 %x, 1
%r = icmp eq i32 %m, 0
ret i1 %r
}
```

normal InstCombine, `default`, and `default` retain the wide masked comparison, while the narrowed form remains valid and has the same number of optimized IR instructions.

Using the fixed Skylake LLVM TTI model in my experiment, the optimized cost changes from:

```text
source: 2
candidate: 1
```

This particular result should be viewed as a cost-model improvement rather than a measured runtime/codegen claim.

Assisted by gpt-5.6-sol

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.