llvm / llvm/llvm-project

[InstCombine] Incorrect clamp optimization propagates poison from `ninf` comparison

Open
#198,440 1 comment 0 reactions 0 assignees View on GitHub
confirmed llvm:instcombine miscompilation
Dominant language
LLVM
Stars
40.5k
Forks
18.7k
PR merge metrics
PR metrics pending

Description

LLVM appears to miscompile this IR:

```llvm
define float @clamp_float_ordered_nonstrict_maxmin1(float %x) {
%cmp2 = fcmp nnan ninf olt float %x, 2.550000e+02
%min = select i1 %cmp2, float %x, float 2.550000e+02
%cmp1 = fcmp ole float %x, 1.000000e+00
%r = select nnan ninf i1 %cmp1, float 1.000000e+00, float %min
ret float %r
}
```
At`opt -O3`, it is optimized to:

```llvm
define float @clamp_float_ordered_nonstrict_maxmin1(float %x) {
%cmp2 = fcmp nnan ninf olt float %x, 2.550000e+02
%min = select i1 %cmp2, float %x, float 2.550000e+02
%.inv = fcmp oge float %min, 1.000000e+00
%r1 = select i1 %.inv, float %min, float 1.000000e+00
ret float %r1
}
```

The point is that the optimised op `%.inv` may lead to a `poison` result, then propagate to the return value, while the original will not.

Reproduce: https://alive2.llvm.org/ce/z/2uYLPY

Contributor guide

Open the contributing guide

Research direction

Start by reproducing the transformation with opt -O3 and the linked Alive2 example. Then trace the InstCombine handling of the fcmp/select clamp pattern and add a regression test covering the ninf comparison; done means the optimization no longer propagates poison and the test preserves the original behavior.

Written by the indexing model from the issue text.

Assessment

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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.