[llvm] LangRef: Clarify llvm.minnum and llvm.maxnum about sNaN (PR #112852)
YunQiang Su via llvm-commits
llvm-commits at lists.llvm.org
Wed Oct 30 04:29:21 PDT 2024
https://github.com/wzssyqa updated https://github.com/llvm/llvm-project/pull/112852
>From 508c33a9673ab129395e53cfa21b179c86ff3dae Mon Sep 17 00:00:00 2001
From: YunQiang Su <yunqiang at isrc.iscas.ac.cn>
Date: Fri, 18 Oct 2024 16:16:43 +0800
Subject: [PATCH 1/7] LangRef: Clarify llvm.minnum and llvm.maxnum about sNaN
The documents claims that it ignores sNaN, while in the code it may
be different.
- as the finally callback, it use libc call fmin(3)/fmax(3).
while C23 clarify that fmin(3)/fmax(3) should return NaN for sNaN vs NUM.
- on some architectures, such as aarch64, it converts to `fmaxnm`,
which returns qNaN for sNaN vs NUM.
- on RISC-V (SPEC 2019+), it converts to `fmax`, which returns NUM
for sNaN vs NUM.
Since we have introduced llvm.minimumnum and llvm.maximumnum, which
follow IEEE 754-2019's minimumNumber/maximumNumber.
So, it's time for use to clarify llvm.minnum and llvm.maxnum.
Let's define it to the libc's defination.
---
llvm/docs/LangRef.rst | 75 ++++++++++++++++++-------------------------
1 file changed, 31 insertions(+), 44 deletions(-)
diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst
index b83675c6ed97aa..2df01362a27ec6 100644
--- a/llvm/docs/LangRef.rst
+++ b/llvm/docs/LangRef.rst
@@ -16464,21 +16464,13 @@ type.
Semantics:
""""""""""
+Follows the IEEE754 2008 semantics for minNum, except for handling of
++0.0 vs -0.0. This matches the behavior of libm's fmin.
-Follows the IEEE-754 semantics for minNum, except for handling of
-signaling NaNs. This match's the behavior of libm's fmin.
-
-If either operand is a NaN, returns the other non-NaN operand. Returns
-NaN only if both operands are NaN. If the operands compare equal,
-returns either one of the operands. For example, this means that
-fmin(+0.0, -0.0) returns either operand.
-
-Unlike the IEEE-754 2008 behavior, this does not distinguish between
-signaling and quiet NaN inputs. If a target's implementation follows
-the standard and returns a quiet NaN if either input is a signaling
-NaN, the intrinsic lowering is responsible for quieting the inputs to
-correctly return the non-NaN input (e.g. by using the equivalent of
-``llvm.canonicalize``).
+If either operand is a qNaN, returns the other non-NaN operand. Returns
+NaN only if both operands are NaN or either operand is sNaN.
+If the operands compare equal, returns either one of the operands.
+For example, this means that fmin(+0.0, -0.0) returns either operand.
.. _i_maxnum:
@@ -16515,20 +16507,13 @@ type.
Semantics:
""""""""""
-Follows the IEEE-754 semantics for maxNum except for the handling of
-signaling NaNs. This matches the behavior of libm's fmax.
+Follows the IEEE754 2008 semantics for maxNum, except for handling of
++0.0 vs -0.0. This matches the behavior of libm's fmax.
If either operand is a NaN, returns the other non-NaN operand. Returns
-NaN only if both operands are NaN. If the operands compare equal,
-returns either one of the operands. For example, this means that
-fmax(+0.0, -0.0) returns either -0.0 or 0.0.
-
-Unlike the IEEE-754 2008 behavior, this does not distinguish between
-signaling and quiet NaN inputs. If a target's implementation follows
-the standard and returns a quiet NaN if either input is a signaling
-NaN, the intrinsic lowering is responsible for quieting the inputs to
-correctly return the non-NaN input (e.g. by using the equivalent of
-``llvm.canonicalize``).
+NaN only if both operands are NaN or either operand is sNaN.
+If the operands compare equal, returns either one of the operands.
+For example, this means that fmin(+0.0, -0.0) returns either operand.
.. _i_minimum:
@@ -19407,12 +19392,12 @@ The '``llvm.vector.reduce.fmax.*``' intrinsics do a floating-point
matches the element-type of the vector input.
This instruction has the same comparison semantics as the '``llvm.maxnum.*``'
-intrinsic. That is, the result will always be a number unless all elements of
-the vector are NaN. For a vector with maximum element magnitude 0.0 and
-containing both +0.0 and -0.0 elements, the sign of the result is unspecified.
+intrinsic. If the intrinsic call has the ``nnan`` fast-math flag, then the
+operation can assume that NaNs are not present in the input vector.
-If the intrinsic call has the ``nnan`` fast-math flag, then the operation can
-assume that NaNs are not present in the input vector.
+It is deprecated, since the different order of inputs may produce different
+outputs, and it is hard to optimize with Vector or SIMD extensions.
+Use '``llvm.vector.reduce.fmaximum``' or '``llvm.vector.reduce.fmaximumnum``' instead.
Arguments:
""""""""""
@@ -19440,12 +19425,12 @@ The '``llvm.vector.reduce.fmin.*``' intrinsics do a floating-point
matches the element-type of the vector input.
This instruction has the same comparison semantics as the '``llvm.minnum.*``'
-intrinsic. That is, the result will always be a number unless all elements of
-the vector are NaN. For a vector with minimum element magnitude 0.0 and
-containing both +0.0 and -0.0 elements, the sign of the result is unspecified.
+intrinsic. If the intrinsic call has the ``nnan`` fast-math flag, then the
+operation can assume that NaNs are not present in the input vector.
-If the intrinsic call has the ``nnan`` fast-math flag, then the operation can
-assume that NaNs are not present in the input vector.
+It is deprecated, since the different order of inputs may produce different
+outputs, and it is hard to optimize with Vector or SIMD extensions.
+Use '``llvm.vector.reduce.fminimum``' or '``llvm.vector.reduce.fminimumnum``' instead.
Arguments:
""""""""""
@@ -22994,13 +22979,14 @@ result type. If only ``nnan`` is set then the neutral value is ``-Infinity``.
This instruction has the same comparison semantics as the
:ref:`llvm.vector.reduce.fmax <int_vector_reduce_fmax>` intrinsic (and thus the
-'``llvm.maxnum.*``' intrinsic). That is, the result will always be a number
-unless all elements of the vector and the starting value are ``NaN``. For a
-vector with maximum element magnitude ``0.0`` and containing both ``+0.0`` and
-``-0.0`` elements, the sign of the result is unspecified.
+'``llvm.maxnum.*``' intrinsic).
To ignore the start value, the neutral value can be used.
+It is deprecated, since the different order of inputs may produce different
+outputs, and it is hard to optimize with Vector or SIMD extensions.
+Use '``llvm.vp.vector.reduce.fmaximum``' or '``llvm.vp.vector.reduce.fmaximumnum``' instead.
+
Examples:
"""""""""
@@ -23064,13 +23050,14 @@ result type. If only ``nnan`` is set then the neutral value is ``+Infinity``.
This instruction has the same comparison semantics as the
:ref:`llvm.vector.reduce.fmin <int_vector_reduce_fmin>` intrinsic (and thus the
-'``llvm.minnum.*``' intrinsic). That is, the result will always be a number
-unless all elements of the vector and the starting value are ``NaN``. For a
-vector with maximum element magnitude ``0.0`` and containing both ``+0.0`` and
-``-0.0`` elements, the sign of the result is unspecified.
+'``llvm.minnum.*``' intrinsic).
To ignore the start value, the neutral value can be used.
+It is deprecated, since the different order of inputs may produce different
+outputs, and it is hard to optimize with Vector or SIMD extensions.
+Use '``llvm.vp.vector.reduce.fminimum``' or '``llvm.vp.vector.reduce.fminimumnum``' instead.
+
Examples:
"""""""""
>From ea6a89bd0fe9d8c5071fef7667efd9b08d0abbde Mon Sep 17 00:00:00 2001
From: YunQiang Su <wzssyqa at gmail.com>
Date: Sat, 19 Oct 2024 01:33:13 +0800
Subject: [PATCH 2/7] minNum doesn't care about +0 vs -0
---
llvm/docs/LangRef.rst | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst
index 2df01362a27ec6..fb52141d62038e 100644
--- a/llvm/docs/LangRef.rst
+++ b/llvm/docs/LangRef.rst
@@ -16464,8 +16464,8 @@ type.
Semantics:
""""""""""
-Follows the IEEE754 2008 semantics for minNum, except for handling of
-+0.0 vs -0.0. This matches the behavior of libm's fmin.
+Follows the IEEE754 2008 semantics for minNum.
+This also matches the behavior of libm's fmin.
If either operand is a qNaN, returns the other non-NaN operand. Returns
NaN only if both operands are NaN or either operand is sNaN.
@@ -16507,8 +16507,8 @@ type.
Semantics:
""""""""""
-Follows the IEEE754 2008 semantics for maxNum, except for handling of
-+0.0 vs -0.0. This matches the behavior of libm's fmax.
+Follows the IEEE754 2008 semantics for maxNum.
+This also matches the behavior of libm's fmax.
If either operand is a NaN, returns the other non-NaN operand. Returns
NaN only if both operands are NaN or either operand is sNaN.
>From b653061afd2481d1581302f6c3af0e3b3d0d5d34 Mon Sep 17 00:00:00 2001
From: YunQiang Su <syq at debian.org>
Date: Sun, 20 Oct 2024 12:13:21 +0800
Subject: [PATCH 3/7] add history about libm
---
llvm/docs/LangRef.rst | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst
index fb52141d62038e..bde5d4c23ce32c 100644
--- a/llvm/docs/LangRef.rst
+++ b/llvm/docs/LangRef.rst
@@ -16465,7 +16465,11 @@ type.
Semantics:
""""""""""
Follows the IEEE754 2008 semantics for minNum.
-This also matches the behavior of libm's fmin.
+This also matches the current (C23) behavior of libm's fmin.
+
+Historically, libc returns NUM for NUM vs (sNaN or qNaN), and may return
+sNaN for qNaN vs sNaN. Withe recent libc versions, libc follows IEEE754-2008:
+NUM vs sNaN -> qNaN; NUM vs qNaN -> NUM; qNaN vs sNaN -> qNaN; sNaN vs sNaN -> qNaN.
If either operand is a qNaN, returns the other non-NaN operand. Returns
NaN only if both operands are NaN or either operand is sNaN.
@@ -16508,7 +16512,11 @@ type.
Semantics:
""""""""""
Follows the IEEE754 2008 semantics for maxNum.
-This also matches the behavior of libm's fmax.
+This also matches the current (C23) behavior of libm's fmax.
+
+Historically, libc returns NUM for NUM vs (sNaN or qNaN), and may return
+sNaN for qNaN vs sNaN. Withe recent libc versions, libc follows IEEE754-2008:
+NUM vs sNaN -> qNaN; NUM vs qNaN -> NUM; qNaN vs sNaN -> qNaN; sNaN vs sNaN -> qNaN.
If either operand is a NaN, returns the other non-NaN operand. Returns
NaN only if both operands are NaN or either operand is sNaN.
>From 02b738fbbcbc9567b172e38b95929f55a4849376 Mon Sep 17 00:00:00 2001
From: YunQiang Su <yunqiang at isrc.iscas.ac.cn>
Date: Mon, 21 Oct 2024 08:56:22 +0800
Subject: [PATCH 4/7] fmin requires +0>-0
---
llvm/docs/LangRef.rst | 24 ++++++++++++++++--------
1 file changed, 16 insertions(+), 8 deletions(-)
diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst
index bde5d4c23ce32c..01f71779872315 100644
--- a/llvm/docs/LangRef.rst
+++ b/llvm/docs/LangRef.rst
@@ -16420,7 +16420,7 @@ versions of the intrinsics respect the exception behavior.
- qNaN, invalid exception
* - ``+0.0 vs -0.0``
- - either one
+ - +0.0(max)/-0.0(min)
- +0.0(max)/-0.0(min)
- +0.0(max)/-0.0(min)
@@ -16464,8 +16464,14 @@ type.
Semantics:
""""""""""
-Follows the IEEE754 2008 semantics for minNum.
-This also matches the current (C23) behavior of libm's fmin.
+Follows the IEEE754 2008 semantics for minNum with +0.0>-0.0.
+This is more strict than current (C23) behavior of libm's fmin.
+Some applications like Clang, can call '``llvm.minnum.*``' with '``nsz``' attribute
+to archive the same behaivor of libm's fmin.
+
+For some architecturs, such as ARMv8, LoongArch, MIPSr6, PowerPC/VSX, they have the
+strict same instructions; thus it is quite simple for these architectures.
+For other architectures, the custom or expand methods may provide '``nsz``' flavor.
Historically, libc returns NUM for NUM vs (sNaN or qNaN), and may return
sNaN for qNaN vs sNaN. Withe recent libc versions, libc follows IEEE754-2008:
@@ -16511,12 +16517,14 @@ type.
Semantics:
""""""""""
-Follows the IEEE754 2008 semantics for maxNum.
-This also matches the current (C23) behavior of libm's fmax.
+Follows the IEEE754 2008 semantics for maxNum with +0.0>-0.0.
+This is more strict than current (C23) behavior of libm's fmax.
+Some applications like Clang, can call '``llvm.maxnum.*``' with '``nsz``' attribute
+to archive the same behaivor of libm's fmax.
-Historically, libc returns NUM for NUM vs (sNaN or qNaN), and may return
-sNaN for qNaN vs sNaN. Withe recent libc versions, libc follows IEEE754-2008:
-NUM vs sNaN -> qNaN; NUM vs qNaN -> NUM; qNaN vs sNaN -> qNaN; sNaN vs sNaN -> qNaN.
+For some architecturs, such as ARMv8, LoongArch, MIPSr6, PowerPC/VSX, they have the
+strict same instructions; thus it is quite simple for these architectures.
+For other architectures, the custom or expand methods may provide '``nsz``' flavor.
If either operand is a NaN, returns the other non-NaN operand. Returns
NaN only if both operands are NaN or either operand is sNaN.
>From 1d50663bcea3a903bbd32dc59156053dd41b607e Mon Sep 17 00:00:00 2001
From: YunQiang Su <yunqiang at isrc.iscas.ac.cn>
Date: Mon, 21 Oct 2024 09:11:35 +0800
Subject: [PATCH 5/7] some fix
---
llvm/docs/LangRef.rst | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst
index 01f71779872315..11c536b0314365 100644
--- a/llvm/docs/LangRef.rst
+++ b/llvm/docs/LangRef.rst
@@ -16470,17 +16470,16 @@ Some applications like Clang, can call '``llvm.minnum.*``' with '``nsz``' attrib
to archive the same behaivor of libm's fmin.
For some architecturs, such as ARMv8, LoongArch, MIPSr6, PowerPC/VSX, they have the
-strict same instructions; thus it is quite simple for these architectures.
+strictly same instructions; thus it is quite simple for these architectures.
For other architectures, the custom or expand methods may provide '``nsz``' flavor.
Historically, libc returns NUM for NUM vs (sNaN or qNaN), and may return
-sNaN for qNaN vs sNaN. Withe recent libc versions, libc follows IEEE754-2008:
+sNaN for qNaN vs sNaN. With the recent libc versions, libc follows IEEE754-2008:
NUM vs sNaN -> qNaN; NUM vs qNaN -> NUM; qNaN vs sNaN -> qNaN; sNaN vs sNaN -> qNaN.
If either operand is a qNaN, returns the other non-NaN operand. Returns
NaN only if both operands are NaN or either operand is sNaN.
If the operands compare equal, returns either one of the operands.
-For example, this means that fmin(+0.0, -0.0) returns either operand.
.. _i_maxnum:
@@ -16523,13 +16522,16 @@ Some applications like Clang, can call '``llvm.maxnum.*``' with '``nsz``' attrib
to archive the same behaivor of libm's fmax.
For some architecturs, such as ARMv8, LoongArch, MIPSr6, PowerPC/VSX, they have the
-strict same instructions; thus it is quite simple for these architectures.
+strictly same instructions; thus it is quite simple for these architectures.
For other architectures, the custom or expand methods may provide '``nsz``' flavor.
+Historically, libc returns NUM for NUM vs (sNaN or qNaN), and may return
+sNaN for qNaN vs sNaN. With the recent libc versions, libc follows IEEE754-2008:
+NUM vs sNaN -> qNaN; NUM vs qNaN -> NUM; qNaN vs sNaN -> qNaN; sNaN vs sNaN -> qNaN.
+
If either operand is a NaN, returns the other non-NaN operand. Returns
NaN only if both operands are NaN or either operand is sNaN.
If the operands compare equal, returns either one of the operands.
-For example, this means that fmin(+0.0, -0.0) returns either operand.
.. _i_minimum:
>From d9c5bcf603e7721338e91b4cc12214beee9d94e6 Mon Sep 17 00:00:00 2001
From: YunQiang Su <yunqiang at isrc.iscas.ac.cn>
Date: Wed, 23 Oct 2024 09:25:07 +0800
Subject: [PATCH 6/7] add inconsistent note
---
llvm/docs/LangRef.rst | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst
index 11c536b0314365..010d8b0ceb0f5d 100644
--- a/llvm/docs/LangRef.rst
+++ b/llvm/docs/LangRef.rst
@@ -16477,6 +16477,11 @@ Historically, libc returns NUM for NUM vs (sNaN or qNaN), and may return
sNaN for qNaN vs sNaN. With the recent libc versions, libc follows IEEE754-2008:
NUM vs sNaN -> qNaN; NUM vs qNaN -> NUM; qNaN vs sNaN -> qNaN; sNaN vs sNaN -> qNaN.
+Note that that arithmetic on an sNaN doesn't consistently produce a qNaN,
+so arithmetic feeding into a minnum can produce inconsistent results.
+Such as `fmin(sNaN+0.0, 1.0)` can produce qNaN or 1.0 depending on whether `+0.0`
+is optimized out.
+
If either operand is a qNaN, returns the other non-NaN operand. Returns
NaN only if both operands are NaN or either operand is sNaN.
If the operands compare equal, returns either one of the operands.
@@ -16529,6 +16534,11 @@ Historically, libc returns NUM for NUM vs (sNaN or qNaN), and may return
sNaN for qNaN vs sNaN. With the recent libc versions, libc follows IEEE754-2008:
NUM vs sNaN -> qNaN; NUM vs qNaN -> NUM; qNaN vs sNaN -> qNaN; sNaN vs sNaN -> qNaN.
+Note that that arithmetic on an sNaN doesn't consistently produce a qNaN,
+so arithmetic feeding into a maxnum can produce inconsistent results.
+Such as `fmax(sNaN+0.0, 1.0)` can produce qNaN or 1.0 depending on whether `+0.0`
+is optimized out.
+
If either operand is a NaN, returns the other non-NaN operand. Returns
NaN only if both operands are NaN or either operand is sNaN.
If the operands compare equal, returns either one of the operands.
>From fb06acbedbc13e5040ea06c8bd967034a58df9da Mon Sep 17 00:00:00 2001
From: YunQiang Su <yunqiang at isrc.iscas.ac.cn>
Date: Wed, 30 Oct 2024 19:23:17 +0800
Subject: [PATCH 7/7] do more clarify
---
llvm/docs/LangRef.rst | 46 ++++++++++++++++----------
llvm/include/llvm/CodeGen/ISDOpcodes.h | 17 +++++++---
2 files changed, 40 insertions(+), 23 deletions(-)
diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst
index 010d8b0ceb0f5d..15af4dec27cfa0 100644
--- a/llvm/docs/LangRef.rst
+++ b/llvm/docs/LangRef.rst
@@ -16464,12 +16464,21 @@ type.
Semantics:
""""""""""
-Follows the IEEE754 2008 semantics for minNum with +0.0>-0.0.
-This is more strict than current (C23) behavior of libm's fmin.
-Some applications like Clang, can call '``llvm.minnum.*``' with '``nsz``' attribute
-to archive the same behaivor of libm's fmin.
+Follows the IEEE-754 semantics for minNum, except that -0.0 < +0.0 for the purposes
+of this intrinsic. As for signaling NaNs, per the IEEE-754 semantics, if either operand
+is an sNaN, the result is always a qNaN. This matches the recommended behavior for the libm
+function fmin, although not all implementations have implemented these recommended behaviors.
-For some architecturs, such as ARMv8, LoongArch, MIPSr6, PowerPC/VSX, they have the
+If either operand is a qNaN, returns the other non-NaN operand. Returns
+NaN only if both operands are NaN or either operand is sNaN.
+
+If the operands compare equal, returns either one of the operands.
+
+Returns -0.0 for +0.0 vs -0.0. libm doesn't require it, so that
+some applications like Clang, can call '``llvm.minnum.*``' with '``nsz``' attribute
+to archive the required behaivors of libm's fmin.
+
+Some architecturs, such as ARMv8, LoongArch, MIPSr6, PowerPC/VSX, have the
strictly same instructions; thus it is quite simple for these architectures.
For other architectures, the custom or expand methods may provide '``nsz``' flavor.
@@ -16482,10 +16491,6 @@ so arithmetic feeding into a minnum can produce inconsistent results.
Such as `fmin(sNaN+0.0, 1.0)` can produce qNaN or 1.0 depending on whether `+0.0`
is optimized out.
-If either operand is a qNaN, returns the other non-NaN operand. Returns
-NaN only if both operands are NaN or either operand is sNaN.
-If the operands compare equal, returns either one of the operands.
-
.. _i_maxnum:
'``llvm.maxnum.*``' Intrinsic
@@ -16521,12 +16526,21 @@ type.
Semantics:
""""""""""
-Follows the IEEE754 2008 semantics for maxNum with +0.0>-0.0.
-This is more strict than current (C23) behavior of libm's fmax.
-Some applications like Clang, can call '``llvm.maxnum.*``' with '``nsz``' attribute
-to archive the same behaivor of libm's fmax.
+Follows the IEEE-754 semantics for minNum, except that -0.0 < +0.0 for the purposes
+of this intrinsic. As for signaling NaNs, per the IEEE-754 semantics, if either operand
+is an sNaN, the result is always a qNaN. This matches the recommended behavior for the libm
+function fmin, although not all implementations have implemented these recommended behaviors.
-For some architecturs, such as ARMv8, LoongArch, MIPSr6, PowerPC/VSX, they have the
+If either operand is a qNaN, returns the other non-NaN operand. Returns
+NaN only if both operands are NaN or either operand is sNaN.
+
+If the operands compare equal, returns either one of the operands.
+
+Returns -0.0 for +0.0 vs -0.0. libm doesn't require it, so that
+some applications like Clang, can call '``llvm.minnum.*``' with '``nsz``' attribute
+to archive the required behaivors of libm's fmin.
+
+Some architecturs, such as ARMv8, LoongArch, MIPSr6, PowerPC/VSX, have the
strictly same instructions; thus it is quite simple for these architectures.
For other architectures, the custom or expand methods may provide '``nsz``' flavor.
@@ -16539,10 +16553,6 @@ so arithmetic feeding into a maxnum can produce inconsistent results.
Such as `fmax(sNaN+0.0, 1.0)` can produce qNaN or 1.0 depending on whether `+0.0`
is optimized out.
-If either operand is a NaN, returns the other non-NaN operand. Returns
-NaN only if both operands are NaN or either operand is sNaN.
-If the operands compare equal, returns either one of the operands.
-
.. _i_minimum:
'``llvm.minimum.*``' Intrinsic
diff --git a/llvm/include/llvm/CodeGen/ISDOpcodes.h b/llvm/include/llvm/CodeGen/ISDOpcodes.h
index 0b6d155b6d161e..179cab137b5095 100644
--- a/llvm/include/llvm/CodeGen/ISDOpcodes.h
+++ b/llvm/include/llvm/CodeGen/ISDOpcodes.h
@@ -1021,13 +1021,20 @@ enum NodeType {
LRINT,
LLRINT,
- /// FMINNUM/FMAXNUM - Perform floating-point minimum or maximum on two
- /// values.
+ /// FMINNUM/FMAXNUM - Perform floating-point minimum maximum on two values,
+ /// following IEEE-754 definitions.
///
- /// In the case where a single input is a NaN (either signaling or quiet),
- /// the non-NaN input is returned.
+ /// If one input is a signaling NaN, returns a quiet NaN. This matches
+ /// IEEE-754 2008's minnum/maxnum behavior for signaling NaNs (which differs
+ /// from 2019).
+ ///
+ /// These treat -0 as ordered less than +0, matching the behavior of IEEE-754
+ /// 2019's minimumNumber/maximumNumber.
///
- /// The return value of (FMINNUM 0.0, -0.0) could be either 0.0 or -0.0.
+ /// Note that that arithmetic on an sNaN doesn't consistently produce a qNaN,
+ /// so arithmetic feeding into a minnum/maxnum can produce inconsistent
+ /// results. FMAXIMUN/FMINIMUM or FMAXIMUMNUM/FMINIMUMNUM may be better choice
+ /// for non-distinction of sNaN/qNaN handling.
FMINNUM,
FMAXNUM,
More information about the llvm-commits
mailing list