[llvm] LangRef: Clarify nsz on min/max operations for +0.0 vs -0.0 (PR #137567)
YunQiang Su via llvm-commits
llvm-commits at lists.llvm.org
Wed May 7 03:27:26 PDT 2025
================
@@ -3914,6 +3914,10 @@ following flags to enable otherwise unsafe floating-point transformations.
No Signed Zeros - Allow optimizations to treat the sign of a zero
argument or zero result as insignificant. This does not imply that -0.0
is poison and/or guaranteed to not exist in the operation.
+ Don't require +0.0>-0.0 for min/max operations - Allow optimizations of the
+ min/max operation not to treat +0.0>-0.0. Note the result should be either of
+ the operands. (max|min)(-0.0, -0.0) should never return +0.0, and vice versa.
+ Note: floating compare operations always imply -0.0 == +0.0.
----------------
wzssyqa wrote:
> The general definition of nsz is, essentially that the optimizer can toggle the sign bit of any zero input or output of the operation. So it's possible to do "generic" optimizations based on the presence of nsz. The new rule says no, that's not how it works; it has a different effect for each possible operation, and it can't be copied from one operation to another. Do we have existing optimizations that query nsz on a generic FPMathOperator?
>
When we expand the fmin(3) and fmax(3) libc calls, we need something like `nsz` here.
We define `FMINNUM` is a little more strict than fmin(3) with: +0.0>-0.0.
So if we are working on libc call, we need to tell the `expandFMINNUM_FMAXNUM` to not care about the sign of zero. And dropping/adding the sign is not allowed by fmin(3) and fmax(3).
It means fmax(+0.0, +0.0) should never be -0.0.
> Assuming we actually want to do this, I think the text here needs to be organized differently: if there is no "generic" effect, you need to list out the effect on each operation.
>
We already do this:
```
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.
```
> Also, min/max is ambiguous: there are at least 6 different "min/max" intrinsics, and it's not clear if this applies to all of them.
It effects all of the 6 intrinsics.
https://github.com/llvm/llvm-project/pull/137567
More information about the llvm-commits
mailing list