-
Notifications
You must be signed in to change notification settings - Fork 17.7k
[LangRef] Clarify specification for float min/max operations #172012
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
Changes from 16 commits
c4b5988
efdceb0
7ed8a9b
87b8ebd
4986f87
27ac393
d9ce6e1
af77786
6d23cc2
2405da3
0f5aa2a
c209ffd
cded10c
18622c4
6484632
6d61cfd
29e7cee
1d48412
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||
|---|---|---|---|---|---|---|---|---|
|
|
@@ -17305,95 +17305,44 @@ The returned value is completely identical to the input except for the sign bit; | |||||||
| in particular, if the input is a NaN, then the quiet/signaling bit and payload | ||||||||
| are perfectly preserved. | ||||||||
|
|
||||||||
| .. _i_fminmax_family: | ||||||||
| Floating-point min/max intrinsics comparison | ||||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ||||||||
|
|
||||||||
| '``llvm.min.*``' Intrinsics Comparation | ||||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ||||||||
| LLVM supports three pairs of floating-point min/max intrinsics, which differ | ||||||||
| in their handling of :ref:`NaN values <floatnan>`: | ||||||||
|
|
||||||||
| Standard: | ||||||||
| """"""""" | ||||||||
| * ``llvm.minimum`` and ``llvm.maximum``: Return NaN if one the arguments is | ||||||||
| NaN. | ||||||||
| * ``llvm.minimumnum`` and ``llvm.maximumnum``: Return the other argument if | ||||||||
| one of the arguments is NaN. | ||||||||
| * ``llvm.minnum`` and ``llvm.maxnum``: For quiet NaNs behaves like | ||||||||
| minimumnum/maximumnum. For signaling NaNs, non-deterministically returns | ||||||||
| NaN or the other operand. | ||||||||
|
|
||||||||
| IEEE754 and ISO C define some min/max operations, and they have some differences | ||||||||
| on working with qNaN/sNaN and +0.0/-0.0. Here is the list: | ||||||||
| Additionally, each of these intrinsics supports two behaviors for signed zeroes. | ||||||||
| By default, -0.0 is considered smaller than +0.0. If the ``nsz`` flag is | ||||||||
| specified, the order is non-deterministic. | ||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done. |
||||||||
|
|
||||||||
| .. list-table:: | ||||||||
| :header-rows: 2 | ||||||||
|
|
||||||||
| * - ``ISO C`` | ||||||||
| - fmin/fmax | ||||||||
| - fmininum/fmaximum | ||||||||
| - fminimum_num/fmaximum_num | ||||||||
|
|
||||||||
| * - ``IEEE754`` | ||||||||
| - minNum/maxNum (2008) | ||||||||
| - minimum/maximum (2019) | ||||||||
| - minimumNumber/maximumNumber (2019) | ||||||||
|
|
||||||||
| * - ``+0.0 vs -0.0`` | ||||||||
| - either one | ||||||||
| - +0.0 > -0.0 | ||||||||
| - +0.0 > -0.0 | ||||||||
|
|
||||||||
| * - ``NUM vs sNaN`` | ||||||||
| - qNaN, invalid exception | ||||||||
| - qNaN, invalid exception | ||||||||
| - NUM, invalid exception | ||||||||
|
|
||||||||
| * - ``qNaN vs sNaN`` | ||||||||
| - qNaN, invalid exception | ||||||||
| - qNaN, invalid exception | ||||||||
| - qNaN, invalid exception | ||||||||
|
|
||||||||
| * - ``NUM vs qNaN`` | ||||||||
| - NUM, no exception | ||||||||
| - qNaN, no exception | ||||||||
| - NUM, no exception | ||||||||
|
|
||||||||
| LLVM Implementation: | ||||||||
| """""""""""""""""""" | ||||||||
|
|
||||||||
| LLVM implements all ISO C flavors as listed in this table, except in the | ||||||||
| default floating-point environment exceptions are ignored. The constrained | ||||||||
| versions of the intrinsics respect the exception behavior. | ||||||||
| The mapping between the LLVM intrinsics, C functions and IEEE 754 functions is | ||||||||
| as follows (up to divergences permitted by the usual `NaN rules <floatnan>`): | ||||||||
|
|
||||||||
| .. list-table:: | ||||||||
| :header-rows: 1 | ||||||||
| :widths: 16 28 28 28 | ||||||||
|
|
||||||||
| * - Operation | ||||||||
| - minnum/maxnum | ||||||||
| - minimum/maximum | ||||||||
| - minimumnum/maximumnum | ||||||||
|
|
||||||||
| * - ``NUM vs qNaN`` | ||||||||
| - NUM, no exception | ||||||||
| - qNaN, no exception | ||||||||
| - NUM, no exception | ||||||||
|
|
||||||||
| * - ``NUM vs sNaN`` | ||||||||
| - qNaN, invalid exception | ||||||||
| - qNaN, invalid exception | ||||||||
| - NUM, invalid exception | ||||||||
|
|
||||||||
| * - ``qNaN vs sNaN`` | ||||||||
| - qNaN, invalid exception | ||||||||
| - qNaN, invalid exception | ||||||||
| - qNaN, invalid exception | ||||||||
|
|
||||||||
| * - ``sNaN vs sNaN`` | ||||||||
| - qNaN, invalid exception | ||||||||
| - qNaN, invalid exception | ||||||||
| - qNaN, invalid exception | ||||||||
|
|
||||||||
| * - ``+0.0 vs -0.0`` | ||||||||
| - +0.0(max)/-0.0(min) | ||||||||
| - +0.0(max)/-0.0(min) | ||||||||
| - +0.0(max)/-0.0(min) | ||||||||
|
|
||||||||
| * - ``NUM vs NUM`` | ||||||||
| - larger(max)/smaller(min) | ||||||||
| - larger(max)/smaller(min) | ||||||||
| - larger(max)/smaller(min) | ||||||||
|
|
||||||||
| * - LLVM intrinsic | ||||||||
| - llvm.minnum with nsz flag | ||||||||
| - llvm.minimum | ||||||||
| - llvm.minimumnum | ||||||||
|
|
||||||||
| * - C function | ||||||||
| - fmin | ||||||||
| - fminimum | ||||||||
| - fminimum_num | ||||||||
|
|
||||||||
| * - IEEE 754 function | ||||||||
|
nikic marked this conversation as resolved.
Outdated
|
||||||||
| - minNum (2008) | ||||||||
| - minimum (2019) | ||||||||
| - minimumNumber (2019) | ||||||||
|
|
||||||||
| .. _i_minnum: | ||||||||
|
|
||||||||
|
|
@@ -17430,30 +17379,36 @@ type. | |||||||
|
|
||||||||
| Semantics: | ||||||||
| """""""""" | ||||||||
| Follows the semantics of minNum in IEEE-754-2008, except that -0.0 < +0.0 for the purposes | ||||||||
| of this intrinsic. As for signaling NaNs, per the minNum semantics, if either operand is sNaN, | ||||||||
| the result is qNaN. This matches the recommended behavior for the libm | ||||||||
| function ``fmin``, although not all implementations have implemented these recommended behaviors. | ||||||||
|
|
||||||||
| If either operand is a qNaN, returns the other non-NaN operand. Returns NaN only if both operands are | ||||||||
| NaN or if either operand is sNaN. Note that arithmetic on an sNaN doesn't consistently produce a qNaN, | ||||||||
| so arithmetic feeding into a minnum can produce inconsistent results. For example, | ||||||||
| ``minnum(fadd(sNaN, -0.0), 1.0)`` can produce qNaN or 1.0 depending on whether ``fadd`` is folded. | ||||||||
| If both operands are qNaNs, returns a :ref:`NaN <floatnan>`. If one operand is | ||||||||
| qNaN and another operand is a number, returns the number. If both operands are | ||||||||
| numbers, returns the lesser of the two arguments. -0.0 is considered to be less | ||||||||
| than +0.0 for this intrinsic. | ||||||||
|
|
||||||||
| If an operand is a signaling NaN, then the intrinsic will non-deterministically | ||||||||
| either: | ||||||||
|
|
||||||||
| IEEE-754-2008 defines minNum, and it was removed in IEEE-754-2019. As the replacement, IEEE-754-2019 | ||||||||
| defines :ref:`minimumNumber <i_minimumnum>`. | ||||||||
| * Return a :ref:`NaN <floatnan>`. | ||||||||
| * Or treat the signaling NaN as a quiet NaN. | ||||||||
|
|
||||||||
| If the intrinsic is marked with the nsz attribute, then the effect is as in the definition in C | ||||||||
| and IEEE-754-2008: the result of ``minnum(-0.0, +0.0)`` may be either -0.0 or +0.0. | ||||||||
| If the ``nsz`` flag is specified, ``llvm.minnum`` with one +0.0 and one | ||||||||
| -0.0 operand may non-deterministically return either operand. Contrary to normal | ||||||||
| ``nsz`` semantics, if both operands have the same sign, the result must also | ||||||||
| have the same sign. | ||||||||
|
|
||||||||
| Some architectures, such as ARMv8 (FMINNM), LoongArch (fmin), MIPSr6 (min.fmt), PowerPC/VSX (xsmindp), | ||||||||
| have instructions that match these semantics exactly; thus it is quite simple for these architectures. | ||||||||
| Some architectures have similar ones while they are not exact equivalent. Such as x86 implements ``MINPS``, | ||||||||
| which implements the semantics of C code ``a<b?a:b``: NUM vs qNaN always return qNaN. ``MINPS`` can be used | ||||||||
| if ``nsz`` and ``nnan`` are given. | ||||||||
| When used with the ``nsz`` flag, this intrinsic follows the semantics of | ||||||||
|
nikic marked this conversation as resolved.
Outdated
|
||||||||
| ``fmin`` in C and ``minNum`` in IEEE 754-2008, except for signaling NaN inputs, | ||||||||
| which follow :ref:`LLVM's usual signaling NaN behavior <floatnan>` instead. | ||||||||
|
|
||||||||
| For existing libc implementations, the behaviors of fmin may be quite different on sNaN and signed zero behaviors, | ||||||||
| even in the same release of a single libm implementation. | ||||||||
| The ``llvm.minnum`` intrinsic can be refined into ``llvm.minimumnum``, as the | ||||||||
| latter exhibits a subset of behaviors of the former. | ||||||||
|
|
||||||||
| .. warning:: | ||||||||
|
|
||||||||
| If the intrinsic is used without nsz, not all backends currently respect the | ||||||||
| specified signed zero ordering. Do not rely on it until this warning has | ||||||||
| been removed. See `issue #174730 | ||||||||
| <https://github.com/llvm/llvm-project/issues/174730>`_. | ||||||||
|
Comment on lines
+17411
to
+17414
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Reflecting my latest comment on the discourse thread, my concrete suggestion is to switch this from being a warning about a bug, to instead be the expected semantics of llvm.minnum without nsz. That is, it's recommended for it to order -0.0 < 0.0, but that may not happen on all targets, depending on the backend lowering and the libc in use. Compiler transforms shouldn't break the property, but also cannot rely on it without external knowledge.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That's a whole new dimension of complications that I am not sure is worth it. It's also not anywhere in the "convex hull" of what has been documented and implemented in LLVM over the past ~year. Should we really expand the design space even further?
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No, this is the worst possible world and leaves us back where we started. Every intrinsic needs to have a fixed definition, without target flexibility. Otherwise it's useless to any analysis or transformation that might as well be a black box |
||||||||
|
|
||||||||
| .. _i_maxnum: | ||||||||
|
|
||||||||
|
|
@@ -17490,30 +17445,36 @@ type. | |||||||
|
|
||||||||
| Semantics: | ||||||||
| """""""""" | ||||||||
| Follows the semantics of maxNum in IEEE-754-2008, except that -0.0 < +0.0 for the purposes | ||||||||
| of this intrinsic. As for signaling NaNs, per the maxNum semantics, if either operand is sNaN, | ||||||||
| the result is qNaN. This matches the recommended behavior for the libm | ||||||||
| function ``fmax``, although not all implementations have implemented these recommended behaviors. | ||||||||
|
|
||||||||
| If either operand is a qNaN, returns the other non-NaN operand. Returns NaN only if both operands are | ||||||||
| NaN or if either operand is sNaN. Note that arithmetic on an sNaN doesn't consistently produce a qNaN, | ||||||||
| so arithmetic feeding into a maxnum can produce inconsistent results. For example, | ||||||||
| ``maxnum(fadd(sNaN, -0.0), 1.0)`` can produce qNaN or 1.0 depending on whether ``fadd`` is folded. | ||||||||
| If both operands are qNaNs, returns a :ref:`NaN <floatnan>`. If one operand is | ||||||||
| qNaN and another operand is a number, returns the number. If both operands are | ||||||||
| numbers, returns the greater of the two arguments. -0.0 is considered to be | ||||||||
| less than +0.0 for this intrinsic. | ||||||||
|
|
||||||||
| If an operand is a signaling NaN, then the intrinsic will non-deterministically | ||||||||
| either: | ||||||||
|
|
||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe should be explicit that the output for a signaling nan input must be a quiet nan result. Though on second thought, maybe we can't guarantee this given option 2. e.g.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If the input is sNaN, the output does not have to be qNaN, per our usual NaN semantics.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't see any alternatives except for defining |
||||||||
| IEEE-754-2008 defines maxNum, and it was removed in IEEE-754-2019. As the replacement, IEEE-754-2019 | ||||||||
| defines :ref:`maximumNumber <i_maximumnum>`. | ||||||||
| * Return a :ref:`NaN <floatnan>`. | ||||||||
| * Or treat the signaling NaN as a quiet NaN. | ||||||||
|
|
||||||||
| If the intrinsic is marked with the nsz attribute, then the effect is as in the definition in C | ||||||||
| and IEEE-754-2008: the result of maxnum(-0.0, +0.0) may be either -0.0 or +0.0. | ||||||||
| If the ``nsz`` flag is specified, ``llvm.maxnum`` with one +0.0 and one | ||||||||
| -0.0 operand may non-deterministically return either operand. Contrary to normal | ||||||||
| ``nsz`` semantics, if both operands have the same sign, the result must also | ||||||||
| have the same sign. | ||||||||
|
|
||||||||
| Some architectures, such as ARMv8 (FMAXNM), LoongArch (fmax), MIPSr6 (max.fmt), PowerPC/VSX (xsmaxdp), | ||||||||
| have instructions that match these semantics exactly; thus it is quite simple for these architectures. | ||||||||
| Some architectures have similar ones while they are not exact equivalent. Such as x86 implements ``MAXPS``, | ||||||||
| which implements the semantics of C code ``a>b?a:b``: NUM vs qNaN always return qNaN. ``MAXPS`` can be used | ||||||||
| if ``nsz`` and ``nnan`` are given. | ||||||||
| When used with the ``nsz`` flag, this intrinsic follows the semantics of | ||||||||
| ``fmax`` in C and ``maxNum`` in IEEE 754-2008, except for signaling NaN inputs, | ||||||||
|
nikic marked this conversation as resolved.
Outdated
|
||||||||
| which follow :ref:`LLVM's usual signaling NaN behavior <floatnan>` instead. | ||||||||
|
|
||||||||
| For existing libc implementations, the behaviors of fmin may be quite different on sNaN and signed zero behaviors, | ||||||||
| even in the same release of a single libm implementation. | ||||||||
| The ``llvm.maxnum`` intrinsic can be refined into ``llvm.maximumnum``, as the | ||||||||
| latter exhibits a subset of behaviors of the former. | ||||||||
|
|
||||||||
| .. warning:: | ||||||||
|
|
||||||||
| If the intrinsic is used without nsz, not all backends currently respect the | ||||||||
| specified signed zero ordering. Do not rely on it until this warning has | ||||||||
| been removed. See `issue #174730 | ||||||||
| <https://github.com/llvm/llvm-project/issues/174730>`_. | ||||||||
|
|
||||||||
| .. _i_minimum: | ||||||||
|
|
||||||||
|
|
@@ -17550,10 +17511,18 @@ type. | |||||||
|
|
||||||||
| Semantics: | ||||||||
| """""""""" | ||||||||
| If either operand is a NaN, returns NaN. Otherwise returns the lesser | ||||||||
| of the two arguments. -0.0 is considered to be less than +0.0 for this | ||||||||
| intrinsic. Note that these are the semantics specified in the draft of | ||||||||
| IEEE 754-2019. | ||||||||
| If either operand is a NaN, returns a :ref:`NaN <floatnan>`. Otherwise returns | ||||||||
| the lesser of the two arguments. -0.0 is considered to be less than +0.0 for | ||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same here. Signaling NaN is not treated specially here so I think even less there is an "exception". It's just that the output NaN representation is somewhat indeterminate.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In terms of keeping parallel style, this should follow the style that we do for minnum. In other words, something like this for the final sentence:
(in particular, it is helpful to mention the C23 name of the function, since the C standard is easily available for free publicly, whereas IEEE 754 is not).
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done. |
||||||||
| this intrinsic. | ||||||||
|
|
||||||||
| This intrinsic follows the semantics of ``fminimum`` in C23 and ``minimum`` in | ||||||||
| IEEE 754-2019, except for signaling NaN inputs, which follow | ||||||||
| :ref:`LLVM's usual signaling NaN behavior <floatnan>` instead. | ||||||||
|
|
||||||||
| If the ``nsz`` flag is specified, ``llvm.maximum`` with one +0.0 and one | ||||||||
| -0.0 operand may non-deterministically return either operand. Contrary to normal | ||||||||
| ``nsz`` semantics, if both operands have the same sign, the result must also | ||||||||
| have the same sign. | ||||||||
|
|
||||||||
| .. _i_maximum: | ||||||||
|
|
||||||||
|
|
@@ -17590,10 +17559,18 @@ type. | |||||||
|
|
||||||||
| Semantics: | ||||||||
| """""""""" | ||||||||
| If either operand is a NaN, returns NaN. Otherwise returns the greater | ||||||||
| of the two arguments. -0.0 is considered to be less than +0.0 for this | ||||||||
| intrinsic. Note that these are the semantics specified in the draft of | ||||||||
| IEEE 754-2019. | ||||||||
| If either operand is a NaN, returns a :ref:`NaN <floatnan>`. Otherwise returns | ||||||||
| the greater of the two arguments. -0.0 is considered to be less than +0.0 for | ||||||||
| this intrinsic. | ||||||||
|
|
||||||||
| This intrinsic follows the semantics of ``fmaximum`` in C23 and ``maximum`` in | ||||||||
| IEEE 754-2019, except for signaling NaN inputs, which follow | ||||||||
| :ref:`LLVM's usual signaling NaN behavior <floatnan>` instead. | ||||||||
|
|
||||||||
| If the ``nsz`` flag is specified, ``llvm.maximum`` with one +0.0 and one | ||||||||
| -0.0 operand may non-deterministically return either operand. Contrary to normal | ||||||||
| ``nsz`` semantics, if both operands have the same sign, the result must also | ||||||||
| have the same sign. | ||||||||
|
|
||||||||
| .. _i_minimumnum: | ||||||||
|
|
||||||||
|
|
@@ -17636,12 +17613,17 @@ one operand is NaN (including sNaN) and another operand is a number, | |||||||
| return the number. Otherwise returns the lesser of the two | ||||||||
| arguments. -0.0 is considered to be less than +0.0 for this intrinsic. | ||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. FWIW, there's now a mix of "IEEE-754" and "IEEE 754". Not sure that it matters...
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, there is a mix of both forms throughout the document. We should normalize to one of them in a separate change.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I see at present 3 uses of IEEE754, 6 of IEEE 754, 32 of IEEE-754, 0 of any flavor of ISO/IEC 60559. (Of the three forms, while IEEE-754 is the dominant form right now, IEEE 754- appears to be the most correct form.)
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. #174721 normalizes to IEEE 754. |
||||||||
|
|
||||||||
| Note that these are the semantics of minimumNumber specified in | ||||||||
| IEEE-754-2019 with the usual :ref:`signaling NaN <floatnan>` exception. | ||||||||
| If the ``nsz`` flag is specified, ``llvm.minimumnum`` with one +0.0 and one | ||||||||
| -0.0 operand may non-deterministically return either operand. Contrary to normal | ||||||||
|
nikic marked this conversation as resolved.
|
||||||||
| ``nsz`` semantics, if both operands have the same sign, the result must also | ||||||||
| have the same sign. | ||||||||
|
|
||||||||
| It has some differences with '``llvm.minnum.*``': | ||||||||
| 1)'``llvm.minnum.*``' will return qNaN if either operand is sNaN. | ||||||||
| 2)'``llvm.minnum*``' may return either one if we compare +0.0 vs -0.0. | ||||||||
| This intrinsic follows the semantics of ``fminimum_num`` in C23 and | ||||||||
| ``minimumNumber`` in IEEE 754-2019, except for signaling NaN inputs, which | ||||||||
| follow :ref:`LLVM's usual signaling NaN behavior <floatnan>` instead. | ||||||||
|
|
||||||||
| This intrinsic behaves the same as ``llvm.minnum`` other than its treatment of | ||||||||
| sNaN inputs. | ||||||||
|
|
||||||||
| .. _i_maximumnum: | ||||||||
|
|
||||||||
|
|
@@ -17685,12 +17667,17 @@ another operand is a number, return the number. Otherwise returns the | |||||||
| greater of the two arguments. -0.0 is considered to be less than +0.0 | ||||||||
| for this intrinsic. | ||||||||
|
|
||||||||
| Note that these are the semantics of maximumNumber specified in | ||||||||
| IEEE-754-2019 with the usual :ref:`signaling NaN <floatnan>` exception. | ||||||||
| If the ``nsz`` flag is specified, ``llvm.maximumnum`` with one +0.0 and one | ||||||||
| -0.0 operand may non-deterministically return either operand. Contrary to normal | ||||||||
| ``nsz`` semantics, if both operands have the same sign, the result must also | ||||||||
| have the same sign. | ||||||||
|
|
||||||||
| This intrinsic follows the semantics of ``fmaximum_num`` in C23 and | ||||||||
| ``maximumNumber`` in IEEE 754-2019, except for signaling NaN inputs, which | ||||||||
| follow :ref:`LLVM's usual signaling NaN behavior <floatnan>` instead. | ||||||||
|
|
||||||||
| It has some differences with '``llvm.maxnum.*``': | ||||||||
| 1)'``llvm.maxnum.*``' will return qNaN if either operand is sNaN. | ||||||||
| 2)'``llvm.maxnum*``' may return either one if we compare +0.0 vs -0.0. | ||||||||
| This intrinsic behaves the same as ``llvm.maxnum`` other than its treatment of | ||||||||
| sNaN inputs. | ||||||||
|
|
||||||||
| .. _int_copysign: | ||||||||
|
|
||||||||
|
|
@@ -20445,9 +20432,14 @@ The '``llvm.vector.reduce.fmax.*``' intrinsics do a floating-point | |||||||
| ``MAX`` reduction of a vector, returning the result as a scalar. The return type | ||||||||
| matches the element-type of the vector input. | ||||||||
|
|
||||||||
| This instruction has the same comparison semantics as the '``llvm.maxnum.*``' | ||||||||
| 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. | ||||||||
| This instruction has the same comparison and ``nsz`` semantics as the | ||||||||
| '``llvm.maxnum.*``' intrinsic. | ||||||||
|
|
||||||||
| If any of the vector elements is a signaling NaN, the intrinsic will | ||||||||
| non-deterministically either: | ||||||||
|
|
||||||||
| * Return a :ref:`NaN <floatnan>`. | ||||||||
| * Treat the signaling NaN as a quiet NaN. | ||||||||
|
|
||||||||
| Arguments: | ||||||||
| """""""""" | ||||||||
|
|
@@ -20474,9 +20466,14 @@ The '``llvm.vector.reduce.fmin.*``' intrinsics do a floating-point | |||||||
| ``MIN`` reduction of a vector, returning the result as a scalar. The return type | ||||||||
| matches the element-type of the vector input. | ||||||||
|
|
||||||||
| This instruction has the same comparison semantics as the '``llvm.minnum.*``' | ||||||||
| 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. | ||||||||
| This instruction has the same comparison and ``nsz`` semantics as the | ||||||||
| '``llvm.minnum.*``' intrinsic. | ||||||||
|
|
||||||||
| If any of the vector elements is a signaling NaN, the intrinsic will | ||||||||
| non-deterministically either: | ||||||||
|
|
||||||||
| * Return a :ref:`NaN <floatnan>`. | ||||||||
| * Treat the signaling NaN as a quiet NaN. | ||||||||
|
|
||||||||
| Arguments: | ||||||||
| """""""""" | ||||||||
|
|
||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FWIW this header is actually referenced by the clang docs (https://clang.llvm.org/docs/LanguageExtensions.html, Ctrl-F "__builtin_elementwise_minnum"). So they might need updating.
Those clang docs also provide a motivation for having "minnum (2008-style) with signed zero ordering", though it is not clear how deliberate that decision was.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, I changed these to reference
i-fminmax-familyinstead, so it's not dependent on the header (which had a typo previously...)