Submitter:CFP group
Submission Date: 2021-??-??
Document: WG14 N27??
Title: N27??: *_HAS_SUBNORM==0 implies what?
Reference Documents:

Summary: A reader has asked some of the CFP group members:

If *_HAS_SUBNORM is 0, what does that imply? For example, what is fpclassify(subnormal)? Is it: FP_SUBNORMAL or FP_ZERO, or lead to undefined behaviour (UB)?

Discussion

5.2.4.2.2, paragraph 14 defines what *_HAS_SUBNORM means in vague terms. In particular:

0 absent (type does not support subnormal numbers)28)
28) Characterization as absent is intended if no floating-point operations produce subnormal results from non-subnormal inputs, even if the type format includes representations of subnormal numbers.

IEC 60559 has in 8.2 Resuming alternate exception handling attributes

-- abruptUnderflow
When underflow is signaled because a tiny non-zero result is detected, replace the default result with a zero of the same sign or a minimum normal rounded result of the same sign, raise the underflow flag, and signal the inexact exception. When roundTiesToEven, roundTiesToAway, or the roundTowardZero attribute is applicable, the rounded result magnitude shall be zero. When the roundTowardPositive attribute is applicable, the rounded result magnitude shall be the minimum normal magnitude for positive tiny results, and zero for negative tiny results. When the roundTowardNegative attribute is applicable, the rounded result magnitude shall be the minimum normal magnitude for negative tiny results, and zero for positive tiny results. This attribute has no effect on the interpretation of subnormal operands.

The above has not been added to C23.

There are architectures, such as ARM, that have control bits for two independent actions:

Those apply to all floating-point formats (as far as we know).

The user's program can change those at runtime (by facilities not part of Standard C). So, *_HAS_SUBNORM really should be a dynamic runtime property (not a constant translation time property); so should be like FLT_ROUNDS. But, since it is probably too late to change that, it should have (for this case) the value -1 (meaning indeterminable).

Early versions of ARM let the sign of the zeros from flushed subnormals be implementation defined. Later versions set the sign of the zero to be the sign of the subnormal. Rounding control has no effect.

So, if subnormal operands are treated as zero, then subnormal numbers could be considered as non-canonical encodings of zero. That would mean (independent of flushing subnormal results):

However, if subnormal operands are NOT treated as zero, that would mean (independent of flushing subnormal results):

Proposal

Change 5.2.4.2.2, paragraph 14:

The presence or absence of subnormal numbers is characterized by the implementation-defined values of FLT_HAS_SUBNORM, DBL_HAS_SUBNORM, and LDBL_HAS_SUBNORM
-1 indeterminable27)
0 absent (type does not support subnormal numbers)28)
1 present (type does support subnormal numbers)
to
The presence or absence of subnormal numbers, and the amount of support, is characterized by the implementation-defined values of FLT_HAS_SUBNORM, DBL_HAS_SUBNORM, and LDBL_HAS_SUBNORM
-1 indeterminable or changable at runtime27)
0 absent or both subnormal operands and results are flushed to zero (type does not support subnormal numbers)28)
1 present and both subnormal operands and results are not flushed to zero (type does support subnormal numbers)
2 present and subnormal operands (but not results) are flushed to zero
4 present and subnormal results (but not operands) are flushed to zero
Flushing to zero may depend upon rounding direction and may produce the smallest normal number (with the same sign).
If subnormal operands are treated as zero (independent of flushing subnormal results), then subnormal numbers shall be considered as non-canonical encodings of zero; else subnormal operands shall be treated as subnormal.

Change footnote 28 in 5.2.4.2.2 to:

28) Characterization as absent is intended if either subnormal operands are treated as zero or no floating-point operations produce subnormal results from non-subnormal inputs, even if the type format includes representations of subnormal numbers.