On Tue, 28 Sep 2021, Roger Sayle wrote:

> Next, I'd like to state that your "five restrictions" ontology is an 
> excellent starting point, but I'd like to argue that your proposed list 
> of 5 is the wrong shape (insufficiently refined). Instead, I'd like to 
> counter-propose that an improvement/refinement of the Myers model, is 
> actually "3 primitive restrictions * N trapping conditions * 2 flow 
> control sensitivity".

It's true you can treat the rules on what code transformations are 
permitted as orthogonal to which exceptions or sub-exceptions those are 
applied to.  (I'm not sure exact what you are including under "flow 
control sensitivity".)  And also that IEEE 754-2019 subclause 8.1 says 
that language standards should allow for alternate exception handling 
attributes to be associated with sets of exceptions or sub-exceptions (as 
well as being associated to particular blocks in the source code, as 
represented for C by the pragmas defined in TS 18661-5), which does tend 
to suggest such a model listing (sub-)exceptions separately for each rule 
on alternate exception handling.

Note that "trapping conditions" is not a good way of expressing things; 
the right way is much closer to "alternate exception handling" as defined 
in IEEE 754-2019 (or -2008), even if some of the more permissive modes 
(e.g. allowing spurious exceptions to be raised) don't actually correspond 
to any kind of alternate exception handling described in IEEE 754.  
Trapping, in the sense of transferring control to a trap handler 
(typically a SIGFPE signal handler) is, at least at the level of APIs for 
user code, an obsolescent form of exception handling: it was described in 
IEEE 754-1985 but removed in IEEE 754-2008, replaced by alternate 
exception handling.  Trapping and trap handlers are too machine-specific 
to form a good API for normal user code.  Some architectures may invoke a 
trap handler some time later than the instruction that signaled the 
exception.  Some may not support trapping on floating-point exceptions at 
all; support is optional on Arm and many processors don't implement it, 
trapping on floating-point exceptions isn't supported by RISC-V at all, 
for example.

So I think we should avoid reference to traps, when talking about 
floating-point exceptions, as much as possible, in the GCC documentation, 
command-line option names, source code and development discussion, except 
in limited cases where the specific legacy mechanism described in IEEE 
754-1985 is meant.  That doesn't make much difference to permitted 
optimizations; some forms of alternate exception handling would place 
similar restrictions on permitted code transformations to those 
restrictions coming from 1985-style trapping.

> Next your item [4] highlights what I consider the underlying problem that
> until now has been overlooked, that there are different kinds of traps are
> observationally/behaviourally different.  Above you describe, "underflow",
> but likewise there are traps for inexact result, "2.0 / 3.0", traps for
> division
> by 0.0, that invokes undefined behaviour in C++ (but sometimes not in C),
> and distinctions between quiet and signaling NaNs.  Your primitivie
> restrictions,
> [1], [2] and [5] may apply differently to these different kinds of
> exceptions.

As per the above, these aren't kinds of traps, but exceptions or 
sub-exceptions.

> Consider the following four lines of C++:
> constexpr t1 = 2.0 / 3.0;
> constexpr t2 = std::numeric_limits<double>::quiet_NaN() == 0.0;
> constexpr t2 = std::numeric_limits<double>::quiet_NaN() < 0.0;
> constexpr t3 = 1.0 / 0.0;
> which by IEEE generate four different types of exception, but as you've

t2 does not generate an exception; == is compareQuietEqual not 
compareSignalingEqual.

> Two very useful references I've been following are:
> https://docs.oracle.com/cd/E19957-01/806-3568/ncg_handle.html
> https://docs.oracle.com/cd/E88353_01/html/E37846/fex-getexcepthandler-3m.html

I don't think these are a good starting point; the TS 18661-5 APIs are a 
more appropriate basis for possible C bindings to alternate exception 
handling as described in IEEE 754-2008 or -2019, as opposed to 1985-style 
trapping or anything not based on 754-2008 or newer.

> numbers in match.pd, fold-const.c and simplify-rtx.c.  For example, what
> IEEE calls
> "FPE_INTOVF" is more commonly known as TRAPV inside GCC.  Likewise, IEEE

IEEE has no such name as FPE_INTOVF.

-ftrapv is itself an obsolescent feature.  Not because of any problems 
with its notion of trap, which is disjoint from that of floating-point 
exceptions (it's a synchronous call to abort or something equivalent), but 
because the implementation is problematic and an alias for certain 
sanitizer options is more maintainable.  We should be moving to that alias 
rather than adding any more internal representation related to -ftrapv.

> concepts such as FE_INVALID are really just groups of bits in our 
> enumeration, but we allow much finer control, for example, whether sqrt 
> of a negative number (other than -0.0) is considered a trap.

That's item (g), "squareRoot if the operand is less than zero", in 
subclause 7.2 of IEEE 754-2019.  TS 18661-5 gives it the name 
FE_INVALID_SQRT.  So we don't need to invent our own name for it.

> I'd prefer that GCC maintainers retain control/definition over the 
> semantics of this enumeration rather the a standards committee.  It is 
> for front-ends and libraries to map from their semantics, to the handles 
> provided by the middle-end.

Where languages want to use this granularity at all, I expect it will be 
for language bindings doing what IEEE 754-2019 specifies regarding 
alternate exception handling - including supporting lists of 
sub-exceptions as specified in IEEE 754-2019.  That means the 
classification in IEEE 754-2019 (given names in TS 18661-5) is the 
appropriate starting point.  That enumeration is sufficiently fine-grained 
it seems very unlikely it will be useful to subdivide it further.

It might be relevant to add *one* further enumeration element for those 
"invalid" exceptions that do not correspond to any of the listed cases 
(for example, sin(Inf) doesn't seem to fall into any of them, and, as per 
TS 18661-5, "Sub-exceptions corresponding to defined macros occur as 
specified below, and not in other cases." so it shouldn't be added to one 
of them by the implementation).

I don't think any enumeration element will need adding to distinguish 
exact and inexact underflow, simply because that's covered by one of the 
orthogonal pieces of data (what kind of alternate exception handling 
applies to the underflow exception - if we only care about flags, exact 
underflow is OK to ignore and OK to signal spuriously because it's not 
observable through flags; if we care about anything changing flow of 
control, or some other kinds of alternate exception handling such as 
abruptUnderflow, exact underflow does become of significance).

> Finally, I'll correct you that the reason why TRAPPING_MATH_INEXACT is not
> included in TRAPPING_MATH_DEFAULT is precisely to preserve the current 
> behaviour.  The expressions 2.0/3.0 and (float)1.12345678 are both folded by
> the middle-end and considered constexpr by g++; changing this would inhibit

Losing the inexact exception there is a bug, according to documented 
semantics of -ftrapping-math.  It's a specific case of failing to disallow 
local transformations that might cause code to signal fewer exceptions 
than it would have before.

Documented semantics apply equally to all exceptions.  We might choose to 
change some defaults (possibly just for inexact, possibly more generally 
allowing by default transformations that lose exceptions, possibly 
disabling -ftrapping-math by default), or to change the details of what 
-ftrapping-math does.  And we might choose, when fixing a bug about 
inexact, to decide that we need to change the defaults at that time.  But 
any such change should be separate from internal classification of 
(existing) transformations in GCC regarding what restrictions they obey 
for what exceptions or sub-exceptions.

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

Reply via email to