diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst index c8cc38c23cff3..2dd297a795c26 100644 --- a/llvm/docs/LangRef.rst +++ b/llvm/docs/LangRef.rst @@ -16936,7 +16936,7 @@ versions of the intrinsics respect the exception behavior. - qNaN, invalid exception * - ``+0.0 vs -0.0`` - - +0.0(max)/-0.0(min) + - either one - +0.0(max)/-0.0(min) - +0.0(max)/-0.0(min) @@ -16980,30 +16980,21 @@ 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. -IEEE-754-2008 defines minNum, and it was removed in IEEE-754-2019. As the replacement, IEEE-754-2019 -defines :ref:`minimumNumber `. +Follows the IEEE-754 semantics for minNum, except for handling of +signaling NaNs. This match's the behavior of libm's fmin. -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 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. -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 similiar ones while they are not exact equivalent. Such as x86 implements ``MINPS``, -which implements the semantics of C code ``a`. +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. -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. - -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 similiar 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. - -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 implemention. +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``). .. _i_minimum: @@ -19942,8 +19923,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. If the intrinsic call has the ``nnan`` fast-math flag, then the -operation can assume that NaNs are not present in the input vector. +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. + +If the intrinsic call has the ``nnan`` fast-math flag, then the operation can +assume that NaNs are not present in the input vector. Arguments: """""""""" @@ -19971,8 +19956,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. If the intrinsic call has the ``nnan`` fast-math flag, then the -operation can assume that NaNs are not present in the input vector. +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. + +If the intrinsic call has the ``nnan`` fast-math flag, then the operation can +assume that NaNs are not present in the input vector. Arguments: """""""""" @@ -22262,7 +22251,7 @@ This is an overloaded intrinsic. Overview: """"""""" -Predicated floating-point IEEE-754-2008 minNum of two vectors of floating-point values. +Predicated floating-point IEEE-754 minNum of two vectors of floating-point values. Arguments: @@ -22311,7 +22300,7 @@ This is an overloaded intrinsic. Overview: """"""""" -Predicated floating-point IEEE-754-2008 maxNum of two vectors of floating-point values. +Predicated floating-point IEEE-754 maxNum of two vectors of floating-point values. Arguments: @@ -23610,7 +23599,10 @@ 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 ` intrinsic (and thus the -'``llvm.maxnum.*``' intrinsic). +'``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. To ignore the start value, the neutral value can be used. @@ -23677,7 +23669,10 @@ 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 ` intrinsic (and thus the -'``llvm.minnum.*``' intrinsic). +'``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. To ignore the start value, the neutral value can be used. @@ -28349,7 +28344,7 @@ The third argument specifies the exception behavior as described above. Semantics: """""""""" -This function follows the IEEE-754-2008 semantics for maxNum. +This function follows the IEEE-754 semantics for maxNum. '``llvm.experimental.constrained.minnum``' Intrinsic @@ -28381,7 +28376,7 @@ The third argument specifies the exception behavior as described above. Semantics: """""""""" -This function follows the IEEE-754-2008 semantics for minNum. +This function follows the IEEE-754 semantics for minNum. '``llvm.experimental.constrained.maximum``' Intrinsic diff --git a/llvm/include/llvm/CodeGen/ISDOpcodes.h b/llvm/include/llvm/CodeGen/ISDOpcodes.h index 80ef32aff62ae..9bd1ebb2abd55 100644 --- a/llvm/include/llvm/CodeGen/ISDOpcodes.h +++ b/llvm/include/llvm/CodeGen/ISDOpcodes.h @@ -1024,20 +1024,13 @@ enum NodeType { LRINT, LLRINT, - /// FMINNUM/FMAXNUM - Perform floating-point minimum maximum on two values, - /// following IEEE-754 definitions except for signed zero behavior. + /// FMINNUM/FMAXNUM - Perform floating-point minimum or maximum on two + /// values. /// - /// 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). + /// In the case where a single input is a NaN (either signaling or quiet), + /// the non-NaN input is returned. /// - /// These treat -0 as ordered less than +0, matching the behavior of IEEE-754 - /// 2019's minimumNumber/maximumNumber. - /// - /// 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. + /// The return value of (FMINNUM 0.0, -0.0) could be either 0.0 or -0.0. FMINNUM, FMAXNUM, @@ -1051,9 +1044,6 @@ enum NodeType { /// /// These treat -0 as ordered less than +0, matching the behavior of IEEE-754 /// 2019's minimumNumber/maximumNumber. - /// - /// Deprecated, and will be removed soon, as FMINNUM/FMAXNUM have the same - /// semantics now. FMINNUM_IEEE, FMAXNUM_IEEE,