Repository navigation
[LangRef] Clarify denormal_fpenv slightly - #237290
LewisCrawford wants to merge 1 commit into
Conversation
|
@llvm/pr-subscribers-llvm-ir Author: Lewis Crawford (LewisCrawford) ChangesClarify in the langref that denormal_fpenv settings can also cause flushing to occur for calculations whose results are the smallest normal number, not just denormal numbers. Also, tidy up some duplicated text about the separate Full diff: https://github.com/llvm/llvm-project/pull/237290.diff 1 Files Affected:
diff --git a/llvm/docs/LangRef.md b/llvm/docs/LangRef.md
index 1e8342fd119be9..2d7131eec4ba54 100644
--- a/llvm/docs/LangRef.md
+++ b/llvm/docs/LangRef.md
@@ -2876,9 +2876,11 @@ fn -> other_fn -> other_fn ; fn is norecurse
If the output mode is `preservesign`, or `positivezero`,
denormal outputs may be flushed to zero by standard floating-point
- operations. It is not mandated that flushing to zero occurs, but if
- a denormal output is flushed to zero, it must respect the sign
- mode. Not all targets support all modes.
+ operations. On some targets, outputs that are rounded up to the smallest
+ positive normal number, or rounded down to the smallest negative normal
+ number may also be flushed to zero. It is not mandated that
+ flushing to zero occurs, but if an output is flushed to zero,
+ it must respect the sign mode. Not all targets support all modes.
If the mode is `dynamic`, the behavior is derived from the
dynamic state of the floating-point environment. Transformations
@@ -2890,10 +2892,6 @@ fn -> other_fn -> other_fn ; fn is norecurse
the mode is consistent. User or platform code is expected to set
the floating point mode appropriately before function entry.
- This may optionally specify a second pair, prefixed with
- `float:`. This provides an override for the behavior of 32-bit
- float type (or vectors of 32-bit floats).
-
If the input mode is `preservesign`, or `positivezero`,
a floating-point operation must treat any input denormal value as
zero. In some situations, if an instruction does not respect this
@@ -2902,11 +2900,10 @@ fn -> other_fn -> other_fn ; fn is norecurse
This may optionally specify a second pair, prefixed with
`float:`. This provides an override for the behavior of 32-bit
- float type. (or vectors of 32-bit floats). If this is present,
- this overrides the base handling of the default mode. Not all
+ float type (or vectors of 32-bit floats). Not all
targets support separately setting the denormal mode per type, and
- no attempt is made to diagnose unsupported uses. Currently this
- attribute is respected by the AMDGPU and NVPTX backends.
+ no attempt is made to diagnose unsupported uses. Currently the separate
+ `float:` attribute is respected by the AMDGPU and NVPTX backends.
**Examples:**
|
dc58691 to
8d8adfa
Compare
arsenm
left a comment
There was a problem hiding this comment.
This is mixing in some other phrasing fixups. But the core change is wrong and is just a bug?
Denormal flushing on x86 and ARM at least is defined not in terms of "is the result a denormal" but "would an underflow exception occur" (not in so few words though). Because of the rules for how underflow works, that does mean that there are circumstances where the precise result is in the range (largest subnormal, smallest normal) triggers underflow and yet the rounded result ends up being the smallest normal. See https://godbolt.org/z/nd5Mbq76n for some examples. |
|
(I don't know the behavior on all architectures, and quite frankly, this is the kind of detail that I wouldn't trust without having executable programs to prove the actual behavior of hardware, because the ISA manuals tend to really gloss over this sort of stuff.) |
|
It seems like NVPTX behaves the same as x86 in this regard too (at least on the GPUs I tried it with). I think it's fine at the IR level to treat things in the simple case of "subnormal results get flushed", since that's a case all hardware implementations should agree on. However, I also think it is useful to inform users that most actual target lowerings e.g. x86 with FTZ, Arm and AArch64 (with both AH=0 and AH=1 floating-point modes) with FZ, and NVTPX's .ftz instruction-modifiers can lead to these min-normal edge-cases where underflow detection causes a flush, even if the un-flushed result would be min-normal. This occurs because x86 and AArch64 (in both AH modes) detect when to do FTZ according to IEEE 754 section 7.5's Underflow definition. This definition allows checking for Underflow either:
Since it does this detection with either an unbounded exponent or both unbounded exponent+precision, it detects Underflow (and hence FTZ) before the final normalization step that may round things up to min-normal. So I don't think this edge-case requires any behaviour changes, but would be useful to highlight to users to avoid confusion about why it's not always strictly subnormal results that end up getting flushed. |
Clarify in the langref that denormal_fpenv settings can also cause flushing to occur for calculations whose results are the smallest normal number, not just denormal numbers.
8d8adfa to
29eaef2
Compare
|
I've split out the typo clean-up stuff into a separate patch here: #237921 to make the actual min-normal wording change clearer to review. Another potential wording here could be something like:
But I wasn't sure how much we wanted to tie this wording specifically to Underflow, or whether to keep it more abstract and less target-specific in case there are other similar min-normal edge-cases on other hardware that don't use Underflow detection for this though. |
Clarify in the langref that denormal_fpenv settings can also cause flushing to occur for calculations whose results are the smallest normal number, not just denormal numbers.
Also, tidy up some duplicated text about the separate
float:attribute left over from merging with the old "denormal-fp-math-f32" value #174293.Also, fix small typo "If this is attribute is"