[InstCombine] Incorrect clamp optimization propagates poison from `ninf` comparison
- 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
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