diff mbox

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

Message ID 1475254617-10825-3-git-send-email-james.greenhalgh@arm.com
State New
Headers show

Commit Message

James Greenhalgh Sept. 30, 2016, 4:56 p.m. UTC
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 and tested in series on AArch64.

OK?

Thanks,
James

---
gcc/c-family/

2016-09-30  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-09-30  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-09-30  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

Jeff Law Sept. 30, 2016, 5:34 p.m. UTC | #1
On 09/30/2016 10:56 AM, James Greenhalgh wrote:
>
> 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 and tested in series on AArch64.
>
> OK?
>
> Thanks,
> James
>
> ---
> gcc/c-family/
>
> 2016-09-30  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-09-30  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-09-30  James Greenhalgh  <james.greenhalgh@arm.com>
>
> 	* gcc.dg/fpermitted-flt-eval-methods_1.c: New.
> 	* gcc.dg/fpermitted-flt-eval-methods_2.c: New.
OK.    Are you going to need to do something for C++ (or gasp ObjC) in 
the future, or do you expect this to be C only indefinitely?

jeff
>
Mike Stump Sept. 30, 2016, 9:43 p.m. UTC | #2
On Sep 30, 2016, at 10:34 AM, Jeff Law <law@redhat.com> wrote:
>> 2016-09-30  James Greenhalgh  <james.greenhalgh@arm.com>
>> 
>> 	* gcc.dg/fpermitted-flt-eval-methods_1.c: New.
>> 	* gcc.dg/fpermitted-flt-eval-methods_2.c: New.
> OK.    Are you going to need to do something for C++ (or gasp ObjC) in the future

ObjC should come along for free as long as major rules of ettiquite aren't broken.

As test that says, make this work only for C, would be wrong.  Conditionalizing a flag as only for C would be wrong.  I glanced around and didn't see anything that would make it not work for ObjC.
Joseph Myers Oct. 5, 2016, 10:59 p.m. UTC | #3
On Fri, 30 Sep 2016, James Greenhalgh wrote:

> 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.

As noted in my comments on patch 6, the tests should check FLT_EVAL_METHOD 
from <float.h>, not the internal __FLT_EVAL_METHOD__ macro (and <float.h> 
will need to contain conditionals so that the -std=c11 
-D__STDC_WANT_IEC_60559_TYPES_EXT__ case uses the new values when 
appropriate).
diff mbox

Patch

diff --git a/gcc/c-family/c-opts.c b/gcc/c-family/c-opts.c
index c5a699d..af8d7fe 100644
--- a/gcc/c-family/c-opts.c
+++ b/gcc/c-family/c-opts.c
@@ -789,6 +789,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 0e01577..3a22aa0 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -1305,6 +1305,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 8a84e4f..9cb0b54 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -375,7 +375,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
@@ -8917,6 +8918,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 816df6b..ac3075b 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;
+    }
+}