Known not-NaN or not-inf should get the same optimizations as `nnan`/`ninf` (missed `minimumnum` optimizations)
- Dominant language
- LLVM
- Stars
- 40.5k
- Forks
- 18.7k
- PR merge metrics
- PR metrics pending
Description
Code:
```llvm
define noundef double @minimumnum_nsz_assume_nann(double noundef %x, double noundef %y) unnamed_addr {
start:
%_4 = fcmp ord double %x, 0.0
%_6 = fcmp ord double %y, 0.0
tail call void @llvm.assume(i1 %_4)
tail call void @llvm.assume(i1 %_6)
%0 = tail call nsz double @llvm.minimumnum.f64(double %x, double %y)
ret double %0
}
define noundef double @minimumnum_nsz_nann(double noundef %x, double noundef %y) unnamed_addr {
start:
%0 = tail call nsz nnan double @llvm.minimumnum.f64(double %x, double %y)
ret double %0
}
```
I would expect the two functions to get the same output because `minimumnum` in `minimumnum_nsz_nann` knows that `x` and `y` are YaN (via `nnan`) and in `minimumnum_nsz_assume_nann` it's known via the `assume`. However, on aarch64, they get different outputs:
```asm
minimumnum_nsz_assume_nann:
fminnm d1, d1, d1
fminnm d0, d0, d0
fminnm d0, d0, d1
ret
minimumnum_nsz_nann:
fminnm d0, d0, d1
ret
```
I noticed this missed optimization on aarch64 but expect that a more general optimization should help a number of targets and functions.
Link: https://llvm.godbolt.org/z/aeWWKW4ro
Contributor guide
Research direction
Start with the LLVM IR reproducer, focusing on the llvm.minimumnum intrinsic, llvm.assume, and the differing AArch64 output shown in the issue. Trace why equivalent known non-NaN facts are handled differently, and consider the general optimization path rather than only AArch64. Done means the reproducer receives equivalent optimized output and regression coverage verifies the 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
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 50/100