Re: [Patch 6/11] Migrate excess precision logic to use TARGET_EXCESS_PRECISION
On Wed, 2 Nov 2016, James Greenhalgh wrote: > OK, I've reworked the patch along those lines. I noticed that the original > logic looked for > > && TARGET_FLT_EVAL_METHOD != 0 > > And I no longer make that check. Is that something I need to reinstate? No, the replacement logic should imply that previously supported cases with TARGET_FLT_EVAL_METHOD == 0 will pass as being IEEE-compatible. > I didn't find any reference to excess precision in Annex F, so I'd guess > not? There are references, e.g. F.6 requiring that the return statement removes excess precision (but that's something done in the front end, nothing to do with this patch). > diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h > index 547bab2..507967d 100644 > --- a/gcc/c-family/c-common.h > +++ b/gcc/c-family/c-common.h > @@ -1314,6 +1314,8 @@ c_tree_chain_next (tree t) > #define TM_STMT_ATTR_ATOMIC 4 > #define TM_STMT_ATTR_RELAXED 8 > > +extern int parse_tm_stmt_attr (tree, int); > + > /* Mask used by tm_attr_to_mask and tm_mask_to_attr. Note that these > are ordered specifically such that more restrictive attributes are > at lower bit positions. This fact is known by the C++ tm attribute > @@ -1325,6 +1327,10 @@ c_tree_chain_next (tree t) > #define TM_ATTR_IRREVOCABLE 8 > #define TM_ATTR_MAY_CANCEL_OUTER 16 > > +extern int tm_attr_to_mask (tree); > +extern tree tm_mask_to_attr (int); > +extern tree find_tm_attribute (tree); > + > /* A suffix-identifier value doublet that represents user-defined literals > for C++-0x. */ > enum overflow_type { These changes to c-common.h are nothing to do with the subject of the patch. The patch is OK with those changes removed. If there are other changes in this series still needing review, please repost the whole series identifying what patches still need review. (I think the ARM _Float16 support still needs the testsuite changes to ensure that architecture-specific options to enable _FloatN / _FloatNx support are used when testing if the types are supported, so that the _Float16 tests are actually run in that case.) -- Joseph S. Myers jos...@codesourcery.com
Re: [Patch 6/11] Migrate excess precision logic to use TARGET_EXCESS_PRECISION
On Fri, Oct 28, 2016 at 09:09:55PM +, Joseph Myers wrote: > On Fri, 14 Oct 2016, James Greenhalgh wrote: > > > +/* If the join of the implicit precision in which the target will compute > > + floating-point values and the standard precision in which the target > > will > > + compute values is not equal to the standard precision, then the target > > + is either unpredictable, or is a broken configuration in which it claims > > + standards compliance, but doesn't honor that. > > + > > + Effective predictability for __GCC_IEC_559 in flag_iso_mode, means that > > + the implicit precision is not wider, or less predictable than the > > + standard precision. > > + > > + Return TRUE if we have been asked to compile with > > + -fexcess-precision=standard, and following the rules above we are able > > + to guarantee the standards mode. */ > > + > > I'm not convinced by the logic you have here. At least, it seems > different from what we have at present, where -std=c11 > -fexcess-precision=fast is not considered unpredictable if the target > doesn't have any implicit excess precision. > > That is: I think the right question is whether the combination (front-end > excess precision, implicit back-end excess precision) does the same thing > as just front-end excess precision, regardless of the -fexcess-precision= > option. OK, I've reworked the patch along those lines. I noticed that the original logic looked for && TARGET_FLT_EVAL_METHOD != 0 And I no longer make that check. Is that something I need to reinstate? I didn't find any reference to excess precision in Annex F, so I'd guess not? Thanks, James --- gcc/ 2016-11-02 James Greenhalgh* toplev.c (init_excess_precision): Delete most logic. * tree.c (excess_precision_type): Rewrite to use TARGET_EXCESS_PRECISION. * doc/invoke.texi (-fexcess-precision): Document behaviour in a more generic fashion. * ginclude/float.h: Wrap definition of FLT_EVAL_METHOD in __STDC_WANT_IEC_60559_TYPES_EXT__. gcc/c-family/ 2016-11-02 James Greenhalgh * c-common.c (excess_precision_mode_join): New. (c_ts18661_flt_eval_method): New. (c_c11_flt_eval_method): Likewise. (c_flt_eval_method): Likewise. * c-common.h (excess_precision_mode_join): New. (c_flt_eval_method): Likewise. * c-cppbuiltin.c (c_cpp_flt_eval_method_iec_559): New. (cpp_iec_559_value): Call it. (c_cpp_builtins): Modify logic for __LIBGCC_*_EXCESS_PRECISION__, call c_flt_eval_method to set __FLT_EVAL_METHOD__ and __FLT_EVAL_METHOD_TS_18661_3__. gcc/testsuite/ 2016-11-02 James Greenhalgh * gcc.dg/fpermitted-flt-eval-methods_3.c: New. * gcc.dg/fpermitted-flt-eval-methods_4.c: Likewise. diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c index 307862b..9f0b4a6 100644 --- a/gcc/c-family/c-common.c +++ b/gcc/c-family/c-common.c @@ -7944,4 +7944,86 @@ cb_get_suggestion (cpp_reader *, const char *goal, return bm.get_best_meaningful_candidate (); } +/* Return the latice point which is the wider of the two FLT_EVAL_METHOD + modes X, Y. This isn't just >, as the FLT_EVAL_METHOD values added + by C TS 18661-3 for interchange types that are computed in their + native precision are larger than the C11 values for evaluating in the + precision of float/double/long double. If either mode is + FLT_EVAL_METHOD_UNPREDICTABLE, return that. */ + +enum flt_eval_method +excess_precision_mode_join (enum flt_eval_method x, + enum flt_eval_method y) +{ + if (x == FLT_EVAL_METHOD_UNPREDICTABLE + || y == FLT_EVAL_METHOD_UNPREDICTABLE) +return FLT_EVAL_METHOD_UNPREDICTABLE; + + /* GCC only supports one interchange type right now, _Float16. If + we're evaluating _Float16 in 16-bit precision, then flt_eval_method + will be FLT_EVAL_METHOD_PROMOTE_TO_FLOAT16. */ + if (x == FLT_EVAL_METHOD_PROMOTE_TO_FLOAT16) +return y; + if (y == FLT_EVAL_METHOD_PROMOTE_TO_FLOAT16) +return x; + + /* Other values for flt_eval_method are directly comparable, and we want + the maximum. */ + return MAX (x, y); +} + +/* Return the value that should be set for FLT_EVAL_METHOD in the + context of ISO/IEC TS 18861-3. + + This relates to the effective excess precision seen by the user, + which is the join point of the precision the target requests for + -fexcess-precision={standard,fast} and the implicit excess precision + the target uses. */ + +static enum flt_eval_method +c_ts18661_flt_eval_method (void) +{ + enum flt_eval_method implicit += targetm.c.excess_precision (EXCESS_PRECISION_TYPE_IMPLICIT); + + enum excess_precision_type flag_type += (flag_excess_precision_cmdline == EXCESS_PRECISION_STANDARD + ? EXCESS_PRECISION_TYPE_STANDARD + : EXCESS_PRECISION_TYPE_FAST); + + enum
Re: [Patch 6/11] Migrate excess precision logic to use TARGET_EXCESS_PRECISION
On Fri, 14 Oct 2016, James Greenhalgh wrote: > +/* If the join of the implicit precision in which the target will compute > + floating-point values and the standard precision in which the target will > + compute values is not equal to the standard precision, then the target > + is either unpredictable, or is a broken configuration in which it claims > + standards compliance, but doesn't honor that. > + > + Effective predictability for __GCC_IEC_559 in flag_iso_mode, means that > + the implicit precision is not wider, or less predictable than the > + standard precision. > + > + Return TRUE if we have been asked to compile with > + -fexcess-precision=standard, and following the rules above we are able > + to guarantee the standards mode. */ > + > +static bool > +c_cpp_flt_eval_method_iec_559 (void) > +{ > + enum flt_eval_method implicit > += targetm.c.excess_precision (EXCESS_PRECISION_TYPE_IMPLICIT); > + enum flt_eval_method standard > += targetm.c.excess_precision (EXCESS_PRECISION_TYPE_STANDARD); > + > + return (excess_precision_mode_join (implicit, standard) == standard > + && flag_excess_precision_cmdline == EXCESS_PRECISION_STANDARD); > +} > + > /* Return the value for __GCC_IEC_559. */ > static int > cpp_iec_559_value (void) > @@ -775,11 +801,12 @@ cpp_iec_559_value (void) > applies to unpredictable contraction. For C++, and outside > strict conformance mode, do not consider these options to mean > lack of IEEE 754 support. */ > + >if (flag_iso >&& !c_dialect_cxx () > - && TARGET_FLT_EVAL_METHOD != 0 > - && flag_excess_precision_cmdline != EXCESS_PRECISION_STANDARD) > + && !c_cpp_flt_eval_method_iec_559 ()) > ret = 0; I'm not convinced by the logic you have here. At least, it seems different from what we have at present, where -std=c11 -fexcess-precision=fast is not considered unpredictable if the target doesn't have any implicit excess precision. That is: I think the right question is whether the combination (front-end excess precision, implicit back-end excess precision) does the same thing as just front-end excess precision, regardless of the -fexcess-precision= option. -- Joseph S. Myers jos...@codesourcery.com
Re: [Patch 6/11] Migrate excess precision logic to use TARGET_EXCESS_PRECISION
On Fri, Sep 30, 2016 at 05:32:01PM +, Joseph Myers wrote: > On Fri, 30 Sep 2016, James Greenhalgh wrote: > > >/* float.h needs to know this. */ > > + /* 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 could also always use the > > + new value if __STDC_WANT_IEC_60559_TYPES_EXT__ is defined.) */ > > This comment makes no sense in the context. The comment should not be > talking about some other option for a different issue, or about > half-thought-out ideas for how something might be implemented; comments > need to relate to the actual code (which in this case is obvious and not > in need of comments beyond saying what the macro semantics are). Yes, that was a particularly useless comment. Modified in this revision. > In any case, this patch does not achieve the proposed semantics, since > there is no change to ginclude/float.h. Ah, I thought float.h was outside the project. My mistake. > The goal is: if the user's options imply new FLT_EVAL_METHOD values are > OK, *or* they defined __STDC_WANT_IEC_60559_TYPES_EXT__ before including > , it should use the appropriate TS 18661-3 value. Otherwise > (strict standards modes for existing standards, no > __STDC_WANT_IEC_60559_TYPES_EXT__) it should use a C11 value. > > So in a strict standards mode you need to predefine macros with both > choices of values and let choose between them. One possibility > is: __FLT_EVAL_METHOD_C99__ is the value to use when > __STDC_WANT_IEC_60559_TYPES_EXT__ is not defined, __FLT_EVAL_METHOD__ is > the value to use when it is defined. Or some other arrangement, with or > without a macro saying what setting you have for the new option. But you > can't avoid changing . > > Tests then should be testing the value of FLT_EVAL_METHOD from , > *not* the internal macros predefined by the compiler. I've added tests testing the float.h behaviour in this patch, and I'll leave those testing __FLT_EVAL_METHOD__ in patch [5/11]. For all the difference the extra testing makes, I'd rather test both, as explicit testing that the clamping from -fpermitted-eval-methods works, and the value is correctly set in float.h, but I can certainly drop the tests in 5/11 if you'd prefer. I've also fixed a bug I noticed with the legacy __fp16 type. Excess precision should leave this alone, so we need to check with targetm.promoted_type before applying the rules in excess_precision_type. Thanks, James --- gcc/ 2016-10-14 James Greenhalgh* toplev.c (init_excess_precision): Delete most logic. * tree.c (excess_precision_type): Rewrite to use TARGET_EXCESS_PRECISION. * doc/invoke.texi (-fexcess-precision): Document behaviour in a more generic fashion. * ginclude/float.h: Wrap definition of FLT_EVAL_METHOD in __STDC_WANT_IEC_60559_TYPES_EXT__. gcc/c-family/ 2016-10-14 James Greenhalgh * c-common.c (excess_precision_mode_join): New. (c_ts18661_flt_eval_method): New. (c_c11_flt_eval_method): Likewise. (c_flt_eval_method): Likewise. * c-common.h (excess_precision_mode_join): New. (c_flt_eval_method): Likewise. * c-cppbuiltin.c (c_cpp_flt_eval_method_iec_559): New. (cpp_iec_559_value): Call it. (c_cpp_builtins): Modify logic for __LIBGCC_*_EXCESS_PRECISION__, call c_flt_eval_method to set __FLT_EVAL_METHOD__ and __FLT_EVAL_METHOD_TS_18661_3__. gcc/testsuite/ 2016-10-14 James Greenhalgh * gcc.dg/fpermitted-flt-eval-methods_3.c: New. * gcc.dg/fpermitted-flt-eval-methods_4.c: Likewise. diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c index c4a0ce8..2a4add5 100644 --- a/gcc/c-family/c-common.c +++ b/gcc/c-family/c-common.c @@ -11043,4 +11043,86 @@ cb_get_suggestion (cpp_reader *, const char *goal, return bm.get_best_meaningful_candidate (); } +/* Return the latice point which is the wider of the two FLT_EVAL_METHOD + modes X, Y. This isn't just >, as the FLT_EVAL_METHOD values added + by C TS 18661-3 for interchange types that are computed in their + native precision are larger than the C11 values for evaluating in the + precision of float/double/long double. If either mode is + FLT_EVAL_METHOD_UNPREDICTABLE, return that. */ + +enum flt_eval_method +excess_precision_mode_join (enum flt_eval_method x, + enum flt_eval_method y) +{ + if (x == FLT_EVAL_METHOD_UNPREDICTABLE + || y ==
Re: [Patch 6/11] Migrate excess precision logic to use TARGET_EXCESS_PRECISION
On Fri, 30 Sep 2016, James Greenhalgh wrote: >/* float.h needs to know this. */ > + /* 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 could also always use the > + new value if __STDC_WANT_IEC_60559_TYPES_EXT__ is defined.) */ This comment makes no sense in the context. The comment should not be talking about some other option for a different issue, or about half-thought-out ideas for how something might be implemented; comments need to relate to the actual code (which in this case is obvious and not in need of comments beyond saying what the macro semantics are). In any case, this patch does not achieve the proposed semantics, since there is no change to ginclude/float.h. The goal is: if the user's options imply new FLT_EVAL_METHOD values are OK, *or* they defined __STDC_WANT_IEC_60559_TYPES_EXT__ before including , it should use the appropriate TS 18661-3 value. Otherwise (strict standards modes for existing standards, no __STDC_WANT_IEC_60559_TYPES_EXT__) it should use a C11 value. So in a strict standards mode you need to predefine macros with both choices of values and let choose between them. One possibility is: __FLT_EVAL_METHOD_C99__ is the value to use when __STDC_WANT_IEC_60559_TYPES_EXT__ is not defined, __FLT_EVAL_METHOD__ is the value to use when it is defined. Or some other arrangement, with or without a macro saying what setting you have for the new option. But you can't avoid changing . Tests then should be testing the value of FLT_EVAL_METHOD from , *not* the internal macros predefined by the compiler. -- Joseph S. Myers jos...@codesourcery.com
[Patch 6/11] Migrate excess precision logic to use TARGET_EXCESS_PRECISION
Hi, This patch moves the logic for excess precision from using the TARGET_FLT_EVAL_METHOD macro to the TARGET_EXCESS_PRECISION hook introduced earlier in the patch series. These logic changes follow Joseph's comments at https://gcc.gnu.org/ml/gcc-patches/2016-09/msg00410.html Briefly; we have four things to change. 1) The logic in tree.c::excess_precision_type . Here we want to ask the target which excess preicion it would like for whichever of -fexcess-precision=standard or -fexcess-precision=fast is in use, then apply that. 2) The logic in c-family/c-cppbuiltin.c::c_cpp_flt_eval_method_iec_559 . We want to update this to ensure that the target claims the same excess precision to be implicitly added to operations that it reports in -fexcess-precision=standard mode. We take the join of these two reported values, and only if the join is equal to the excess precision requested for -fexcess-precision=standard can we set the IEC_559 macro. 3) The logic in c-family/c-cppbuiltin.c::c_cpp_builtin for setting __FLT_EVAL_METHOD__ . Which is now little more complicated, and makes use of -fpermitted-flt-eval-methods from patch 5. 4) The logic in c-family/c-cppbuiltin.c::c_cpp_builtin for setting __LIBGCC_*_EXCESS_PRECISION__ . This can just be the implicit precision reported by the target. Having moved the logic in to those areas, we can simplify toplev.c::init_excess_precision , which now only retains the assert that -fexcess-precision=default has been rewritten by the language front-end, and the set from the command-line variable to the internal variable. The documentation in invoke.texi is not quite right for the impact of -fexcess-precision, so I've rewritten the text to read a little more generic. Bootstrapped on x86_64 and aarch64 with no issues. Thanks, James --- gcc/ 2016-09-30 James Greenhalgh* toplev.c (init_excess_precision): Delete most logic. * tree.c (excess_precision_type): Rewrite to use TARGET_EXCESS_PRECISION. * doc/invoke.texi (-fexcess-precision): Document behaviour in a more generic fashion. gcc/c-family/ 2016-09-30 James Greenhalgh * c-common.c (excess_precision_mode_join): New. (c_ts18661_flt_eval_method): New. (c_c11_flt_eval_method): Likewise. (c_flt_eval_method): Likewise. * c-common.h (excess_precision_mode_join): New. (c_flt_eval_method): Likewise. * c-cppbuiltin.c (c_cpp_flt_eval_method_iec_559): New. (cpp_iec_559_value): Call it. (c_cpp_builtins): Modify logic for __LIBGCC_*_EXCESS_PRECISION__, call c_flt_eval_method to set __FLT_EVAL_METHOD__ and __FLT_EVAL_METHOD_C99__. diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c index 2652259..983f71a 100644 --- a/gcc/c-family/c-common.c +++ b/gcc/c-family/c-common.c @@ -13145,4 +13145,83 @@ diagnose_mismatched_attributes (tree olddecl, tree newdecl) return warned; } +/* Return the latice point which is the wider of the two FLT_EVAL_METHOD + modes X, Y. This isn't just >, as the FLT_EVAL_METHOD values added + by C TS 18661-3 for interchange types that are computed in their + native precision are larger than the C11 values for evaluating in the + precision of float/double/long double. If either mode is + FLT_EVAL_METHOD_UNPREDICTABLE, return that. */ + +enum flt_eval_method +excess_precision_mode_join (enum flt_eval_method x, + enum flt_eval_method y) +{ + if (x == FLT_EVAL_METHOD_UNPREDICTABLE + || y == FLT_EVAL_METHOD_UNPREDICTABLE) +return FLT_EVAL_METHOD_UNPREDICTABLE; + + /* GCC only supports one interchange type right now, _Float16. If + we're evaluating _Float16 in 16-bit precision, then flt_eval_method + will be FLT_EVAL_METHOD_PROMOTE_TO_FLOAT16. */ + if (x == FLT_EVAL_METHOD_PROMOTE_TO_FLOAT16) +return y; + if (y == FLT_EVAL_METHOD_PROMOTE_TO_FLOAT16) +return x; + + /* Other values for flt_eval_method are directly comparable, and we want + the maximum. */ + return MAX (x, y); +} + +/* Return the value that should be set for FLT_EVAL_METHOD in the + context of ISO/IEC TS 18861-3. + + This should relate to the effective excess precision seen by the user, + which is the join point of the precision the target requests for + -fexcess-precision={standard,fast} and the implicit excess precision + the target uses. */ + +static enum flt_eval_method +c_ts18661_flt_eval_method (void) +{ + enum flt_eval_method implicit += targetm.c.excess_precision (EXCESS_PRECISION_TYPE_IMPLICIT); + + enum excess_precision_type flag_type += (flag_excess_precision_cmdline == EXCESS_PRECISION_STANDARD + ? EXCESS_PRECISION_TYPE_STANDARD + : EXCESS_PRECISION_TYPE_FAST); + + enum flt_eval_method requested += targetm.c.excess_precision (flag_type); + + return excess_precision_mode_join (implicit, requested); +} + +/*