--- This patch was approved here: https://gcc.gnu.org/ml/gcc-patches/2016-09/msg02405.html
Joseph had a comment in https://gcc.gnu.org/ml/gcc-patches/2016-10/msg00335.html that the tests should check FLT_EVAL_METHOD from <float.h> rather than __FLT_EVAL_METHOD__. Rather than implement that suggestion, I added tests to patch 6 which tested the <float.h> macro, and left the tests in this patch testing the internal macro. --- Hi, This option is added to control which values of FLT_EVAL_METHOD the compiler is allowed to set. ISO/IEC TS 18661-3 defines new permissible values for FLT_EVAL_METHOD that indicate that operations and constants with a semantic type that is an interchange or extended format should be evaluated to the precision and range of that type. These new values are a superset of those permitted under C99/C11, which does not specify the meaning of other positive values of FLT_EVAL_METHOD. As such, code conforming to C11 may not have been written expecting the possibility of the new values. -fpermitted-flt-eval-methods specifies whether the compiler should allow only the values of FLT_EVAL_METHOD specified in C99/C11, or the extended set of values specified in ISO/IEC TS 18661-3. The two possible values this option can take are "c11" or "ts-18661-3". The default when in a standards compliant mode (-std=c11 or similar) is -fpermitted-flt-eval-methods=c11. The default when in a GNU dialect (-std=gnu11 or similar) is -fpermitted-flt-eval-methods=ts-18661-3. I've added two testcases which test that when this option, or a C standards dialect, would restrict the range of values to {-1, 0, 1, 2}, those are the only values we see. At this stage in the patch series this trivially holds for all targets. Bootstrapped on x86_64 with no issues. Thanks, James --- gcc/c-family/ 2016-11-09 James Greenhalgh <james.greenha...@arm.com> * c-opts.c (c_common_post_options): Add logic to handle the default case for -fpermitted-flt-eval-methods. gcc/ 2016-11-09 James Greenhalgh <james.greenha...@arm.com> * common.opt (fpermitted-flt-eval-methods): New. * doc/invoke.texi (-fpermitted-flt-eval-methods): Document it. * flag_types.h (permitted_flt_eval_methods): New. gcc/testsuite/ 2016-11-09 James Greenhalgh <james.greenha...@arm.com> * gcc.dg/fpermitted-flt-eval-methods_1.c: New. * gcc.dg/fpermitted-flt-eval-methods_2.c: New.
diff --git a/gcc/c-family/c-opts.c b/gcc/c-family/c-opts.c index de260e7..57717ff 100644 --- a/gcc/c-family/c-opts.c +++ b/gcc/c-family/c-opts.c @@ -788,6 +788,18 @@ c_common_post_options (const char **pfilename) && flag_unsafe_math_optimizations == 0) flag_fp_contract_mode = FP_CONTRACT_OFF; + /* If we are compiling C, and we are outside of a standards mode, + we can permit the new values from ISO/IEC TS 18661-3 for + FLT_EVAL_METHOD. Otherwise, we must restrict the possible values to + the set specified in ISO C99/C11. */ + if (!flag_iso + && !c_dialect_cxx () + && (global_options_set.x_flag_permitted_flt_eval_methods + == PERMITTED_FLT_EVAL_METHODS_DEFAULT)) + flag_permitted_flt_eval_methods = PERMITTED_FLT_EVAL_METHODS_TS_18661; + else + flag_permitted_flt_eval_methods = PERMITTED_FLT_EVAL_METHODS_C11; + /* By default we use C99 inline semantics in GNU99 or C99 mode. C99 inline semantics are not supported in GNU89 or C89 mode. */ if (flag_gnu89_inline == -1) diff --git a/gcc/common.opt b/gcc/common.opt index 314145a..915c406 100644 --- a/gcc/common.opt +++ b/gcc/common.opt @@ -1326,6 +1326,21 @@ Enum(excess_precision) String(fast) Value(EXCESS_PRECISION_FAST) EnumValue Enum(excess_precision) String(standard) Value(EXCESS_PRECISION_STANDARD) +; 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. +fpermitted-flt-eval-methods= +Common Joined RejectNegative Enum(permitted_flt_eval_methods) Var(flag_permitted_flt_eval_methods) Init(PERMITTED_FLT_EVAL_METHODS_DEFAULT) +-fpermitted-flt-eval-methods=[c11|ts-18661] Specify which values of FLT_EVAL_METHOD are permitted. + +Enum +Name(permitted_flt_eval_methods) Type(enum permitted_flt_eval_methods) UnknownError(unknown specification for the set of FLT_EVAL_METHOD values to permit %qs) + +EnumValue +Enum(permitted_flt_eval_methods) String(c11) Value(PERMITTED_FLT_EVAL_METHODS_C11) + +EnumValue +Enum(permitted_flt_eval_methods) String(ts-18661-3) Value(PERMITTED_FLT_EVAL_METHODS_TS_18661) + ffast-math Common Optimization diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index f133b3a..75ff8ec 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -378,7 +378,8 @@ Objective-C and Objective-C++ Dialects}. -flto-partition=@var{alg} -fmerge-all-constants @gol -fmerge-constants -fmodulo-sched -fmodulo-sched-allow-regmoves @gol -fmove-loop-invariants -fno-branch-count-reg @gol --fno-defer-pop -fno-fp-int-builtin-inexact -fno-function-cse @gol +-fno-defer-pop -fno-fp-int-builtin-inexact @gol +-fpermitted-flt-eval-methods=@var{standard} -fno-function-cse @gol -fno-guess-branch-probability -fno-inline -fno-math-errno -fno-peephole @gol -fno-peephole2 -fno-sched-interblock -fno-sched-spec -fno-signed-zeros @gol -fno-toplevel-reorder -fno-trapping-math -fno-zero-initialized-in-bss @gol @@ -9155,6 +9156,30 @@ Even if @option{-fno-fp-int-builtin-inexact} is used, if the functions generate a call to a library function then the ``inexact'' exception may be raised if the library implementation does not follow TS 18661. +@item -fpermitted-flt-eval-methods=@var{style} +@opindex fpermitted-flt-eval-methods +@opindex fpermitted-flt-eval-methods=c11 +@opindex fpermitted-flt-eval-methods=ts-18661-3 +ISO/IEC TS 18661-3 defines new permissible values for +@code{FLT_EVAL_METHOD} that indicate that operations and constants with +a semantic type that is an interchange or extended format should be +evaluated to the precision and range of that type. These new values are +a superset of those permitted under C99/C11, which does not specify the +meaning of other positive values of @code{FLT_EVAL_METHOD}. As such, code +conforming to C11 may not have been written expecting the possibility of +the new values. + +@option{-fpermitted-flt-eval-methods} specifies whether the compiler +should allow only the values of @code{FLT_EVAL_METHOD} specified in C99/C11, +or the extended set of values specified in ISO/IEC TS 18661-3. + +@var{style} is either @code{c11} or @code{ts-18661-3} as appropriate. + +The default when in a standards compliant mode (@option{-std=c11} or similar) +is @option{-fpermitted-flt-eval-methods=c11}. The default when in a GNU +dialect (@option{-std=gnu11} or similar) is +@option{-fpermitted-flt-eval-methods=ts-18661-3}. + @item -fsingle-precision-constant @opindex fsingle-precision-constant Treat floating-point constants as single precision instead of diff --git a/gcc/flag-types.h b/gcc/flag-types.h index 6c5a4cc..d69f8f4 100644 --- a/gcc/flag-types.h +++ b/gcc/flag-types.h @@ -158,6 +158,14 @@ enum excess_precision EXCESS_PRECISION_STANDARD }; +/* The options for which values of FLT_EVAL_METHOD are permissible. */ +enum permitted_flt_eval_methods +{ + PERMITTED_FLT_EVAL_METHODS_DEFAULT, + PERMITTED_FLT_EVAL_METHODS_TS_18661, + PERMITTED_FLT_EVAL_METHODS_C11 +}; + /* Type of stack check. */ enum stack_check_type { diff --git a/gcc/testsuite/gcc.dg/fpermitted-flt-eval-methods_1.c b/gcc/testsuite/gcc.dg/fpermitted-flt-eval-methods_1.c new file mode 100644 index 0000000..c022f86 --- /dev/null +++ b/gcc/testsuite/gcc.dg/fpermitted-flt-eval-methods_1.c @@ -0,0 +1,19 @@ +/* { dg-do run } */ +/* { dg-options "-std=c11" } */ + +/* Test that we only see the C99/C11 values for __FLT_EVAL_METHOD__ if + we are compiling with -std=c11. */ + +int main (int argc, char** argv) +{ + switch (__FLT_EVAL_METHOD__) + { + case 0: + case 1: + case 2: + case -1: + return 0; + default: + return 1; + } +} diff --git a/gcc/testsuite/gcc.dg/fpermitted-flt-eval-methods_2.c b/gcc/testsuite/gcc.dg/fpermitted-flt-eval-methods_2.c new file mode 100644 index 0000000..a76ea7e --- /dev/null +++ b/gcc/testsuite/gcc.dg/fpermitted-flt-eval-methods_2.c @@ -0,0 +1,19 @@ +/* { dg-do run } */ +/* { dg-options "-fpermitted-flt-eval-methods=c11" } */ + +/* Test that we only see the C99/C11 values for __FLT_EVAL_METHOD__ if + we are compiling with -fpermitted-flt-eval-methods=c11. */ + +int main (int argc, char** argv) +{ + switch (__FLT_EVAL_METHOD__) + { + case 0: + case 1: + case 2: + case -1: + return 0; + default: + return 1; + } +}