Support -fexcess-precision=16 which will enable FLT_EVAL_METHOD_PROMOTE_TO_FLOAT16 when backend supports _Float16.

gcc/ada/ChangeLog:

	* gcc-interface/misc.c (gnat_post_options): Issue an error for
	-fexcess-precision=16.

gcc/c-family/ChangeLog:

	* c-common.c (excess_precision_mode_join): Update below comments.
	(c_ts18661_flt_eval_method): Set excess_precision_type to
	EXCESS_PRECISION_TYPE_FLOAT16 when -fexcess-precision=16.
	* c-cppbuiltin.c (cpp_atomic_builtins): Update below comments.
	(c_cpp_flt_eval_method_iec_559): Set excess_precision_type to
	EXCESS_PRECISION_TYPE_FLOAT16 when -fexcess-precision=16.

gcc/ChangeLog:

	* common.opt: Support -fexcess-precision=16.
	* config/aarch64/aarch64.c (aarch64_excess_precision): Return
	FLT_EVAL_METHOD_PROMOTE_TO_FLOAT16 when
	EXCESS_PRECISION_TYPE_FLOAT16.
	* config/arm/arm.c (arm_excess_precision): Ditto.
	* config/i386/i386.c (ix86_get_excess_precision): Ditto.
	* config/m68k/m68k.c (m68k_excess_precision): Issue an error
	when EXCESS_PRECISION_TYPE_FLOAT16.
	* config/s390/s390.c (s390_excess_precision): Ditto.
	* coretypes.h (enum excess_precision_type): Add
	EXCESS_PRECISION_TYPE_FLOAT16.
	* doc/tm.texi (TARGET_C_EXCESS_PRECISION): Update documents.
	* doc/tm.texi.in (TARGET_C_EXCESS_PRECISION): Ditto.
	* doc/extend.texi (Half-Precision): Document
	-fexcess-precision=16.
	* flag-types.h (enum excess_precision): Add
	EXCESS_PRECISION_FLOAT16.
	* target.def (excess_precision): Update document.
	* tree.c (excess_precision_type): Set excess_precision_type to
	EXCESS_PRECISION_FLOAT16 when -fexcess-precision=16.

gcc/fortran/ChangeLog:

	* options.c (gfc_post_options): Issue an error for
	-fexcess-precision=16.

gcc/testsuite/ChangeLog:

	* gcc.target/i386/float16-6.c: New test.
	* gcc.target/i386/float16-7.c: New test.
This commit is contained in:
liuhongt 2021-08-02 10:56:45 +08:00
parent a549a9a39a
commit f19a327077
19 changed files with 76 additions and 17 deletions

View File

@ -256,6 +256,9 @@ gnat_post_options (const char **pfilename ATTRIBUTE_UNUSED)
/* Excess precision other than "fast" requires front-end support. */ /* Excess precision other than "fast" requires front-end support. */
if (flag_excess_precision == EXCESS_PRECISION_STANDARD) if (flag_excess_precision == EXCESS_PRECISION_STANDARD)
sorry ("%<-fexcess-precision=standard%> for Ada"); sorry ("%<-fexcess-precision=standard%> for Ada");
else if (flag_excess_precision == EXCESS_PRECISION_FLOAT16)
sorry ("%<-fexcess-precision=16%> for Ada");
flag_excess_precision = EXCESS_PRECISION_FAST; flag_excess_precision = EXCESS_PRECISION_FAST;
/* No psABI change warnings for Ada. */ /* No psABI change warnings for Ada. */

View File

@ -8778,7 +8778,7 @@ excess_precision_mode_join (enum flt_eval_method x,
This relates to the effective excess precision seen by the user, This relates to the effective excess precision seen by the user,
which is the join point of the precision the target requests for which is the join point of the precision the target requests for
-fexcess-precision={standard,fast} and the implicit excess precision -fexcess-precision={standard,fast,16} and the implicit excess precision
the target uses. */ the target uses. */
static enum flt_eval_method static enum flt_eval_method
@ -8790,7 +8790,9 @@ c_ts18661_flt_eval_method (void)
enum excess_precision_type flag_type enum excess_precision_type flag_type
= (flag_excess_precision == EXCESS_PRECISION_STANDARD = (flag_excess_precision == EXCESS_PRECISION_STANDARD
? EXCESS_PRECISION_TYPE_STANDARD ? EXCESS_PRECISION_TYPE_STANDARD
: EXCESS_PRECISION_TYPE_FAST); : (flag_excess_precision == EXCESS_PRECISION_FLOAT16
? EXCESS_PRECISION_TYPE_FLOAT16
: EXCESS_PRECISION_TYPE_FAST));
enum flt_eval_method requested enum flt_eval_method requested
= targetm.c.excess_precision (flag_type); = targetm.c.excess_precision (flag_type);

View File

@ -753,7 +753,7 @@ cpp_atomic_builtins (cpp_reader *pfile)
/* Return TRUE if the implicit excess precision in which the back-end will /* Return TRUE if the implicit excess precision in which the back-end will
compute floating-point calculations is not more than the explicit compute floating-point calculations is not more than the explicit
excess precision that the front-end will apply under excess precision that the front-end will apply under
-fexcess-precision=[standard|fast]. -fexcess-precision=[standard|fast|16].
More intuitively, return TRUE if the excess precision proposed by the More intuitively, return TRUE if the excess precision proposed by the
front-end is the excess precision that will actually be used. */ front-end is the excess precision that will actually be used. */
@ -764,7 +764,9 @@ c_cpp_flt_eval_method_iec_559 (void)
enum excess_precision_type front_end_ept enum excess_precision_type front_end_ept
= (flag_excess_precision == EXCESS_PRECISION_STANDARD = (flag_excess_precision == EXCESS_PRECISION_STANDARD
? EXCESS_PRECISION_TYPE_STANDARD ? EXCESS_PRECISION_TYPE_STANDARD
: EXCESS_PRECISION_TYPE_FAST); : (flag_excess_precision == EXCESS_PRECISION_FLOAT16
? EXCESS_PRECISION_TYPE_FLOAT16
: EXCESS_PRECISION_TYPE_FAST));
enum flt_eval_method back_end enum flt_eval_method back_end
= targetm.c.excess_precision (EXCESS_PRECISION_TYPE_IMPLICIT); = targetm.c.excess_precision (EXCESS_PRECISION_TYPE_IMPLICIT);

View File

@ -1518,7 +1518,7 @@ Perform a number of minor, expensive optimizations.
fexcess-precision= fexcess-precision=
Common Joined RejectNegative Enum(excess_precision) Var(flag_excess_precision) Init(EXCESS_PRECISION_DEFAULT) Optimization SetByCombined Common Joined RejectNegative Enum(excess_precision) Var(flag_excess_precision) Init(EXCESS_PRECISION_DEFAULT) Optimization SetByCombined
-fexcess-precision=[fast|standard] Specify handling of excess floating-point precision. -fexcess-precision=[fast|standard|16] Specify handling of excess floating-point precision.
Enum Enum
Name(excess_precision) Type(enum excess_precision) UnknownError(unknown excess precision style %qs) Name(excess_precision) Type(enum excess_precision) UnknownError(unknown excess precision style %qs)
@ -1529,6 +1529,9 @@ Enum(excess_precision) String(fast) Value(EXCESS_PRECISION_FAST)
EnumValue EnumValue
Enum(excess_precision) String(standard) Value(EXCESS_PRECISION_STANDARD) Enum(excess_precision) String(standard) Value(EXCESS_PRECISION_STANDARD)
EnumValue
Enum(excess_precision) String(16) Value(EXCESS_PRECISION_FLOAT16)
; Whether we permit the extended set of values for FLT_EVAL_METHOD ; Whether we permit the extended set of values for FLT_EVAL_METHOD
; introduced in ISO/IEC TS 18661-3, or limit ourselves to those in C99/C11. ; introduced in ISO/IEC TS 18661-3, or limit ourselves to those in C99/C11.
fpermitted-flt-eval-methods= fpermitted-flt-eval-methods=

View File

@ -25045,6 +25045,7 @@ aarch64_excess_precision (enum excess_precision_type type)
? FLT_EVAL_METHOD_PROMOTE_TO_FLOAT16 ? FLT_EVAL_METHOD_PROMOTE_TO_FLOAT16
: FLT_EVAL_METHOD_PROMOTE_TO_FLOAT); : FLT_EVAL_METHOD_PROMOTE_TO_FLOAT);
case EXCESS_PRECISION_TYPE_IMPLICIT: case EXCESS_PRECISION_TYPE_IMPLICIT:
case EXCESS_PRECISION_TYPE_FLOAT16:
return FLT_EVAL_METHOD_PROMOTE_TO_FLOAT16; return FLT_EVAL_METHOD_PROMOTE_TO_FLOAT16;
default: default:
gcc_unreachable (); gcc_unreachable ();

View File

@ -25612,6 +25612,7 @@ arm_excess_precision (enum excess_precision_type type)
? FLT_EVAL_METHOD_PROMOTE_TO_FLOAT16 ? FLT_EVAL_METHOD_PROMOTE_TO_FLOAT16
: FLT_EVAL_METHOD_PROMOTE_TO_FLOAT); : FLT_EVAL_METHOD_PROMOTE_TO_FLOAT);
case EXCESS_PRECISION_TYPE_IMPLICIT: case EXCESS_PRECISION_TYPE_IMPLICIT:
case EXCESS_PRECISION_TYPE_FLOAT16:
return FLT_EVAL_METHOD_PROMOTE_TO_FLOAT16; return FLT_EVAL_METHOD_PROMOTE_TO_FLOAT16;
default: default:
gcc_unreachable (); gcc_unreachable ();

View File

@ -23599,6 +23599,11 @@ ix86_get_excess_precision (enum excess_precision_type type)
return (type == EXCESS_PRECISION_TYPE_STANDARD return (type == EXCESS_PRECISION_TYPE_STANDARD
? FLT_EVAL_METHOD_PROMOTE_TO_FLOAT ? FLT_EVAL_METHOD_PROMOTE_TO_FLOAT
: FLT_EVAL_METHOD_UNPREDICTABLE); : FLT_EVAL_METHOD_UNPREDICTABLE);
case EXCESS_PRECISION_TYPE_FLOAT16:
if (TARGET_80387
&& !(TARGET_SSE_MATH && TARGET_SSE))
error ("%<-fexcess-precision=16%> is not compatible with %<-mfpmath=387%>");
return FLT_EVAL_METHOD_PROMOTE_TO_FLOAT16;
default: default:
gcc_unreachable (); gcc_unreachable ();
} }

View File

@ -7115,6 +7115,9 @@ m68k_excess_precision (enum excess_precision_type type)
return FLT_EVAL_METHOD_PROMOTE_TO_FLOAT; return FLT_EVAL_METHOD_PROMOTE_TO_FLOAT;
return FLT_EVAL_METHOD_PROMOTE_TO_LONG_DOUBLE; return FLT_EVAL_METHOD_PROMOTE_TO_LONG_DOUBLE;
case EXCESS_PRECISION_TYPE_FLOAT16:
error ("%<-fexcess-precision=16%> is not supported on this target");
break;
default: default:
gcc_unreachable (); gcc_unreachable ();
} }

View File

@ -16549,6 +16549,9 @@ s390_excess_precision (enum excess_precision_type type)
ensure consistency with the implementation in glibc, report that ensure consistency with the implementation in glibc, report that
float is evaluated to the range and precision of double. */ float is evaluated to the range and precision of double. */
return FLT_EVAL_METHOD_PROMOTE_TO_DOUBLE; return FLT_EVAL_METHOD_PROMOTE_TO_DOUBLE;
case EXCESS_PRECISION_TYPE_FLOAT16:
error ("%<-fexcess-precision=16%> is not supported on this target");
break;
default: default:
gcc_unreachable (); gcc_unreachable ();
} }

View File

@ -425,7 +425,8 @@ enum excess_precision_type
{ {
EXCESS_PRECISION_TYPE_IMPLICIT, EXCESS_PRECISION_TYPE_IMPLICIT,
EXCESS_PRECISION_TYPE_STANDARD, EXCESS_PRECISION_TYPE_STANDARD,
EXCESS_PRECISION_TYPE_FAST EXCESS_PRECISION_TYPE_FAST,
EXCESS_PRECISION_TYPE_FLOAT16
}; };
/* Level of size optimization. */ /* Level of size optimization. */

View File

@ -1160,7 +1160,8 @@ On x86 targets with SSE2 enabled, without @option{-mavx512fp16},
software emulation and the @code{float} instructions. The default behavior software emulation and the @code{float} instructions. The default behavior
for @code{FLT_EVAL_METHOD} is to keep the intermediate result of the operation for @code{FLT_EVAL_METHOD} is to keep the intermediate result of the operation
as 32-bit precision. This may lead to inconsistent behavior between software as 32-bit precision. This may lead to inconsistent behavior between software
emulation and AVX512-FP16 instructions. emulation and AVX512-FP16 instructions. Using @option{-fexcess-precision=16}
will force round back after each operation.
@node Decimal Float @node Decimal Float
@section Decimal Floating Types @section Decimal Floating Types

View File

@ -982,20 +982,26 @@ Do not define this macro if it would never modify @var{m}.
Return a value, with the same meaning as the C99 macro Return a value, with the same meaning as the C99 macro
@code{FLT_EVAL_METHOD} that describes which excess precision should be @code{FLT_EVAL_METHOD} that describes which excess precision should be
applied. @var{type} is either @code{EXCESS_PRECISION_TYPE_IMPLICIT}, applied. @var{type} is either @code{EXCESS_PRECISION_TYPE_IMPLICIT},
@code{EXCESS_PRECISION_TYPE_FAST}, or @code{EXCESS_PRECISION_TYPE_FAST},
@code{EXCESS_PRECISION_TYPE_STANDARD}. For @code{EXCESS_PRECISION_TYPE_STANDARD}, or
@code{EXCESS_PRECISION_TYPE_FLOAT16}. For
@code{EXCESS_PRECISION_TYPE_IMPLICIT}, the target should return which @code{EXCESS_PRECISION_TYPE_IMPLICIT}, the target should return which
precision and range operations will be implictly evaluated in regardless precision and range operations will be implictly evaluated in regardless
of the excess precision explicitly added. For of the excess precision explicitly added. For
@code{EXCESS_PRECISION_TYPE_STANDARD} and @code{EXCESS_PRECISION_TYPE_STANDARD},
@code{EXCESS_PRECISION_TYPE_FLOAT16}, and
@code{EXCESS_PRECISION_TYPE_FAST}, the target should return the @code{EXCESS_PRECISION_TYPE_FAST}, the target should return the
explicit excess precision that should be added depending on the explicit excess precision that should be added depending on the
value set for @option{-fexcess-precision=@r{[}standard@r{|}fast@r{]}}. value set for @option{-fexcess-precision=@r{[}standard@r{|}fast@r{]}}.
Note that unpredictable explicit excess precision does not make sense, Note that unpredictable explicit excess precision does not make sense,
so a target should never return @code{FLT_EVAL_METHOD_UNPREDICTABLE} so a target should never return @code{FLT_EVAL_METHOD_UNPREDICTABLE}
when @var{type} is @code{EXCESS_PRECISION_TYPE_STANDARD} or when @var{type} is @code{EXCESS_PRECISION_TYPE_STANDARD},
@code{EXCESS_PRECISION_TYPE_FLOAT16} or
@code{EXCESS_PRECISION_TYPE_FAST}. @code{EXCESS_PRECISION_TYPE_FAST}.
@end deftypefn @end deftypefn
Return a value, with the same meaning as the C99 macro
@code{FLT_EVAL_METHOD} that describes which excess precision should be
applied.
@deftypefn {Target Hook} machine_mode TARGET_PROMOTE_FUNCTION_MODE (const_tree @var{type}, machine_mode @var{mode}, int *@var{punsignedp}, const_tree @var{funtype}, int @var{for_return}) @deftypefn {Target Hook} machine_mode TARGET_PROMOTE_FUNCTION_MODE (const_tree @var{type}, machine_mode @var{mode}, int *@var{punsignedp}, const_tree @var{funtype}, int @var{for_return})
Like @code{PROMOTE_MODE}, but it is applied to outgoing function arguments or Like @code{PROMOTE_MODE}, but it is applied to outgoing function arguments or

View File

@ -929,6 +929,9 @@ Do not define this macro if it would never modify @var{m}.
@end defmac @end defmac
@hook TARGET_C_EXCESS_PRECISION @hook TARGET_C_EXCESS_PRECISION
Return a value, with the same meaning as the C99 macro
@code{FLT_EVAL_METHOD} that describes which excess precision should be
applied.
@hook TARGET_PROMOTE_FUNCTION_MODE @hook TARGET_PROMOTE_FUNCTION_MODE

View File

@ -202,7 +202,8 @@ enum excess_precision
{ {
EXCESS_PRECISION_DEFAULT, EXCESS_PRECISION_DEFAULT,
EXCESS_PRECISION_FAST, EXCESS_PRECISION_FAST,
EXCESS_PRECISION_STANDARD EXCESS_PRECISION_STANDARD,
EXCESS_PRECISION_FLOAT16
}; };
/* The options for which values of FLT_EVAL_METHOD are permissible. */ /* The options for which values of FLT_EVAL_METHOD are permissible. */

View File

@ -267,6 +267,9 @@ gfc_post_options (const char **pfilename)
support. */ support. */
if (flag_excess_precision == EXCESS_PRECISION_STANDARD) if (flag_excess_precision == EXCESS_PRECISION_STANDARD)
sorry ("%<-fexcess-precision=standard%> for Fortran"); sorry ("%<-fexcess-precision=standard%> for Fortran");
else if (flag_excess_precision == EXCESS_PRECISION_FLOAT16)
sorry ("%<-fexcess-precision=16%> for Fortran");
flag_excess_precision = EXCESS_PRECISION_FAST; flag_excess_precision = EXCESS_PRECISION_FAST;
/* Fortran allows associative math - but we cannot reassociate if /* Fortran allows associative math - but we cannot reassociate if

View File

@ -6225,18 +6225,21 @@ DEFHOOK
"Return a value, with the same meaning as the C99 macro\n\ "Return a value, with the same meaning as the C99 macro\n\
@code{FLT_EVAL_METHOD} that describes which excess precision should be\n\ @code{FLT_EVAL_METHOD} that describes which excess precision should be\n\
applied. @var{type} is either @code{EXCESS_PRECISION_TYPE_IMPLICIT},\n\ applied. @var{type} is either @code{EXCESS_PRECISION_TYPE_IMPLICIT},\n\
@code{EXCESS_PRECISION_TYPE_FAST}, or\n\ @code{EXCESS_PRECISION_TYPE_FAST},\n\
@code{EXCESS_PRECISION_TYPE_STANDARD}. For\n\ @code{EXCESS_PRECISION_TYPE_STANDARD}, or\n\
@code{EXCESS_PRECISION_TYPE_FLOAT16}. For\n\
@code{EXCESS_PRECISION_TYPE_IMPLICIT}, the target should return which\n\ @code{EXCESS_PRECISION_TYPE_IMPLICIT}, the target should return which\n\
precision and range operations will be implictly evaluated in regardless\n\ precision and range operations will be implictly evaluated in regardless\n\
of the excess precision explicitly added. For\n\ of the excess precision explicitly added. For\n\
@code{EXCESS_PRECISION_TYPE_STANDARD} and\n\ @code{EXCESS_PRECISION_TYPE_STANDARD}, \n\
@code{EXCESS_PRECISION_TYPE_FLOAT16}, and\n\
@code{EXCESS_PRECISION_TYPE_FAST}, the target should return the\n\ @code{EXCESS_PRECISION_TYPE_FAST}, the target should return the\n\
explicit excess precision that should be added depending on the\n\ explicit excess precision that should be added depending on the\n\
value set for @option{-fexcess-precision=@r{[}standard@r{|}fast@r{]}}.\n\ value set for @option{-fexcess-precision=@r{[}standard@r{|}fast@r{]}}.\n\
Note that unpredictable explicit excess precision does not make sense,\n\ Note that unpredictable explicit excess precision does not make sense,\n\
so a target should never return @code{FLT_EVAL_METHOD_UNPREDICTABLE}\n\ so a target should never return @code{FLT_EVAL_METHOD_UNPREDICTABLE}\n\
when @var{type} is @code{EXCESS_PRECISION_TYPE_STANDARD} or\n\ when @var{type} is @code{EXCESS_PRECISION_TYPE_STANDARD},\n\
@code{EXCESS_PRECISION_TYPE_FLOAT16} or\n\
@code{EXCESS_PRECISION_TYPE_FAST}.", @code{EXCESS_PRECISION_TYPE_FAST}.",
enum flt_eval_method, (enum excess_precision_type type), enum flt_eval_method, (enum excess_precision_type type),
default_excess_precision) default_excess_precision)

View File

@ -0,0 +1,8 @@
/* { dg-do compile } */
/* { dg-options "-msse2 -O2 -mfpmath=sse -fdump-tree-gimple -fexcess-precision=16" } */
/* { dg-final { scan-tree-dump-not "\\(float\\)" "gimple" } } */
_Float16
foo (_Float16 a, _Float16 b, _Float16 c)
{
return a + b + c;
}

View File

@ -0,0 +1,9 @@
/* { dg-do compile } */
/* { dg-options "-O2 -mfpmath=387 -fexcess-precision=16" } */
/* { dg-excess-errors "'-fexcess-precision=16' is not compatible with '-mfpmath=387'" } */
_Float16
foo (_Float16 a, _Float16 b)
{
return a + b;/* { dg-error "'-fexcess-precision=16' is not compatible with '-mfpmath=387'" } */
}

View File

@ -7637,7 +7637,8 @@ excess_precision_type (tree type)
enum excess_precision_type requested_type enum excess_precision_type requested_type
= (flag_excess_precision == EXCESS_PRECISION_FAST = (flag_excess_precision == EXCESS_PRECISION_FAST
? EXCESS_PRECISION_TYPE_FAST ? EXCESS_PRECISION_TYPE_FAST
: EXCESS_PRECISION_TYPE_STANDARD); : (flag_excess_precision == EXCESS_PRECISION_FLOAT16
? EXCESS_PRECISION_TYPE_FLOAT16 :EXCESS_PRECISION_TYPE_STANDARD));
enum flt_eval_method target_flt_eval_method enum flt_eval_method target_flt_eval_method
= targetm.c.excess_precision (requested_type); = targetm.c.excess_precision (requested_type);