This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[Patch 5/17] Add -fpermitted-flt-eval-methods=[c11|ts-18661-3]
- From: James Greenhalgh <james dot greenhalgh at arm dot com>
- To: <gcc-patches at gcc dot gnu dot org>
- Cc: <nd at arm dot com>, <joseph at codesourcery dot com>, <law at redhat dot com>
- Date: Fri, 11 Nov 2016 15:37:22 +0000
- Subject: [Patch 5/17] Add -fpermitted-flt-eval-methods=[c11|ts-18661-3]
- Authentication-results: sourceware.org; auth=none
- Authentication-results: spf=pass (sender IP is 217.140.96.140) smtp.mailfrom=arm.com; codesourcery.com; dkim=none (message not signed) header.d=none;codesourcery.com; dmarc=bestguesspass action=none header.from=arm.com;
- Nodisclaimer: True
- References: <1475254617-10825-1-git-send-email-james.greenhalgh@arm.com> <1478878647-22547-1-git-send-email-james.greenhalgh@arm.com>
- Spamdiagnosticmetadata: NSPM
- Spamdiagnosticoutput: 1:99
---
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.greenhalgh@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.greenhalgh@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.greenhalgh@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;
+ }
+}