Issue 178026
Summary [InstCombine] Consider preserving nuw flag when folding select to smax/smin
Labels new issue
Assignees
Reporter mikaseianatsu
    **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.
_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to