diff mbox series

[Fortran] PR 82143: add a -fdefault-real-16 flag

Message ID CAKwh3qgr9Rvijf475FchWPr94JQcaEsMvXvOhPv2Lzi_FXL3wg@mail.gmail.com
State New
Headers show
Series [Fortran] PR 82143: add a -fdefault-real-16 flag | expand

Commit Message

Janus Weil Sept. 17, 2017, 8:42 p.m. UTC
Hi all,

attached is a (technically) simple patch that implements the compiler
flag "-fdefault-real-16" for gfortran.

I know that there is some opposition against this, but I am proposing
it anyway, because I do think it is useful after all. My reasoning is
as follows:

1) Despite tons of -freal-X-real-Y flags, there currently is no way to
only promote the default real kind to real(16).
2) Since a variable of default REAL kind does not specify a KIND value
explicitly, it is quite natural for a compiler to control this by
means of flags.
3) gfortran already has -fdefault-real-8 (which is used in lots of
real-world codes AFAIK) and does support quad-precision variables.
4) Other compilers do have flags for this as well (e.g. ifort's
"-real-size 128" etc).
5) I know that it is possible, any maybe cleaner, to declare variables
with explicit kinds instead of relying on compiler flags, but for
large and historically grown codes it is not always straightforward to
do this right away.
6) The patch does not modify the default behavior of gfortran.
7) No one who dislikes such compiler flags is forced to use them.
8) I don't see how this flag can cause any harm. It adds additional
possibilities of using the compiler and thus makes gfortran more
powerful (and more compatible with other compilers).

The patch regtests cleanly on x86_64-linux-gnu. Ok for trunk?

Cheers,
Janus


2017-09-17  Janus Weil  <janus@gcc.gnu.org>

    PR fortran/82143
    * lang.opt: Add the option -fdefault-real-16.
    * invoke.texi: Add documentation for -fdefault-real-16.
    * trans-types.c (gfc_init_kinds): Implement -fdefault-real-16.

2017-09-17  Janus Weil  <janus@gcc.gnu.org>

    PR fortran/82143
    * gfortran.dg/promotion_3.f90: New test case.

Comments

Steve Kargl Sept. 18, 2017, 4:50 a.m. UTC | #1
On Sun, Sep 17, 2017 at 10:42:01PM +0200, Janus Weil wrote:
> 
> attached is a (technically) simple patch that implements the compiler
> flag "-fdefault-real-16" for gfortran.

What about -fdefault-real-10?  If you're going to add bloat to the
compiler, then you might as well to it right.
Janus Weil Sept. 18, 2017, 7:02 a.m. UTC | #2
Hi Steve,

>> attached is a (technically) simple patch that implements the compiler
>> flag "-fdefault-real-16" for gfortran.
>
> What about -fdefault-real-10?  If you're going to add bloat to the
> compiler, then you might as well to it right.

well, yeah. If my only aim was to add bloat to the compiler out of
plain boredom and nastiness, then I might as well add
-fdefault-real-37. But I don't think that would be very useful.

Regarding -fdefault-real-16, in contrast: Yes, I think it's useful. My
motivation for adding it is to enable Real People(tm) in the Real
World(tm) to do Real Work(tm).

To give a few data points that document the need for such a flag
(brought up by a quick web search):
* https://gcc.gnu.org/ml/fortran/2012-01/msg00148.html
* https://glennklockwood.blogspot.de/2014/02/linux-perf-libquadmath-and-gfortrans.html
* https://ndclx4.bnl.gov/gf/project/empire/mailman/?_forum_action=ForumMessageBrowse&thread_id=1318&action=ListThreads&mailman_id=11
* plus my own usage scenarios for this flag

If nothing else, this flag is supposed to make gfortran compile code
that is built with "ifort -real-size 132". Or make it possible to try
quad-precision for codes that use -fdefault-real-8 (of which I think
there are quite a lot out there, whether you like it or not).

Why all the grumpiness, anyway?

Cheers,
Janus
Steve Kargl Sept. 18, 2017, 2:08 p.m. UTC | #3
On Mon, Sep 18, 2017 at 09:02:22AM +0200, Janus Weil wrote:
> Hi Steve,
> 
> >> attached is a (technically) simple patch that implements the compiler
> >> flag "-fdefault-real-16" for gfortran.
> >
> > What about -fdefault-real-10?  If you're going to add bloat to the
> > compiler, then you might as well to it right.
> 
> well, yeah. If my only aim was to add bloat to the compiler out of
> plain boredom and nastiness, then I might as well add
> -fdefault-real-37. But I don't think that would be very useful.

Why?  One gets 11-bits of additional precision (on most platforms)
and a significant increase in the exponent range (+- ~1024 to
+- ~16384).  REAL(10) maps to hardware floating point, which is
faster than software quad precision.
Janus Weil Sept. 18, 2017, 5:57 p.m. UTC | #4
2017-09-18 16:08 GMT+02:00 Steve Kargl <sgk@troutmask.apl.washington.edu>:
> On Mon, Sep 18, 2017 at 09:02:22AM +0200, Janus Weil wrote:
>> Hi Steve,
>>
>> >> attached is a (technically) simple patch that implements the compiler
>> >> flag "-fdefault-real-16" for gfortran.
>> >
>> > What about -fdefault-real-10?  If you're going to add bloat to the
>> > compiler, then you might as well to it right.
>>
>> well, yeah. If my only aim was to add bloat to the compiler out of
>> plain boredom and nastiness, then I might as well add
>> -fdefault-real-37. But I don't think that would be very useful.
>
> Why?  One gets 11-bits of additional precision (on most platforms)
> and a significant increase in the exponent range (+- ~1024 to
> +- ~16384).  REAL(10) maps to hardware floating point, which is
> faster than software quad precision.

Well, ok. If adding -fdefault-real-10 was a serious suggestion from
your side (which was not so easy to tell through all the sarcasm), I
can surely add that as well.

Cheers,
Janus
Janus Weil Sept. 21, 2017, 7:10 a.m. UTC | #5
Attached is an updated patch, where I'm adding -fdefault-real-10
according to Steve's suggestion. As with -fdefault-real-8 and
-fdefault-real-16, I'm choosing to set the double kind to 16 in this
case. Also I'm renaming flag_default_real to flag_default_real_8 (for
symmetry reasons and to make the code more readable). Finally I'm
removing the restriction that -fdefault-double-8 must occur together
with -fdefault-real-8. It may be useful on its own and should be
combinable with the new flags.

Ok for trunk?

Cheers,
Janus



2017-09-18 19:57 GMT+02:00 Janus Weil <janus@gcc.gnu.org>:
> 2017-09-18 16:08 GMT+02:00 Steve Kargl <sgk@troutmask.apl.washington.edu>:
>> On Mon, Sep 18, 2017 at 09:02:22AM +0200, Janus Weil wrote:
>>> Hi Steve,
>>>
>>> >> attached is a (technically) simple patch that implements the compiler
>>> >> flag "-fdefault-real-16" for gfortran.
>>> >
>>> > What about -fdefault-real-10?  If you're going to add bloat to the
>>> > compiler, then you might as well to it right.
>>>
>>> well, yeah. If my only aim was to add bloat to the compiler out of
>>> plain boredom and nastiness, then I might as well add
>>> -fdefault-real-37. But I don't think that would be very useful.
>>
>> Why?  One gets 11-bits of additional precision (on most platforms)
>> and a significant increase in the exponent range (+- ~1024 to
>> +- ~16384).  REAL(10) maps to hardware floating point, which is
>> faster than software quad precision.
>
> Well, ok. If adding -fdefault-real-10 was a serious suggestion from
> your side (which was not so easy to tell through all the sarcasm), I
> can surely add that as well.
>
> Cheers,
> Janus
Index: gcc/fortran/invoke.texi
===================================================================
--- gcc/fortran/invoke.texi	(revision 252892)
+++ gcc/fortran/invoke.texi	(working copy)
@@ -119,8 +119,8 @@ by type.  Explanations are in the following sectio
 @gccoptlist{-fall-intrinsics -fbackslash -fcray-pointer -fd-lines-as-code @gol
 -fd-lines-as-comments @gol
 -fdec -fdec-structure -fdec-intrinsic-ints -fdec-static -fdec-math @gol
--fdefault-double-8 -fdefault-integer-8 @gol
--fdefault-real-8 -fdollar-ok -ffixed-line-length-@var{n} @gol
+-fdefault-double-8 -fdefault-integer-8 -fdefault-real-8 @gol
+-fdefault-real-10 -fdefault-real-16 -fdollar-ok -ffixed-line-length-@var{n} @gol
 -ffixed-line-length-none -ffree-form -ffree-line-length-@var{n} @gol
 -ffree-line-length-none -fimplicit-none -finteger-4-integer-8 @gol
 -fmax-identifier-length -fmodule-private -ffixed-form -fno-range-check @gol
@@ -404,6 +404,22 @@ the default width of @code{DOUBLE PRECISION} to 16
 @code{-fdefault-double-8} is given, too. Unlike @option{-freal-4-real-8},
 it does not promote variables with explicit kind declaration.
 
+@item -fdefault-real-10
+@opindex @code{fdefault-real-10}
+Set the default real type to a 10 byte wide type. This option also affects
+the kind of non-double real constants like @code{1.0}, and does promote
+the default width of @code{DOUBLE PRECISION} to 16 bytes if possible, unless
+@code{-fdefault-double-8} is given. Unlike @option{-freal-4-real-10},
+it does not promote variables with explicit kind declaration.
+
+@item -fdefault-real-16
+@opindex @code{fdefault-real-16}
+Set the default real type to a 16 byte wide type. This option also affects
+the kind of non-double real constants like @code{1.0}, and does promote
+the default width of @code{DOUBLE PRECISION} to 16 bytes if possible, unless
+@code{-fdefault-double-8} is given. Unlike @option{-freal-4-real-16},
+it does not promote variables with explicit kind declaration.
+
 @item -fdefault-double-8
 @opindex @code{fdefault-double-8}
 Set the @code{DOUBLE PRECISION} type to an 8 byte wide type.  Do nothing if this
Index: gcc/fortran/lang.opt
===================================================================
--- gcc/fortran/lang.opt	(revision 252892)
+++ gcc/fortran/lang.opt	(working copy)
@@ -457,9 +457,17 @@ Fortran Var(flag_default_integer)
 Set the default integer kind to an 8 byte wide type.
 
 fdefault-real-8
-Fortran Var(flag_default_real)
+Fortran Var(flag_default_real_8)
 Set the default real kind to an 8 byte wide type.
 
+fdefault-real-10
+Fortran Var(flag_default_real_10)
+Set the default real kind to an 10 byte wide type.
+
+fdefault-real-16
+Fortran Var(flag_default_real_16)
+Set the default real kind to an 16 byte wide type.
+
 fdollar-ok
 Fortran Var(flag_dollar_ok)
 Allow dollar signs in entity names.
Index: gcc/fortran/module.c
===================================================================
--- gcc/fortran/module.c	(revision 252892)
+++ gcc/fortran/module.c	(working copy)
@@ -6741,7 +6741,7 @@ use_iso_fortran_env_module (void)
 				   "standard", symbol[i].name, &u->where))
 	        continue;
 
-	      if ((flag_default_integer || flag_default_real)
+	      if ((flag_default_integer || flag_default_real_8)
 		  && symbol[i].id == ISOFORTRANENV_NUMERIC_STORAGE_SIZE)
 		gfc_warning_now (0, "Use of the NUMERIC_STORAGE_SIZE named "
 				 "constant from intrinsic module "
@@ -6808,7 +6808,7 @@ use_iso_fortran_env_module (void)
 	  if ((gfc_option.allow_std & symbol[i].standard) == 0)
 	    continue;
 
-	  if ((flag_default_integer || flag_default_real)
+	  if ((flag_default_integer || flag_default_real_8)
 	      && symbol[i].id == ISOFORTRANENV_NUMERIC_STORAGE_SIZE)
 	    gfc_warning_now (0,
 			     "Use of the NUMERIC_STORAGE_SIZE named constant "
Index: gcc/fortran/trans-types.c
===================================================================
--- gcc/fortran/trans-types.c	(revision 252892)
+++ gcc/fortran/trans-types.c	(working copy)
@@ -530,7 +530,7 @@ gfc_init_kinds (void)
     }
 
   /* Choose the default real kind.  Again, we choose 4 when possible.  */
-  if (flag_default_real)
+  if (flag_default_real_8)
     {
       if (!saw_r8)
 	gfc_fatal_error ("REAL(KIND=8) is not available for "
@@ -538,6 +538,22 @@ gfc_init_kinds (void)
 
       gfc_default_real_kind = 8;
     }
+  else if (flag_default_real_10)
+  {
+    if (!saw_r10)
+      gfc_fatal_error ("REAL(KIND=10) is not available for "
+			"%<-fdefault-real-10%> option");
+
+    gfc_default_real_kind = 10;
+  }
+  else if (flag_default_real_16)
+  {
+    if (!saw_r16)
+      gfc_fatal_error ("REAL(KIND=16) is not available for "
+			"%<-fdefault-real-16%> option");
+
+    gfc_default_real_kind = 16;
+  }
   else if (flag_real4_kind == 8)
   {
     if (!saw_r8)
@@ -571,13 +587,10 @@ gfc_init_kinds (void)
      are specified, we use kind=8, if it's available.  If -fdefault-real is
      specified without -fdefault-double, we use kind=16, if it's available.
      Otherwise we do not change anything.  */
-  if (flag_default_double && !flag_default_real)
-    gfc_fatal_error ("Use of %<-fdefault-double-8%> requires "
-		     "%<-fdefault-real-8%>");
-
-  if (flag_default_real && flag_default_double && saw_r8)
+  if (flag_default_double && saw_r8)
     gfc_default_double_kind = 8;
-  else if (flag_default_real && saw_r16)
+  else if ((flag_default_real_8 || flag_default_real_10 || flag_default_real_16)
+	   && saw_r16)
     gfc_default_double_kind = 16;
   else if (flag_real8_kind == 4)
     {
Steve Kargl Sept. 21, 2017, 8:38 p.m. UTC | #6
On Thu, Sep 21, 2017 at 09:10:42AM +0200, Janus Weil wrote:
> Attached is an updated patch, where I'm adding -fdefault-real-10
> according to Steve's suggestion. As with -fdefault-real-8 and
> -fdefault-real-16, I'm choosing to set the double kind to 16 in this
> case. Also I'm renaming flag_default_real to flag_default_real_8 (for
> symmetry reasons and to make the code more readable). Finally I'm
> removing the restriction that -fdefault-double-8 must occur together
> with -fdefault-real-8. It may be useful on its own and should be
> combinable with the new flags.
> 
> Ok for trunk?
> 

Although I would prefer these options to be deprecated,
I did read the patch and it appears to be correct.  So,
I suppose it's ok for trunk.
Janus Weil Sept. 22, 2017, 5:02 a.m. UTC | #7
2017-09-21 22:38 GMT+02:00 Steve Kargl <sgk@troutmask.apl.washington.edu>:
> On Thu, Sep 21, 2017 at 09:10:42AM +0200, Janus Weil wrote:
>> Attached is an updated patch, where I'm adding -fdefault-real-10
>> according to Steve's suggestion. As with -fdefault-real-8 and
>> -fdefault-real-16, I'm choosing to set the double kind to 16 in this
>> case. Also I'm renaming flag_default_real to flag_default_real_8 (for
>> symmetry reasons and to make the code more readable). Finally I'm
>> removing the restriction that -fdefault-double-8 must occur together
>> with -fdefault-real-8. It may be useful on its own and should be
>> combinable with the new flags.
>>
>> Ok for trunk?
>>
>
> Although I would prefer these options to be deprecated,
> I did read the patch and it appears to be correct.  So,
> I suppose it's ok for trunk.

Thanks, Steve. I'm attaching the updated ChangeLog and the two test
cases for the two new flags. Since this appears to be  a somewhat
controversial feature, I'll wait two more days to allow for others to
contribute their feedback (positive or negative). I'll commit on
Sunday if I hear nothing until then.

Cheers,
Janus

2017-09-22  Janus Weil  <janus@gcc.gnu.org>

    PR fortran/82143
    * lang.opt: Add the options -fdefault-real-10 and -fdefault-real-16.
    Rename flag_default_real to flag_default_real_8.
    * invoke.texi: Add documentation.
    * module.c (use_iso_fortran_env_module): flag_default_real is renamed.
    * trans-types.c (gfc_init_kinds): Implement the flags
    -fdefault-real-10 and -fdefault-real-16. Make -fdefault-double-8 work
    without -fdefault-real-8.

2017-09-22  Janus Weil  <janus@gcc.gnu.org>

    PR fortran/82143
    * gfortran.dg/promotion_3.f90: New test case.
    * gfortran.dg/promotion_4.f90: New test case.
! { dg-do run }
! { dg-options "-fdefault-real-16" }
!
! PR 82143: add a -fdefault-real-16 flag
!
! Contributed by Janus Weil <janus@gcc.gnu.org>

real :: r
real(kind=4) :: r4
real(kind=8) :: r8
double precision :: d
if (kind(r4) /= 4) call abort
if (kind(r8) /= 8) call abort
if (kind(r) /= 16) call abort
if (kind(d) /= 16) call abort
end
! { dg-do run }
! { dg-options "-fdefault-real-10" }
!
! PR 82143: add a -fdefault-real-16 flag
!
! Contributed by Janus Weil <janus@gcc.gnu.org>

real :: r
real(kind=4) :: r4
real(kind=8) :: r8
double precision :: d
if (kind(r4) /= 4) call abort
if (kind(r8) /= 8) call abort
if (kind(r) /= 10) call abort
if (kind(d) /= 16) call abort
end
Janne Blomqvist Sept. 22, 2017, 7:11 a.m. UTC | #8
On Fri, Sep 22, 2017 at 8:02 AM, Janus Weil <janus@gcc.gnu.org> wrote:
> Thanks, Steve. I'm attaching the updated ChangeLog and the two test
> cases for the two new flags. Since this appears to be  a somewhat
> controversial feature, I'll wait two more days to allow for others to
> contribute their feedback (positive or negative). I'll commit on
> Sunday if I hear nothing until then.

Well, if you're actively soliciting bikeshedding, here goes:

Since we're about to have several -fdefault-real-N flags, would it
make sense to instead make a single flag -fdefault-real=SOMEVALUE (and
for backwards compatibility, make -fdefault-real-8 an alias for
-fdefault-real=8)? And similarly for -fdefault-double=.

And since the standard requires that double precision variables are
twice as big as reals, in the absence of an explicit -fdefault-double=
flag, would it make sense to have -fdefault-real=N imply
-fdefault-double=[2*N or if that isn't supported on the target, the
largest supported real kind]? (This is sort-of an extension of the
current -fdefault-real-8 behavior)
Janus Weil Sept. 22, 2017, 9:44 a.m. UTC | #9
2017-09-22 9:11 GMT+02:00 Janne Blomqvist <blomqvist.janne@gmail.com>:
> On Fri, Sep 22, 2017 at 8:02 AM, Janus Weil <janus@gcc.gnu.org> wrote:
>> Thanks, Steve. I'm attaching the updated ChangeLog and the two test
>> cases for the two new flags. Since this appears to be  a somewhat
>> controversial feature, I'll wait two more days to allow for others to
>> contribute their feedback (positive or negative). I'll commit on
>> Sunday if I hear nothing until then.
>
> Well, if you're actively soliciting bikeshedding, here goes:

I'm not soliciting anything. I'm giving people a fair chance to
comment. What you make out of that is completely up to you.


> Since we're about to have several -fdefault-real-N flags, would it
> make sense to instead make a single flag -fdefault-real=SOMEVALUE

I don't think that's a good idea, for several reasons:

1) We're probably not going to have much more N values (adding a
single one is tough enough of a job apparently, plus the list of
supported real kinds is very much limited anyway).

2) The syntax you're proposing is inconsistent with other flags like
-fdefault-integer-8, -fdefault-double-8. I'm sure we don't want to
change all of them.

3) That kind of syntax is not even used in other flags like
-ffree-line-length-n, where the range of possible values is
potentially much larger.



> And since the standard requires that double precision variables are
> twice as big as reals, in the absence of an explicit -fdefault-double=
> flag, would it make sense to have -fdefault-real=N imply
> -fdefault-double=[2*N or if that isn't supported on the target, the
> largest supported real kind]?

That's basically the behavior I tried to implement in my current patch
(although I notice now that you're not necessarily getting the largest
real kind, if 16 is not supported).

Cheers,
Janus
Steve Kargl Sept. 22, 2017, 2:05 p.m. UTC | #10
On Fri, Sep 22, 2017 at 10:11:55AM +0300, Janne Blomqvist wrote:
> On Fri, Sep 22, 2017 at 8:02 AM, Janus Weil <janus@gcc.gnu.org> wrote:
> > Thanks, Steve. I'm attaching the updated ChangeLog and the two test
> > cases for the two new flags. Since this appears to be  a somewhat
> > controversial feature, I'll wait two more days to allow for others to
> > contribute their feedback (positive or negative). I'll commit on
> > Sunday if I hear nothing until then.
> 
> Well, if you're actively soliciting bikeshedding, here goes:
> 
> Since we're about to have several -fdefault-real-N flags, would it
> make sense to instead make a single flag -fdefault-real=SOMEVALUE (and
> for backwards compatibility, make -fdefault-real-8 an alias for
> -fdefault-real=8)? And similarly for -fdefault-double=.
> 
> And since the standard requires that double precision variables are
> twice as big as reals, in the absence of an explicit -fdefault-double=
> flag, would it make sense to have -fdefault-real=N imply
> -fdefault-double=[2*N or if that isn't supported on the target, the
> largest supported real kind]? (This is sort-of an extension of the
> current -fdefault-real-8 behavior)

The standard requires more than just double precision being twice
as big as default real.  Among other things, storage association
rules require default logical, integer, and real to all occupy
the same number of storage units.  The promotion of DOUBLE
PRECISION to REAL(16), if available, was my misguided attempt to
enforce storage assocation.  That is the essenses of why I think
these options should go away.

But, I understand Janus's position that -fdefault-real-16 allows
a developer to quickly test whether an algorithm works and/or is
stable at higher precision.  The unfortunate side-effect is that
a developer finds that the result of the option appears to work,
so the developer never reviews the actual code.  It is not uncommon
to find old code of the form

       REAL EPS, NEW, OLD
       PARAMETER(EPS=1.E-8)
       ...
C      TEST FOR CONVERGENCE
       IF (ABS(NEW-OLD).LT.EPS) THEN

Is the convergence criteria still correct for -fdefault-real-16?
Only a developer reviewing and properly porting the code to a 
higher precision can make that decision.
Janus Weil Sept. 22, 2017, 7:32 p.m. UTC | #11
2017-09-22 11:44 GMT+02:00 Janus Weil <janus@gcc.gnu.org>:
> 2017-09-22 9:11 GMT+02:00 Janne Blomqvist <blomqvist.janne@gmail.com>:
>> And since the standard requires that double precision variables are
>> twice as big as reals, in the absence of an explicit -fdefault-double=
>> flag, would it make sense to have -fdefault-real=N imply
>> -fdefault-double=[2*N or if that isn't supported on the target, the
>> largest supported real kind]?
>
> That's basically the behavior I tried to implement in my current patch
> (although I notice now that you're not necessarily getting the largest
> real kind, if 16 is not supported).

Attached is a new version of the patch, which improves this point. In
the absence of further comments, I'll commit this by tomorrow.

Cheers,
Janus
Index: gcc/fortran/invoke.texi
===================================================================
--- gcc/fortran/invoke.texi	(revision 253108)
+++ gcc/fortran/invoke.texi	(working copy)
@@ -119,8 +119,8 @@ by type.  Explanations are in the following sectio
 @gccoptlist{-fall-intrinsics -fbackslash -fcray-pointer -fd-lines-as-code @gol
 -fd-lines-as-comments @gol
 -fdec -fdec-structure -fdec-intrinsic-ints -fdec-static -fdec-math @gol
--fdefault-double-8 -fdefault-integer-8 @gol
--fdefault-real-8 -fdollar-ok -ffixed-line-length-@var{n} @gol
+-fdefault-double-8 -fdefault-integer-8 -fdefault-real-8 @gol
+-fdefault-real-10 -fdefault-real-16 -fdollar-ok -ffixed-line-length-@var{n} @gol
 -ffixed-line-length-none -ffree-form -ffree-line-length-@var{n} @gol
 -ffree-line-length-none -fimplicit-none -finteger-4-integer-8 @gol
 -fmax-identifier-length -fmodule-private -ffixed-form -fno-range-check @gol
@@ -404,6 +404,22 @@ the default width of @code{DOUBLE PRECISION} to 16
 @code{-fdefault-double-8} is given, too. Unlike @option{-freal-4-real-8},
 it does not promote variables with explicit kind declaration.
 
+@item -fdefault-real-10
+@opindex @code{fdefault-real-10}
+Set the default real type to a 10 byte wide type. This option also affects
+the kind of non-double real constants like @code{1.0}, and does promote
+the default width of @code{DOUBLE PRECISION} to 16 bytes if possible, unless
+@code{-fdefault-double-8} is given. Unlike @option{-freal-4-real-10},
+it does not promote variables with explicit kind declaration.
+
+@item -fdefault-real-16
+@opindex @code{fdefault-real-16}
+Set the default real type to a 16 byte wide type. This option also affects
+the kind of non-double real constants like @code{1.0}, and does promote
+the default width of @code{DOUBLE PRECISION} to 16 bytes if possible, unless
+@code{-fdefault-double-8} is given. Unlike @option{-freal-4-real-16},
+it does not promote variables with explicit kind declaration.
+
 @item -fdefault-double-8
 @opindex @code{fdefault-double-8}
 Set the @code{DOUBLE PRECISION} type to an 8 byte wide type.  Do nothing if this
Index: gcc/fortran/lang.opt
===================================================================
--- gcc/fortran/lang.opt	(revision 253108)
+++ gcc/fortran/lang.opt	(working copy)
@@ -457,9 +457,17 @@ Fortran Var(flag_default_integer)
 Set the default integer kind to an 8 byte wide type.
 
 fdefault-real-8
-Fortran Var(flag_default_real)
+Fortran Var(flag_default_real_8)
 Set the default real kind to an 8 byte wide type.
 
+fdefault-real-10
+Fortran Var(flag_default_real_10)
+Set the default real kind to an 10 byte wide type.
+
+fdefault-real-16
+Fortran Var(flag_default_real_16)
+Set the default real kind to an 16 byte wide type.
+
 fdollar-ok
 Fortran Var(flag_dollar_ok)
 Allow dollar signs in entity names.
Index: gcc/fortran/module.c
===================================================================
--- gcc/fortran/module.c	(revision 253108)
+++ gcc/fortran/module.c	(working copy)
@@ -6741,7 +6741,7 @@ use_iso_fortran_env_module (void)
 				   "standard", symbol[i].name, &u->where))
 	        continue;
 
-	      if ((flag_default_integer || flag_default_real)
+	      if ((flag_default_integer || flag_default_real_8)
 		  && symbol[i].id == ISOFORTRANENV_NUMERIC_STORAGE_SIZE)
 		gfc_warning_now (0, "Use of the NUMERIC_STORAGE_SIZE named "
 				 "constant from intrinsic module "
@@ -6808,7 +6808,7 @@ use_iso_fortran_env_module (void)
 	  if ((gfc_option.allow_std & symbol[i].standard) == 0)
 	    continue;
 
-	  if ((flag_default_integer || flag_default_real)
+	  if ((flag_default_integer || flag_default_real_8)
 	      && symbol[i].id == ISOFORTRANENV_NUMERIC_STORAGE_SIZE)
 	    gfc_warning_now (0,
 			     "Use of the NUMERIC_STORAGE_SIZE named constant "
Index: gcc/fortran/trans-types.c
===================================================================
--- gcc/fortran/trans-types.c	(revision 253108)
+++ gcc/fortran/trans-types.c	(working copy)
@@ -530,7 +530,7 @@ gfc_init_kinds (void)
     }
 
   /* Choose the default real kind.  Again, we choose 4 when possible.  */
-  if (flag_default_real)
+  if (flag_default_real_8)
     {
       if (!saw_r8)
 	gfc_fatal_error ("REAL(KIND=8) is not available for "
@@ -538,6 +538,22 @@ gfc_init_kinds (void)
 
       gfc_default_real_kind = 8;
     }
+  else if (flag_default_real_10)
+  {
+    if (!saw_r10)
+      gfc_fatal_error ("REAL(KIND=10) is not available for "
+			"%<-fdefault-real-10%> option");
+
+    gfc_default_real_kind = 10;
+  }
+  else if (flag_default_real_16)
+  {
+    if (!saw_r16)
+      gfc_fatal_error ("REAL(KIND=16) is not available for "
+			"%<-fdefault-real-16%> option");
+
+    gfc_default_real_kind = 16;
+  }
   else if (flag_real4_kind == 8)
   {
     if (!saw_r8)
@@ -571,14 +587,20 @@ gfc_init_kinds (void)
      are specified, we use kind=8, if it's available.  If -fdefault-real is
      specified without -fdefault-double, we use kind=16, if it's available.
      Otherwise we do not change anything.  */
-  if (flag_default_double && !flag_default_real)
-    gfc_fatal_error ("Use of %<-fdefault-double-8%> requires "
-		     "%<-fdefault-real-8%>");
-
-  if (flag_default_real && flag_default_double && saw_r8)
+  if (flag_default_double && saw_r8)
     gfc_default_double_kind = 8;
-  else if (flag_default_real && saw_r16)
-    gfc_default_double_kind = 16;
+  else if (flag_default_real_8 || flag_default_real_10 || flag_default_real_16)
+    {
+      /* Use largest available kind.  */
+      if (saw_r16)
+	gfc_default_double_kind = 16;
+      else if (saw_r10)
+	gfc_default_double_kind = 10;
+      else if (saw_r8)
+	gfc_default_double_kind = 8;
+      else
+	gfc_default_double_kind = gfc_default_real_kind;
+    }
   else if (flag_real8_kind == 4)
     {
       if (!saw_r4)
Index: gcc/testsuite/gfortran.dg/promotion_3.f90
===================================================================
--- gcc/testsuite/gfortran.dg/promotion_3.f90	(nonexistent)
+++ gcc/testsuite/gfortran.dg/promotion_3.f90	(working copy)
@@ -0,0 +1,16 @@
+! { dg-do run }
+! { dg-options "-fdefault-real-16" }
+!
+! PR 82143: add a -fdefault-real-16 flag
+!
+! Contributed by Janus Weil <janus@gcc.gnu.org>
+
+real :: r
+real(kind=4) :: r4
+real(kind=8) :: r8
+double precision :: d
+if (kind(r4) /= 4) call abort
+if (kind(r8) /= 8) call abort
+if (kind(r) /= 16) call abort
+if (kind(d) /= 16) call abort
+end
Index: gcc/testsuite/gfortran.dg/promotion_4.f90
===================================================================
--- gcc/testsuite/gfortran.dg/promotion_4.f90	(nonexistent)
+++ gcc/testsuite/gfortran.dg/promotion_4.f90	(working copy)
@@ -0,0 +1,16 @@
+! { dg-do run }
+! { dg-options "-fdefault-real-10" }
+!
+! PR 82143: add a -fdefault-real-16 flag
+!
+! Contributed by Janus Weil <janus@gcc.gnu.org>
+
+real :: r
+real(kind=4) :: r4
+real(kind=8) :: r8
+double precision :: d
+if (kind(r4) /= 4) call abort
+if (kind(r8) /= 8) call abort
+if (kind(r) /= 10) call abort
+if (kind(d) /= 16) call abort
+end
Janus Weil Sept. 23, 2017, 1:19 p.m. UTC | #12
2017-09-22 21:32 GMT+02:00 Janus Weil <janus@gcc.gnu.org>:
> 2017-09-22 11:44 GMT+02:00 Janus Weil <janus@gcc.gnu.org>:
>> 2017-09-22 9:11 GMT+02:00 Janne Blomqvist <blomqvist.janne@gmail.com>:
>>> And since the standard requires that double precision variables are
>>> twice as big as reals, in the absence of an explicit -fdefault-double=
>>> flag, would it make sense to have -fdefault-real=N imply
>>> -fdefault-double=[2*N or if that isn't supported on the target, the
>>> largest supported real kind]?
>>
>> That's basically the behavior I tried to implement in my current patch
>> (although I notice now that you're not necessarily getting the largest
>> real kind, if 16 is not supported).
>
> Attached is a new version of the patch, which improves this point. In
> the absence of further comments, I'll commit this by tomorrow.

Landed on trunk as r253117.

Cheers,
Janus
diff mbox series

Patch

Index: gcc/fortran/invoke.texi
===================================================================
--- gcc/fortran/invoke.texi	(revision 252892)
+++ gcc/fortran/invoke.texi	(working copy)
@@ -120,7 +120,7 @@  by type.  Explanations are in the following sectio
 -fd-lines-as-comments @gol
 -fdec -fdec-structure -fdec-intrinsic-ints -fdec-static -fdec-math @gol
 -fdefault-double-8 -fdefault-integer-8 @gol
--fdefault-real-8 -fdollar-ok -ffixed-line-length-@var{n} @gol
+-fdefault-real-8 -fdefault-real-16 -fdollar-ok -ffixed-line-length-@var{n} @gol
 -ffixed-line-length-none -ffree-form -ffree-line-length-@var{n} @gol
 -ffree-line-length-none -fimplicit-none -finteger-4-integer-8 @gol
 -fmax-identifier-length -fmodule-private -ffixed-form -fno-range-check @gol
@@ -404,6 +404,14 @@  the default width of @code{DOUBLE PRECISION} to 16
 @code{-fdefault-double-8} is given, too. Unlike @option{-freal-4-real-8},
 it does not promote variables with explicit kind declaration.
 
+@item -fdefault-real-16
+@opindex @code{fdefault-real-16}
+Set the default real type to a 16 byte wide type. This option also affects
+the kind of non-double real constants like @code{1.0}, and does promote
+the default width of @code{DOUBLE PRECISION} to 16 bytes if possible, unless
+@code{-fdefault-double-8} is given. Unlike @option{-freal-4-real-16},
+it does not promote variables with explicit kind declaration.
+
 @item -fdefault-double-8
 @opindex @code{fdefault-double-8}
 Set the @code{DOUBLE PRECISION} type to an 8 byte wide type.  Do nothing if this
Index: gcc/fortran/lang.opt
===================================================================
--- gcc/fortran/lang.opt	(revision 252892)
+++ gcc/fortran/lang.opt	(working copy)
@@ -460,6 +460,10 @@  fdefault-real-8
 Fortran Var(flag_default_real)
 Set the default real kind to an 8 byte wide type.
 
+fdefault-real-16
+Fortran Var(flag_default_real_16)
+Set the default real kind to an 16 byte wide type.
+
 fdollar-ok
 Fortran Var(flag_dollar_ok)
 Allow dollar signs in entity names.
Index: gcc/fortran/trans-types.c
===================================================================
--- gcc/fortran/trans-types.c	(revision 252892)
+++ gcc/fortran/trans-types.c	(working copy)
@@ -538,6 +538,14 @@  gfc_init_kinds (void)
 
       gfc_default_real_kind = 8;
     }
+  else if (flag_default_real_16)
+  {
+    if (!saw_r16)
+      gfc_fatal_error ("REAL(KIND=16) is not available for "
+			"%<-fdefault-real-16%> option");
+
+    gfc_default_real_kind = 16;
+  }
   else if (flag_real4_kind == 8)
   {
     if (!saw_r8)
@@ -577,7 +585,7 @@  gfc_init_kinds (void)
 
   if (flag_default_real && flag_default_double && saw_r8)
     gfc_default_double_kind = 8;
-  else if (flag_default_real && saw_r16)
+  else if ((flag_default_real || flag_default_real_16) && saw_r16)
     gfc_default_double_kind = 16;
   else if (flag_real8_kind == 4)
     {