Open
Description
LLVM's documentation for @llvm.minimumnum.f32
says "If both operands are NaNs (including sNaN), returns qNaN". However, on x86_64, it actually returns sNaN.
Specifically, with this test.c:
#include <stdio.h>
#include <string.h>
float f32_minnumber(float x, float y);
int main() {
float f = __builtin_nansf("");
float g = f32_minnumber(f, f);
float h = g + 0;
unsigned uf, ug, uh;
memcpy(&uf, &f, sizeof(f));
memcpy(&ug, &g, sizeof(f));
memcpy(&uh, &h, sizeof(f));
printf("%x\n%x\n%x\n", uf, ug, uh);
return 0;
}
and this minnumber.ll:
target triple = "x86_64-pc-linux-gnu"
define float @f32_minnumber(float %x, float %y) {
%t = call float @llvm.minimumnum.f32(float %x, float %y)
ret float %t
}
define double @f64_minnumber(double %x, double %y) {
%t = call double @llvm.minimumnum.f32(double %x, double %y)
ret double %t
}
define float @f32_maxnumber(float %x, float %y) {
%t = call float @llvm.maximumnum.f32(float %x, float %y)
ret float %t
}
define double @f64_maxnumber(double %x, double %y) {
%t = call double @llvm.maximumnum.f32(double %x, double %y)
ret double %t
}
Compiling for x86_64 gets this output:
$ clang test.c minnumber.ll
$ ./a.out
7fa00000
7fa00000
7fe00000
$
This shows that the operands of the f32.minimumnum
are sNaN and the result is incorrectly also sNaN.
IEEE 754-2019 says of its corresponding minimumNumber
operattion "If both operands are NaNs, a quiet NaN is returned".
I have not tested similar variants for f64, maximumnum, or other architectures.