llvm / llvm/llvm-project

[InstCombine] Consider preserving nuw flag when folding select to smax/smin

Open
#178,026 1 comment 0 reactions 0 assignees View on GitHub
llvm:instcombine missed-optimization
Dominant language
LLVM
Stars
40.5k
Forks
18.7k
PR merge metrics
PR metrics pending

Description

**Relation to PR #118932**

This behavior appears to be a consequence of the transformation introduced in **PR #118932: \*“[InstCombine] Widen Sel width after Cmp to generate Max/Min intrinsics”\***.

That PR rewrites patterns of the form:

```
bN = ext bK
cond = cmp aN, bN
aK = trunc aN
retK = select cond, aK, bK
```

into:

```
bN = ext bK
cond = cmp aN, bN
retN = select cond, aN, bN
retK = trunc retN
```

in order to enable folding into `llvm.smax/llvm.smin`.

This rewrite is semantically correct and was validated via Alive2 in the PR discussion. However, the transformation does not currently attempt to **preserve or re-derive flags** (such as `nuw`) on the newly introduced `trunc`, even when they are provably implied by the source IR.

**Example:**

```
src
define i16 @src(i16 %a, i32 %max) {
%a32 = zext i16 %a to i32
%cmp = icmp sgt i32 %max, %a32
%max8 = trunc nuw i32 %max to i16
%sel = select i1 %cmp, i16 %max8, i16 %a
ret i16 %sel
}
```

tgt1

```
define i16 @tgt(i16 %a, i32 %max) {
%a32 = zext i16 %a to i32
%sel1 = call i32 @llvm.smax.i32(i32 %max, i32 %a32)
%sel = trunc i32 %sel1 to i16
ret i16 %sel
}
```

tgt2

```
define i16 @tgt(i16 %a, i32 %max) {
%a32 = zext i16 %a to i32
%sel1 = call i32 @llvm.smax.i32(i32 %max, i32 %a32)
%sel = trunc nuw i32 %sel1 to i16
ret i16 %sel
}
```

The source IR is currently optimized to the target1, but not to the target2.

This issue is not a correctness bug, but a missed optimization for flag preservation introduced by the widening-and-folding transformation in PR #118932.

Contributor guide

Open the contributing guide

Research direction

Start by locating the InstCombine widening-and-folding transformation described in PR #118932 and its existing regression coverage. Compare the provided target1 and target2 IR, then run the relevant InstCombine tests. Done means the transformation preserves or re-derives the nuw flag when it is provably valid.

Written by the indexing model from the issue text.

Assessment

Domain
compilers
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.