[InstCombine] Narrow masked integer comparisons to the mask's active bit width
- 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
Assessment
This issue has not been assessed yet.