On Sat, 25 Sep 2021, Roger Sayle wrote:

> Normally Boolean options/flags in GCC take the values zero or one.
> This patch tweaks flag_trapping_math to take the values 0 or 65535.
> More accurately it introduces a new trapping_math_model enumeration in
> flag-types.h, and uses this to allow front-ends to (potentially) control
> which expressions may be constant folded at compile-time by the middle-end.
> Floating point/language experts may recognize these flags (bits) as being
> modelled upon (extended) FENV_ACCESS.

I'm not sure exactly what those bits are modelled on (they are similar to, 
but not exactly the same as, IEEE 754 sub-exceptions), but a lot more 
explanation is needed - explanation of the rationale for the particular 
model chosen, explanation for what is or is not considered a default 
there, comments on each bit documenting its semantics in detail, and 
explanation of how this relates to other relevant discussions and patch 
proposals.

I think the following are the three key things this should be related to, 
none of which are mentioned in this patch submission:


(a) The various possible effects -ftrapping-math might have on allowed 
transformations, as discussed in bug 54192, where in comment #8 I 
identified five different kinds of restriction that -ftrapping-math might 
imply (only the first of which, and maybe to some extent the second, is 
handled much in GCC at present - and even there, there are various open 
bugs about cases where e.g. the expanders generate code not raising the 
right exceptions, or libgcc functions don't raise the right exceptions, 
especially when conversions between floating-point and integer are 
involved).

I actually think this sort of classification of effects of -ftrapping-math 
is probably more useful to provide control over (both internally in GCC 
and externally via more fine-grained command-line options) than the 
details of which individual exceptions are involved as suggested in your 
flags values.  However, the two are largely orthogonal (other than the 
point about exact underflows only relating to one of the exceptions).

I don't make any assertion here of which of these effects (if any) ought 
to be the default - making -ftrapping-math actually implement all five 
restrictions fully while keeping it the default might significantly impair 
optimization.  Also as mentioned in bug 54192, even if some such 
restrictions are applied by default, for soft-float systems with no 
support for exceptions it would make sense to apply more transformations 
unconditionally.


(b) Marc Glisse's -ffenv-access patches from August 2020 (and the 
discussion of them from that time).  Those don't claim to be complete, but 
they are the nearest we have to an attempt at implementing the sort of 
thing that would actually be needed to avoid code movement or removal that 
is invalid in the presence of code using floating-point flags (which 
overlaps a lot with what's needed to get -frounding-math correct under 
similar circumstances - except that a full -ftrapping-math might well 
involve stricter optimization restrictions than full -frounding-math, even 
in the absence of supporting non-local control float for trap handlers, 
because floating-point operations only read the rounding mode, but both 
read and write the exception state).


(c) The alternate exception handling bindings (FENV_EXCEPT pragma) in TS 
18661-5.  I'm not aware of any implementations of those bindings, it's far 
from clear whether they will turn out in the end to be a good way of 
providing C bindings to IEEE 754 alternate exception handling or not, and 
(given those issues) they aren't going to be integrated into C23.  But 
it's at least possible that the OPTIONAL_FLAG action (allowing 
transformations that cause certain exceptions or sub-exceptions not to 
raise the corresponding flag) could sometimes be useful in practice - and 
it's what seems to relate most closely to the sort of classification of 
exceptions in your patch (to implement it, you'd need that classification 
- though you'd also need to fix the other issues under (a) above).


> +  TRAPPING_MATH_QNANOP = 1UL << 0,
> +  TRAPPING_MATH_SNANOP = 1UL << 1,
> +  TRAPPING_MATH_QNANCMP = 1UL << 2,
> +  TRAPPING_MATH_SNANCMP = 1UL << 3,
> +  TRAPPING_MATH_INTCONV = 1UL << 4,
> +  TRAPPING_MATH_SQRTNEG = 1UL << 5,
> +  TRAPPING_MATH_LIBMFUN = 1UL << 6,
> +  TRAPPING_MATH_FDIVZERO = 1UL << 7,
> +  TRAPPING_MATH_IDIVZERO = 1UL << 8,
> +  TRAPPING_MATH_FPDENORM = 1UL << 9,
> +  TRAPPING_MATH_OVERFLOW = 1UL << 10,
> +  TRAPPING_MATH_UNDERFLOW = 1UL << 11,
> +  TRAPPING_MATH_INFDIVINF = 1UL << 12,
> +  TRAPPING_MATH_INFSUBINF = 1UL << 13,
> +  TRAPPING_MATH_INFMULZERO = 1UL << 14,
> +  TRAPPING_MATH_ZERODIVZERO = 1UL << 15,

Many of these are similar to, but not the same as, the sub-exceptions in 
IEEE 754 (enumerated as a more explicit list with names in TS 18661-5).

I think that if you want to handle sub-exceptions at all, it would be much 
better to follow the list in TS 18661-5 exactly (including using the names 
after the FE_ that appear in TS 18661-5, rather than inventing a different 
name for the same thing).  Maybe you then need an additional name to cover 
sub-exception cases not mentioned there (for lots of math.h functions, 
it's not exactly clear which sub-exception an invalid input corresponds 
to), but the TS 18661-5 list would be a good starting point.  (The only 
case I know of hardware that tracks sub-exception information, powerpc, 
has a more limited set of flag bits for sub-exceptions of "invalid".)

> +  TRAPPING_MATH_DEFAULT = (1UL << 16) - 1,
> +
> +  TRAPPING_MATH_INEXACT = 1UL << 16,

I think the existing semantics of -ftrapping-math apply to "inexact" just 
as they do to other exceptions (there may well be bugs there, of course), 
and it should be considered to be included in the default.  Any change to 
the default should be proposed separately from adding more fine-grained 
tracking of parts of -ftrapping-math.

> +  TRAPPING_MATH_TRAPV = 1UL << 17

I'm not sure what the semantics of this one are meant to be.  But since 
-ftrapv is more or less obsolescent, superseded by sanitizers, I don't 
think a new flag should really be named after it.  (And not named after 
the sanitizers either, unless you arrange for the sanitizers to generate 
IR using the new flag in some way.)

-- 
Joseph S. Myers
jos...@codesourcery.com

Reply via email to