================ @@ -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 +``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>`_. ---------------- arsenm wrote:
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 https://github.com/llvm/llvm-project/pull/172012 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
