-
Notifications
You must be signed in to change notification settings - Fork 13.5k
llvm.minnum should be lowered to fminimum_numf instead of fminf #93033
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Glibc introduce |
Did the glibc behavior also change for fmin/fmax? I remember testing this long ago. LLVM doesn't pretend to handling signaling nans correctly for non-strictfp functions. We also should rename the minnum/maxnum intrinsics; the name was always wrong. We should instead have something like minnum2019, minnum2008, and fmin for the range of behaviors |
Ohh, yes, it does.
I guess that we should fellow the naming scheme with IEEE754, if we'd like to support the same behavior of IEEE. If we try to support our flavor operations, I think that we should use a quite different naming scheme, such as |
Ohh, maybe we should update the documents of
I guess this claims existed due to that the |
fminimum and fmaximum are new and separate operations. They are not a change to the behavior of fmin/fmax. Do you have a reference to a change in the fmin implementation, specifically?
It's not dropped, it's now called minimumNumber which coexists with minimum. It is stronger than the 2008 definition since it definitively orders -0 as less than +0 |
It's in the diff of manual/arith.texi. |
https://godbolt.org/z/z7WG3q3Gq glibc does seem to be following the IEEE sNaN behavior. On MacOS, it does not and treats the snan the same as nan. |
So, my proposal is to emit fminimum_numf if we are using -std=gnu23/c23. |
In the documentation of IEEE754-2019, there is:
And there is no other talking about |
If you actually look at 9.6, it has this: So mostly this is a question of wrangling the behavior of different implementations. The LangRef and some of the lowerings will need to change. The LangRef behavior as written matches the behavior on macOS. The apparent glibc behavior on x86 matches the IEEE sNaN handling. So some combination of the lowering and the LangRef will need to change. The AArch64 ISA documentation isn't enlightening me on the instruction behavior there. Additionally, OpenCL says "fmin and fmax behave as defined by C99 and may not match the IEEE 754-2008 definition for minNum and maxNum with regard to signaling NaNs. Specifically, signaling NaNs may behave as quiet NaNs." I would be happy if we could get the minnum behavior to match the IEEE 2019 behavior, matching the sNaN behavior and also strengthening the signed 0 assumption. The outlier lowerings would then have to adjust |
Maybe we can define a group of new intrinsics, and keep My suggestion is:
|
Was there an actual change here, or just clarification? I still don't see the diff that says the behavior changed. I think this was always the implemented behavior in glibc. I'd prefer to just fix minnum to match IEEE and then if necessary at fmin for the ignore-snan case? Or we can just fix the lowering for macOS
We already have this |
I'd prefer it too.
|
The normative text hasn't changed, but the example code for To clear up potential confusion here: there are several variants of minimum, based on NaN-behavior and -0/+0 comparisons.
Note that all three operations have distinct behavior, although We don't have an llvm intrinsic for |
Er, sorry, |
So yes, when the intrinsics were added (and later then clarified to have the libm sNaN behavior), glibc had the wrong behavior. I guess that means we really should just make minnum match the IEEE behavior and add something new for the old The OpenCL footnote also wasn't here last I looked, haven't bothered to track down where that appeared. |
Currently, on different platform, the behaivor of llvm.minnum is different if one operand is sNaN. When we compute sNaN vs NUM ARM/AArch64 follow the IEEE754-2008's minNUM: return qNaN. LIBCALL: returns qNaN. RV/X86/Hexagon follow the IEEE754-2019's minimumNumber: return NUM. MIPS/LoongArch/Generic: return NUM. So, let's introduce `llvm.minmumnum/llvm.maximumnum`, which always follow IEEE754-2019's minimumNumber/maximumNumber. Since `llvm.minnum` shares the same name with IEEE754-2008's minNUM, and currently, it is used for fmin(3), we should ask all ports to switch the behavior to minNUM. Fixes: llvm#93033
Currently, on different platform, the behaivor of llvm.minnum is different if one operand is sNaN: When we compute sNaN vs NUM: ARM/AArch64/PowerPC: follow the IEEE754-2008's minNUM: return qNaN. RISC-V/X86/Hexagon follow the IEEE754-2019's minimumNumber: return NUM. MIPS/LoongArch/Generic: return NUM. LIBCALL: returns qNaN. So, let's introduce llvm.minmumnum/llvm.maximumnum, which always follow IEEE754-2019's minimumNumber/maximumNumber. Half-fix: llvm#93033
Currently, on different platform, the behaivor of llvm.minnum is different if one operand is sNaN: When we compare sNaN vs NUM: ARM/AArch64/PowerPC: follow the IEEE754-2008's minNUM: return qNaN. RISC-V/Hexagon follow the IEEE754-2019's minimumNumber: return NUM. X86: Returns NUM but not same with IEEE754-2019's minimumNumber as +0.0 is not always greater than -0.0. MIPS/LoongArch/Generic: return NUM. LIBCALL: returns qNaN. So, let's introduce llvm.minmumnum/llvm.maximumnum, which always follow IEEE754-2019's minimumNumber/maximumNumber. Half-fix: llvm#93033
Currently, on different platform, the behaivor of llvm.minnum is different if one operand is sNaN: When we compare sNaN vs NUM: ARM/AArch64/PowerPC: follow the IEEE754-2008's minNUM: return qNaN. RISC-V/Hexagon follow the IEEE754-2019's minimumNumber: return NUM. X86: Returns NUM but not same with IEEE754-2019's minimumNumber as +0.0 is not always greater than -0.0. MIPS/LoongArch/Generic: return NUM. LIBCALL: returns qNaN. So, let's introduce llvm.minmumnum/llvm.maximumnum, which always follow IEEE754-2019's minimumNumber/maximumNumber. Half-fix: llvm#93033
Currently, on different platform, the behaivor of llvm.minnum is different if one operand is sNaN: When we compare sNaN vs NUM: ARM/AArch64/PowerPC: follow the IEEE754-2008's minNUM: return qNaN. RISC-V/Hexagon follow the IEEE754-2019's minimumNumber: return NUM. X86: Returns NUM but not same with IEEE754-2019's minimumNumber as +0.0 is not always greater than -0.0. MIPS/LoongArch/Generic: return NUM. LIBCALL: returns qNaN. So, let's introduce llvm.minmumnum/llvm.maximumnum, which always follow IEEE754-2019's minimumNumber/maximumNumber. Half-fix: llvm#93033
Currently, on different platform, the behaivor of llvm.minnum is different if one operand is sNaN: When we compare sNaN vs NUM: ARM/AArch64/PowerPC: follow the IEEE754-2008's minNUM: return qNaN. RISC-V/Hexagon follow the IEEE754-2019's minimumNumber: return NUM. X86: Returns NUM but not same with IEEE754-2019's minimumNumber as +0.0 is not always greater than -0.0. MIPS/LoongArch/Generic: return NUM. LIBCALL: returns qNaN. So, let's introduce llvm.minmumnum/llvm.maximumnum, which always follow IEEE754-2019's minimumNumber/maximumNumber. Half-fix: llvm#93033
Currently, on different platform, the behaivor of llvm.minnum is different if one operand is sNaN: When we compare sNaN vs NUM: ARM/AArch64/PowerPC: follow the IEEE754-2008's minNUM: return qNaN. RISC-V/Hexagon follow the IEEE754-2019's minimumNumber: return NUM. X86: Returns NUM but not same with IEEE754-2019's minimumNumber as +0.0 is not always greater than -0.0. MIPS/LoongArch/Generic: return NUM. LIBCALL: returns qNaN. So, let's introduce llvm.minmumnum/llvm.maximumnum, which always follow IEEE754-2019's minimumNumber/maximumNumber. Half-fix: llvm#93033
Currently, on different platform, the behaivor of llvm.minnum is different if one operand is sNaN: When we compare sNaN vs NUM: ARM/AArch64/PowerPC: follow the IEEE754-2008's minNUM: return qNaN. RISC-V/Hexagon follow the IEEE754-2019's minimumNumber: return NUM. X86: Returns NUM but not same with IEEE754-2019's minimumNumber as +0.0 is not always greater than -0.0. MIPS/LoongArch/Generic: return NUM. LIBCALL: returns qNaN. So, let's introduce llvm.minmumnum/llvm.maximumnum, which always follow IEEE754-2019's minimumNumber/maximumNumber. Half-fix: #93033
We just introduce llvm.minimumnum and llvm.maximumnum intrinsics support to llvm. Let's support them in Clang. See: llvm#93033
Introducing a new intrinsic doesn't solve the current intrinsic behavior being broken |
Sure. I add minimum_num first due to that some arch has minimumNumber hardware instructions. And I am working on change the fminf ones now, and I will submit a new PR. |
Currently, on different platform, the behaivor of llvm.minnum is different if one operand is sNaN: When we compare sNaN vs NUM: ARM/AArch64/PowerPC: follow the IEEE754-2008's minNUM: return qNaN. RISC-V/Hexagon follow the IEEE754-2019's minimumNumber: return NUM. X86: Returns NUM but not same with IEEE754-2019's minimumNumber as +0.0 is not always greater than -0.0. MIPS/LoongArch/Generic: return NUM. LIBCALL: returns qNaN. So, let's introduce llvm.minmumnum/llvm.maximumnum, which always follow IEEE754-2019's minimumNumber/maximumNumber. Half-fix: llvm#93033
We just introduce llvm.minimumnum and llvm.maximumnum intrinsics support to llvm. Let's support them in Clang. See: llvm#93033
Currently, on different platform, the behaivor of llvm.minnum is different if one operand is sNaN: When we compare sNaN vs NUM: ARM/AArch64/PowerPC: follow the IEEE754-2008's minNUM: return qNaN. RISC-V/Hexagon follow the IEEE754-2019's minimumNumber: return NUM. X86: Returns NUM but not same with IEEE754-2019's minimumNumber as +0.0 is not always greater than -0.0. MIPS/LoongArch/Generic: return NUM. LIBCALL: returns qNaN. So, let's introduce llvm.minmumnum/llvm.maximumnum, which always follow IEEE754-2019's minimumNumber/maximumNumber. Half-fix: llvm#93033
We just introduce llvm.minimumnum and llvm.maximumnum intrinsics support to llvm. Let's support them in Clang. See: llvm#93033
We just introduce llvm.minimumnum and llvm.maximumnum intrinsics support to llvm. Let's support them in Clang. See: llvm#93033
We just introduce llvm.minimumnum and llvm.maximumnum intrinsics support to llvm. Let's support them in Clang. See: #93033
We just introduce llvm.minimumnum and llvm.maximumnum intrinsics support to llvm. Let's support them in Clang. See: llvm#93033
It has been fixed. |
In https://llvm.org/docs/LangRef.html#llvm-minnum-intrinsic
While in https://www.gnu.org/software/libc/manual/html_node/Misc-FP-Arithmetic.html
The text was updated successfully, but these errors were encountered: