diff mbox

[5/17] Add -fpermitted-flt-eval-methods=[c11|ts-18661-3]

Message ID 1478878647-22547-6-git-send-email-james.greenhalgh@arm.com
State New
Headers show

Commit Message

James Greenhalgh Nov. 11, 2016, 3:37 p.m. UTC
---
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.

Comments

Sandra Loosemore Nov. 12, 2016, 4:42 a.m. UTC | #1
On 11/11/2016 08:37 AM, James Greenhalgh wrote:

> 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

This seems like totally the wrong place to document this.  The new 
option seems more like a code generation option than an optimization 
option, which is what the context of the above patch hunk is.  Moreover, 
the list above is alphabetized and you're sticking the new option in a 
totally random place within the list.

-Sandra
diff mbox

Patch

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;
+    }
+}