Re: [Patch 6/11] Migrate excess precision logic to use TARGET_EXCESS_PRECISION

2016-11-08 Thread Joseph Myers
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

2016-11-02 Thread James Greenhalgh

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

2016-10-28 Thread Joseph Myers
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

2016-10-14 Thread James Greenhalgh

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

2016-09-30 Thread Joseph Myers
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

2016-09-30 Thread James Greenhalgh

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);
+}
+
+/*