This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [Patch RFC] Modify excess precision logic to permit FLT_EVAL_METHOD=16
On Wed, 7 Sep 2016, Joseph Myers wrote:
> How about instead having more than one target macro / hook. One would
> indicate that excess precision is used by insn patterns (and be set only
> for i386 and m68k). Another would indicate the API-level excess precision
Or, maybe there would be a single hook taking a tristate argument.
Target hooks need to provide the following information:
(a) What excess precision is implicit in the insn patterns (that is, when
a value described in middle-end IR as having a particular mode/type may in
fact implicitly have extra range and precision because insn patterns
produce results with such extra range and precision, not just with the
range and precision of the output mode).
(b) What excess precision should be added explicitly to the IR by the
front end in "fast" mode.
(c) What excess precision should be added explicitly to the IR by the
front end in "standard" mode.
All of these may be represented by FLT_EVAL_METHOD values. In what
follows, "none" means no excess precision (whether the value is 0 or 16);
"unpredictable" means inherently unpredictable even in the absence of
register spills (like -mfpmath=sse+387), so FLT_EVAL_METHOD == -1. In
principle there could be cases of predictable excess precision that have
to map to -1 because there is no other value they could map to, but in
practice I don't expect that to be an issue (given the TS 18661-3 values
of FLT_EVAL_METHOD being available).
(a) should always be "none" except for the existing x86 and m68k cases.
(b) is "none" in all existing cases, but we have the issue of ARM cases
without direct binary16 arithmetic where it would be desirable for it to
apply excess precision to _Float16 values.
(c) is not "none" at present in exactly those cases where
TARGET_FLT_EVAL_METHOD is nonzero (but in the case of s390 this is really
a target bug that should be fixed). It might also be not "none" in future
for ARM cases like in (b).
(a) can be "unpredictable". (b) and (c) never can.
Rather than init_excess_precision setting flag_excess_precision, possibly
turning "standard" into "fast", I think it should set some variable that
describes the result of whichever of (b) and (c) is applicable - and in
the cases where "standard" turns into "fast", it would simply happen that
both (b) and (c) produce the same result.
The effective excess precision seen by the user is the result of applying
first one of (b) and (c), then (a). If (a) is not "none", this is not
entirely predictable. It's a broken compiler configuration if applying
(c) yields a type on which (a) is not a no-op, except in the case where
(a) is "unpredictable" and (c) is "none". I'm not aware of any likely
cases where a type would actually get promoted twice by applying those two
operations.
Right now TARGET_FLT_EVAL_METHOD_NON_DEFAULT is used to give errors for
-fexcess-precision=standard for languages not supporting it. With a
conversion to hooks, that needs to be rethought. The point is to give an
error if predictability was requested but cannot be achieved, so I suppose
ideally the error should be about (a) being not "none", together with
-fexcess-precision=standard being used. But if the relevant back-end
options aren't available at this point to use the hook for (a), the error
could just be given for all targets (for those languages when that option
is given).
Effective predictability, for __GCC_IEC_559 in flag_iso mode, means that
(a) does nothing to any type resulting from whichever of (b) and (c) is in
effect.
The way __LIBGCC_*_EXCESS_PRECISION__ is used is about eliminating excess
precision from results assigned to variables - meaning it should be about
(a) only.
That leaves the question of setting FLT_EVAL_METHOD. It should relate to
the effective excess precision seen by the user, the combination of
whichever of (b) and (c) is in effect with (a). The only problem is the
case where that combination is most precisely described by "16", which as
discussed is not a C11 value and may affect existing code not expecting
such a value. The value -1 is compatible with C11 and TS 18661-3 but
suboptimal, while the value 0 is compatible with C11 only, not with TS
18661-3 even when no feature test macros are defined.
We already have the option -fno-fp-int-builtin-inexact to ensure certain
built-in functions follow TS 18661-1 semantics. It might be reasonable to
have a new option to enable FLT_EVAL_METHOD using new values. However,
I'd be inclined to think that such an option should be on by default for
-std=gnu*, only off for strict conformance modes. (There would be both
__FLT_EVAL_METHOD__ and __FLT_EVAL_METHOD_C99__, say, predefined macros,
so that <float.h> could also always use the new value if
__STDC_WANT_IEC_60559_TYPES_EXT__ is defined.)
--
Joseph S. Myers
joseph@codesourcery.com