| 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