public inbox for fortran@gcc.gnu.org
 help / color / mirror / Atom feed
* [RFC, Fortran] Fix c_float128 and c_float128_complex on targets with 128-bit long double.
@ 2021-08-04 20:14 Sandra Loosemore
  2021-08-05 17:33 ` Michael Meissner
  0 siblings, 1 reply; 15+ messages in thread
From: Sandra Loosemore @ 2021-08-04 20:14 UTC (permalink / raw)
  To: fortran, gcc-patches; +Cc: David Edelsohn, segher

[-- Attachment #1: Type: text/plain, Size: 1943 bytes --]

I was trying last week to run my not-yet-committed TS29113 testsuite on 
a powerpc64le-linux-gnu target and ran into some problems with the kind 
constants c_float128 and c_float128_complex from the ISO_C_BINDING 
module; per the gfortran manual they are supposed to represent the kind 
of the gcc extension type __float128 and the corresponding complex type. 
  They were being set to -4 (e.g., not supported) instead of 16, 
although this target does define __float128 and real(16) is accepted as 
a supported type by the Fortran front end.

Anyway, the root of the problem is that the definition of these 
constants only looked at gfc_float128_type_node, which only gets set if 
TFmode is not the same type as long_double_type_node.  I experimented 
with setting gfc_float128_type_node = long_double_type_node but that 
caused various Bad Things to happen elsewhere in code that expected them 
to be distinct types, so I ended up with this minimally intrusive patch 
that only tweaks the definitions of the c_float128 and 
c_float128_complex constants.

I'm not sure this is completely correct, though.  I see PowerPC
supports 2 different 128-bit encodings and it looks like TFmode/long 
double is mapped onto the one selected by the ABI and/or command-line 
options; that's the only one the Fortran front end knows about.  All of 
TFmode, IFmode, and KFmode would map onto kind 16 anyway (in spite of 
having different TYPE_PRECISION values) so Fortran wouldn't be able to 
distinguish them.  The thing that confuses me is how/when the rs6000 
backend defines __float128; it looks like the documentation in the GCC 
manual doesn't agree with the code, and I'm not sure what the intended 
behavior really is.  Is it possible that __float128 could end up defined 
but specifying a different type than TFmode, and if so is there a 
target-independent way to identify that situation?  Can the PowerPC 
experts help straighten me out?

-Sandra

[-- Attachment #2: iso-c-binding.patch --]
[-- Type: text/x-patch, Size: 3332 bytes --]

commit 158c2f6b1a4134bbdbe59034d38ce12faa8167a8
Author: Sandra Loosemore <sandra@codesourcery.com>
Date:   Tue Aug 3 16:21:16 2021 -0700

    Fix c_float128 and c_float128_complex on targets with 128-bit long double.
    
    gfc_float128_type_node is only non-NULL on targets where float128 is
    supported and is a distinct type from long double.  So, check
    long_double_type_node as well when computing the value of the kind
    constants c_float128 and c_float128_complex from the ISO_C_BINDING
    intrinsic module.
    
    2021-08-03  Sandra Loosemore  <sandra@codesourcery.com>
    
    gcc/fortran/
    	* iso-c-binding.def (c_float128, c_float128_complex): Also
    	check long_double_type_node.  Add comments to explain why.

diff --git a/gcc/fortran/iso-c-binding.def b/gcc/fortran/iso-c-binding.def
index 8bf69ef..a05e324 100644
--- a/gcc/fortran/iso-c-binding.def
+++ b/gcc/fortran/iso-c-binding.def
@@ -114,9 +114,25 @@ NAMED_REALCST (ISOCBINDING_DOUBLE, "c_double", \
                get_real_kind_from_node (double_type_node), GFC_STD_F2003)
 NAMED_REALCST (ISOCBINDING_LONG_DOUBLE, "c_long_double", \
                get_real_kind_from_node (long_double_type_node), GFC_STD_F2003)
+
+/* GNU Extension.  gfc_float128_type_node is only non-null if the target
+   supports a 128-bit type distinct from the long double type.  Otherwise
+   if long double has kind 16, that's also the float128 type and we can
+   use kind 16 for that too.
+
+   Specifically, on x86_64, long double is the 80-bit encoding with kind
+   10; it has a storage size of 128 bits due to alignment requirements,
+   but if a true 128-bit float is supported it will have kind 16 and
+   gfc_float128_type_node will point to it.  PowerPC has 3 different
+   128-bit encodings that are distinguished by having different
+   TYPE_PRECISION values (not necessarily 128).  They all map onto
+   Fortran kind 16, which corresponds to C long double.  The default
+   encoding is determined by the ABI.  */
 NAMED_REALCST (ISOCBINDING_FLOAT128, "c_float128", \
-	       gfc_float128_type_node == NULL_TREE \
-		  ? -4 : get_real_kind_from_node (gfc_float128_type_node), \
+	       (gfc_float128_type_node == NULL_TREE \
+		  ? (get_real_kind_from_node (long_double_type_node) == 16 \
+		     ? 16 : -4) \
+		  : get_real_kind_from_node (gfc_float128_type_node)), \
 	       GFC_STD_GNU)
 NAMED_CMPXCST (ISOCBINDING_FLOAT_COMPLEX, "c_float_complex", \
                get_real_kind_from_node (float_type_node), GFC_STD_F2003)
@@ -124,9 +140,13 @@ NAMED_CMPXCST (ISOCBINDING_DOUBLE_COMPLEX, "c_double_complex", \
                get_real_kind_from_node (double_type_node), GFC_STD_F2003)
 NAMED_CMPXCST (ISOCBINDING_LONG_DOUBLE_COMPLEX, "c_long_double_complex", \
                get_real_kind_from_node (long_double_type_node), GFC_STD_F2003)
+
+/* GNU Extension.  Similar issues to c_float128 above.  */
 NAMED_CMPXCST (ISOCBINDING_FLOAT128_COMPLEX, "c_float128_complex", \
-	       gfc_float128_type_node == NULL_TREE \
-		  ? -4 : get_real_kind_from_node (gfc_float128_type_node), \
+	       (gfc_float128_type_node == NULL_TREE \
+		  ? (get_real_kind_from_node (long_double_type_node) == 16 \
+		     ? 16 : -4) \
+		  : get_real_kind_from_node (gfc_float128_type_node)), \
 	       GFC_STD_GNU)
 
 NAMED_LOGCST (ISOCBINDING_BOOL, "c_bool", \

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [RFC, Fortran] Fix c_float128 and c_float128_complex on targets with 128-bit long double.
  2021-08-04 20:14 [RFC, Fortran] Fix c_float128 and c_float128_complex on targets with 128-bit long double Sandra Loosemore
@ 2021-08-05 17:33 ` Michael Meissner
  2021-08-05 18:19   ` Sandra Loosemore
  0 siblings, 1 reply; 15+ messages in thread
From: Michael Meissner @ 2021-08-05 17:33 UTC (permalink / raw)
  To: Sandra Loosemore
  Cc: fortran, gcc-patches, segher, David Edelsohn, Michael Meissner

On Wed, Aug 04, 2021 at 02:14:07PM -0600, Sandra Loosemore wrote:
> I was trying last week to run my not-yet-committed TS29113 testsuite
> on a powerpc64le-linux-gnu target and ran into some problems with
> the kind constants c_float128 and c_float128_complex from the
> ISO_C_BINDING module; per the gfortran manual they are supposed to
> represent the kind of the gcc extension type __float128 and the
> corresponding complex type.  They were being set to -4 (e.g., not
> supported) instead of 16, although this target does define
> __float128 and real(16) is accepted as a supported type by the
> Fortran front end.
> 
> Anyway, the root of the problem is that the definition of these
> constants only looked at gfc_float128_type_node, which only gets set
> if TFmode is not the same type as long_double_type_node.  I
> experimented with setting gfc_float128_type_node =
> long_double_type_node but that caused various Bad Things to happen
> elsewhere in code that expected them to be distinct types, so I
> ended up with this minimally intrusive patch that only tweaks the
> definitions of the c_float128 and c_float128_complex constants.
> 
> I'm not sure this is completely correct, though.  I see PowerPC
> supports 2 different 128-bit encodings and it looks like TFmode/long
> double is mapped onto the one selected by the ABI and/or
> command-line options; that's the only one the Fortran front end
> knows about.  All of TFmode, IFmode, and KFmode would map onto kind
> 16 anyway (in spite of having different TYPE_PRECISION values) so
> Fortran wouldn't be able to distinguish them.  The thing that
> confuses me is how/when the rs6000 backend defines __float128; it
> looks like the documentation in the GCC manual doesn't agree with
> the code, and I'm not sure what the intended behavior really is.  Is
> it possible that __float128 could end up defined but specifying a
> different type than TFmode, and if so is there a target-independent
> way to identify that situation?  Can the PowerPC experts help
> straighten me out?
> 
> -Sandra

At the moment, we only fully support C and C++ when changing the long double
format (between IEEE 128-bit, IBM 128-bit, and 64-bit) when the compiler is
invoked (and assuming you are using GLIBC 2.32 or newer).

For Fortran and the other languages, the only way to change the floating point
format is to configure the compiler with the '--with-long-double-format=ieee'
configuration option.  This makes TFmode use IEEE 128-bit floating point
instead of IBM 128-bit floating point.

It would take somebody familar with the Fortran front end and libraries to make
the same sort of modifications that were made for the C and C++ languages.
Basically you need build libgfortran so that it has support for both floating
point formats, using different names.  You would need to modify the fortran
front end to call the alternate functions when the switch is used to change the
floating point format.  It might be nice to have a Fortran specific way to
specify which of the two floating point formats are used for REAL*16 (similar
to the use of __float128 and __ibm128 in C/C++, and also _Float128 in just C).

If you are going to do it, good luck.

FWIW, I have built GCC compilers with the alternate floating point format, and
I've been able to run the test suite and compile the Spec 2017 test suite with
it.

Generally to build a bootstrap compiler with the alternate long double
representation I go through the following steps.

1) Make sure you have a GLIBC that supports switching long double
representation (2.32 or new).  I tend to use the IBM Advance Toolchain AT
14.0-3 to provide the new library, but if the native GLIBC on your system is
new enough you could use that.  I've discovered that there are problems if the
GCC zlib is use, so I use the system zlib.  The options I use when configuring
the compiler include:

	--with-advance-toolchain=at14.0
	--with-system-zlib
	--with-native-system-header-dir=/opt/at14.0/include

If you are building and running on a power9 system, it is helpful if you add
the option to set the default CPU to power9, since that way the compiler will
automatically use the hardware IEEE 128-bit instructions that were added in
power9.  Otherwise it has to go through a call to do each operation.  If you
are running on a power9, we use the ifunc attribute to select modules that are
built to use the hardware instruction.

	--with-cpu=power9

2) Build a non-bootstrap compiler with the '--with-long-double-format=ieee'
configuration option, and install it somewhere.

3) With the compiler built in step #2, build the three libraries GCC uses (MPC,
MPFR, and GMP), and install them some place.  You need to do this because these
libraries have functions in them with long double arguments.  GCC doesn't
actually use the functions with the long double arguments, but you will get a
linker warning about mixing long double floating point type.

4) With the compiler built in step #2 and the libraries built in step #3, build
a non-bootstrap compiler using '--with-long-double-format=ieee' and install
it.  You don't need to do this step, but when I was doing the development, I
found it easier to track down problems with the non-bootstrap compiler.

5) If you haven't had any errors, go on to building a full bootstrap version of
the compiler using the compiler built in step #4 for stage1 and the libraries
built in step #2.

-- 
Michael Meissner, IBM
IBM, M/S 2506R, 550 King Street, Littleton, MA 01460-6245, USA
email: meissner@linux.ibm.com, phone: +1 (978) 899-4797

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [RFC, Fortran] Fix c_float128 and c_float128_complex on targets with 128-bit long double.
  2021-08-05 17:33 ` Michael Meissner
@ 2021-08-05 18:19   ` Sandra Loosemore
  2021-08-05 20:09     ` Michael Meissner
  0 siblings, 1 reply; 15+ messages in thread
From: Sandra Loosemore @ 2021-08-05 18:19 UTC (permalink / raw)
  To: Michael Meissner, fortran, gcc-patches, segher, David Edelsohn

On 8/5/21 11:33 AM, Michael Meissner wrote:
> At the moment, we only fully support C and C++ when changing the long double
> format (between IEEE 128-bit, IBM 128-bit, and 64-bit) when the compiler is
> invoked (and assuming you are using GLIBC 2.32 or newer).
> 
> For Fortran and the other languages, the only way to change the floating point
> format is to configure the compiler with the '--with-long-double-format=ieee'
> configuration option.  This makes TFmode use IEEE 128-bit floating point
> instead of IBM 128-bit floating point.

My understanding from reading the code is is that for GNU/Linux targets, 
PowerPC already defaults to the IEEE format for TFmode?  I'm not sure 
what targets the IBM format might be the default on.

> It would take somebody familar with the Fortran front end and libraries to make
> the same sort of modifications that were made for the C and C++ languages.
> Basically you need build libgfortran so that it has support for both floating
> point formats, using different names.  You would need to modify the fortran
> front end to call the alternate functions when the switch is used to change the
> floating point format.  It might be nice to have a Fortran specific way to
> specify which of the two floating point formats are used for REAL*16 (similar
> to the use of __float128 and __ibm128 in C/C++, and also _Float128 in just C).
> 
> If you are going to do it, good luck.

Well, I am actually not at all interested in doing that.  My questions 
for the PowerPC experts are:

(1) When is the __float128 type defined, and which format does it 
specify?  Is it always the IEEE format, or does it specify the same 
format as TFmode/long double?

(2) If __float128 is not always the same 128-bit format as TFmode/long 
double, how can I detect that in the Fortran front end in a 
target-independent way?  Is it possible without adding a new target hook?

(3) Can we do anything about the "Additional Floating Types" section in 
extend.texi?  It's not clear on the answer to (1), and I think the stuff 
about "future versions of GCC" is bit-rotten as it goes back to at least 
GCC 6.  (Either it's been implemented by now, or the idea was discarded.)

Basically, I want the Fortran front end to define c_float128 to 16 if C 
supports __float128 and it corresponds to TFmode, otherwise it ought to 
continue to define c_float128 to -4.  I do not want to make the Fortran 
front end support multiple 128-bit encodings at the same time, just 
accurately define c_float128.

-Sandra


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [RFC, Fortran] Fix c_float128 and c_float128_complex on targets with 128-bit long double.
  2021-08-05 18:19   ` Sandra Loosemore
@ 2021-08-05 20:09     ` Michael Meissner
  2021-08-09 21:42       ` [Patch v2 " Sandra Loosemore
  0 siblings, 1 reply; 15+ messages in thread
From: Michael Meissner @ 2021-08-05 20:09 UTC (permalink / raw)
  To: Sandra Loosemore
  Cc: Michael Meissner, fortran, gcc-patches, segher, David Edelsohn

On Thu, Aug 05, 2021 at 12:19:37PM -0600, Sandra Loosemore wrote:
> On 8/5/21 11:33 AM, Michael Meissner wrote:
> >At the moment, we only fully support C and C++ when changing the long double
> >format (between IEEE 128-bit, IBM 128-bit, and 64-bit) when the compiler is
> >invoked (and assuming you are using GLIBC 2.32 or newer).
> >
> >For Fortran and the other languages, the only way to change the floating point
> >format is to configure the compiler with the '--with-long-double-format=ieee'
> >configuration option.  This makes TFmode use IEEE 128-bit floating point
> >instead of IBM 128-bit floating point.
> 
> My understanding from reading the code is is that for GNU/Linux
> targets, PowerPC already defaults to the IEEE format for TFmode?
> I'm not sure what targets the IBM format might be the default on.

All PowerPC systems that I'm aware of that use 128-bit floating point use the
IBM format.  It is anticipated that one or more Linux distributions in the
future may move to IEEE 128-bit format, but right now, I'm not aware that any
have moved.

> >It would take somebody familar with the Fortran front end and libraries to make
> >the same sort of modifications that were made for the C and C++ languages.
> >Basically you need build libgfortran so that it has support for both floating
> >point formats, using different names.  You would need to modify the fortran
> >front end to call the alternate functions when the switch is used to change the
> >floating point format.  It might be nice to have a Fortran specific way to
> >specify which of the two floating point formats are used for REAL*16 (similar
> >to the use of __float128 and __ibm128 in C/C++, and also _Float128 in just C).
> >
> >If you are going to do it, good luck.
> 
> Well, I am actually not at all interested in doing that.  My
> questions for the PowerPC experts are:
> 
> (1) When is the __float128 type defined, and which format does it
> specify?  Is it always the IEEE format, or does it specify the same
> format as TFmode/long double?

__float128 (and _Float128 in C) is always IEEE 128-bit, if IEEE 128-bit is
supported.  By default, IEEE 128-bit is only supported on little endian PowerPC
64-bit systems.

For C (but not C++), you can declare constants with the f128 suffix so that
they would be compatible with the _Float128 type.

> 
> (2) If __float128 is not always the same 128-bit format as
> TFmode/long double, how can I detect that in the Fortran front end
> in a target-independent way?  Is it possible without adding a new
> target hook?

You can look at the constants in float.h:

For a system with IBM long double:

	FLT_RADIX        = 2
	LDBL_MANT_DIG    = 106
	LDBL_DIG         = 31
	LDBL_MIN_EXP     = -968
	LDBL_MIN_10_EXP  = -291
	LDBL_MAX_EXP     = 1024
	LDBL_MAX_10_EXP  = 308

For a system with IEEE long double:

	FLT_RADIX        = 2
	LDBL_MANT_DIG    = 113
	LDBL_DIG         = 33
	LDBL_MIN_EXP     = -16381
	LDBL_MIN_10_EXP  = -4931
	LDBL_MAX_EXP     = 16384
	LDBL_MAX_10_EXP  = 4932

For a system that uses 64-bit numbers for long double:

	FLT_RADIX        = 2
	LDBL_MANT_DIG    = 53
	LDBL_DIG         = 15
	LDBL_MIN_EXP     = -1021
	LDBL_MIN_10_EXP  = -307
	LDBL_MAX_EXP     = 1024
	LDBL_MAX_10_EXP  = 308

In addition, the PowerPC GCC defines __LONG_DOUBLE_IEEE128__ if long double is
IEEE 128-bit, and __LONG_DOUBLE_IBM128__ if long double IBM 128-bit.  If long
double is 64-bit, the macro __LONG_DOUBLE_128__ is not defined.

> (3) Can we do anything about the "Additional Floating Types" section
> in extend.texi?  It's not clear on the answer to (1), and I think
> the stuff about "future versions of GCC" is bit-rotten as it goes
> back to at least GCC 6.  (Either it's been implemented by now, or
> the idea was discarded.)
> 
> Basically, I want the Fortran front end to define c_float128 to 16
> if C supports __float128 and it corresponds to TFmode, otherwise it
> ought to continue to define c_float128 to -4.  I do not want to make
> the Fortran front end support multiple 128-bit encodings at the same
> time, just accurately define c_float128.

-- 
Michael Meissner, IBM
IBM, M/S 2506R, 550 King Street, Littleton, MA 01460-6245, USA
email: meissner@linux.ibm.com, phone: +1 (978) 899-4797

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [Patch v2 Fortran] Fix c_float128 and c_float128_complex on targets with 128-bit long double.
  2021-08-05 20:09     ` Michael Meissner
@ 2021-08-09 21:42       ` Sandra Loosemore
  2021-08-10  8:29         ` Tobias Burnus
  0 siblings, 1 reply; 15+ messages in thread
From: Sandra Loosemore @ 2021-08-09 21:42 UTC (permalink / raw)
  To: Michael Meissner, fortran, gcc-patches, segher, David Edelsohn

[-- Attachment #1: Type: text/plain, Size: 1784 bytes --]

On 8/5/21 2:09 PM, Michael Meissner wrote:

> All PowerPC systems that I'm aware of that use 128-bit floating point use the
> IBM format.  It is anticipated that one or more Linux distributions in the
> future may move to IEEE 128-bit format, but right now, I'm not aware that any
> have moved.

OK.  I now think it's correct that the Fortran front end doesn't support 
c_float128 and c_float128_complex on this target, but that the code that 
initializes those constants is still buggy.  The reason why it shouldn't 
support them is that all 3 128-bit floating-point modes on PowerPC would 
map onto kind=16, and we can only support one of them unless we make 
some exception to the formula for mapping precision -> kind.  And the 
mode the Fortran front end already prefers is the one that corresponds 
to long double or TFmode.

So the reason why the current code is wrong is that 
gfc_float128_type_node only gets set if there is a type with 128-bit 
precision that is not long double, so c_float128 wouldn't be supported 
on a target where __float128 is equivalent to long double.  Moreover, on 
targets where it does define gfc_float128_type_node, it's not doing 
anything to ensure that it's actually the same IEEE representation as 
__float128.  Both problems can be fixed by just using float128_type_node 
to get the type corresponding to __float128.  If that's not a mode the 
Fortran front end knows about, get_real_kind_from_node will detect that.

I suspect there are some similar lurking bugs in other uses of 
gfc_float128_type_node in the Fortran front end, but that's out of scope 
for my current project focusing on interoperability features.  I'll file 
an issue about it, though.

Here's a revised patch.  Fortran maintainers, is this one OK to check in?

-Sandra

[-- Attachment #2: c_float128.patch --]
[-- Type: text/x-patch, Size: 4597 bytes --]

commit 073dd403d11553c199610b038285b203c130cee5
Author: Sandra Loosemore <sandra@codesourcery.com>
Date:   Tue Aug 3 16:21:16 2021 -0700

    Fix c_float128 and c_float128_complex definitions.
    
    gfc_float128_type_node is only non-NULL on targets that support a
    128-bit type that is not long double.  Use float128_type_node instead
    when computing the value of the kind constants c_float128 and
    c_float128_complex from the ISO_C_BINDING intrinsic module; this also
    ensures it actually corresponds to __float128 (the IEEE encoding) and
    not some other 128-bit floating-point type.
    
    2021-08-09  Sandra Loosemore  <sandra@codesourcery.com>
    
    gcc/fortran/
    	* iso-c-binding.def (c_float128, c_float128_complex): Check
    	float128_type_node instead of gfc_float128_type_node.
    	* trans-types.c (gfc_init_kinds, gfc_build_real_type):
    	Update comments re supported 128-bit floating-point types.

diff --git a/gcc/fortran/iso-c-binding.def b/gcc/fortran/iso-c-binding.def
index 8bf69ef..e65c750 100644
--- a/gcc/fortran/iso-c-binding.def
+++ b/gcc/fortran/iso-c-binding.def
@@ -114,9 +114,14 @@ NAMED_REALCST (ISOCBINDING_DOUBLE, "c_double", \
                get_real_kind_from_node (double_type_node), GFC_STD_F2003)
 NAMED_REALCST (ISOCBINDING_LONG_DOUBLE, "c_long_double", \
                get_real_kind_from_node (long_double_type_node), GFC_STD_F2003)
+
+/* GNU Extension.  Note that the equivalence here is specifically to
+   the IEEE 128-bit type __float128; if that does not map onto a type
+   otherwise supported by the Fortran front end, get_real_kind_from_node
+   will reject it as unsupported.  */
 NAMED_REALCST (ISOCBINDING_FLOAT128, "c_float128", \
-	       gfc_float128_type_node == NULL_TREE \
-		  ? -4 : get_real_kind_from_node (gfc_float128_type_node), \
+		(float128_type_node == NULL_TREE \
+		 ? -4 : get_real_kind_from_node (float128_type_node)), \
 	       GFC_STD_GNU)
 NAMED_CMPXCST (ISOCBINDING_FLOAT_COMPLEX, "c_float_complex", \
                get_real_kind_from_node (float_type_node), GFC_STD_F2003)
@@ -124,9 +129,11 @@ NAMED_CMPXCST (ISOCBINDING_DOUBLE_COMPLEX, "c_double_complex", \
                get_real_kind_from_node (double_type_node), GFC_STD_F2003)
 NAMED_CMPXCST (ISOCBINDING_LONG_DOUBLE_COMPLEX, "c_long_double_complex", \
                get_real_kind_from_node (long_double_type_node), GFC_STD_F2003)
+
+/* GNU Extension.  Similar issues to c_float128 above.  */
 NAMED_CMPXCST (ISOCBINDING_FLOAT128_COMPLEX, "c_float128_complex", \
-	       gfc_float128_type_node == NULL_TREE \
-		  ? -4 : get_real_kind_from_node (gfc_float128_type_node), \
+		(float128_type_node == NULL_TREE \
+		 ? -4 : get_real_kind_from_node (float128_type_node)), \
 	       GFC_STD_GNU)
 
 NAMED_LOGCST (ISOCBINDING_BOOL, "c_bool", \
diff --git a/gcc/fortran/trans-types.c b/gcc/fortran/trans-types.c
index 50fda43..8250219 100644
--- a/gcc/fortran/trans-types.c
+++ b/gcc/fortran/trans-types.c
@@ -446,7 +446,7 @@ gfc_init_kinds (void)
       if (!targetm.scalar_mode_supported_p (mode))
 	continue;
 
-      /* Only let float, double, long double and __float128 go through.
+      /* Only let float, double, long double and TFmode go through.
 	 Runtime support for others is not provided, so they would be
 	 useless.  */
       if (!targetm.libgcc_floating_mode_supported_p (mode))
@@ -471,7 +471,15 @@ gfc_init_kinds (void)
 	 We round up so as to handle IA-64 __floatreg (RFmode), which is an
 	 82 bit type.  Not to be confused with __float80 (XFmode), which is
 	 an 80 bit type also supported by IA-64.  So XFmode should come out
-	 to be kind=10, and RFmode should come out to be kind=11.  Egads.  */
+	 to be kind=10, and RFmode should come out to be kind=11.  Egads.
+
+	 One consequence of this mapping is that all 3 128-bit
+	 floating-point modes on PowerPC would have kind 16 in spite of
+	 having incompatible representations.  But we have filtered out
+	 IFmode (the explicit IBM format) and KFmode (the explicit IEEE
+	 format) already in the code just above, leaving only whichever
+	 representation has been designated for TFmode as kind=16.
+      */
 
       kind = (GET_MODE_PRECISION (mode) + 7) / 8;
 
@@ -851,6 +859,9 @@ gfc_build_real_type (gfc_real_info *info)
     info->c_long_double = 1;
   if (mode_precision != LONG_DOUBLE_TYPE_SIZE && mode_precision == 128)
     {
+      /* FIXME: why are we assuming that this type has IEEE
+	 representation?  That's implied by associating it with the
+	 C type __float128.  */
       info->c_float128 = 1;
       gfc_real16_is_float128 = true;
     }

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [Patch v2 Fortran] Fix c_float128 and c_float128_complex on targets with 128-bit long double.
  2021-08-09 21:42       ` [Patch v2 " Sandra Loosemore
@ 2021-08-10  8:29         ` Tobias Burnus
  2021-08-10 11:59           ` Segher Boessenkool
                             ` (2 more replies)
  0 siblings, 3 replies; 15+ messages in thread
From: Tobias Burnus @ 2021-08-10  8:29 UTC (permalink / raw)
  To: Sandra Loosemore, Michael Meissner, fortran, gcc-patches, segher,
	David Edelsohn

Hi Sandra, hi all,

Let's start reverse – by trying to answer:

On 09.08.21 23:42, Sandra Loosemore wrote:
...
>     if (mode_precision != LONG_DOUBLE_TYPE_SIZE && mode_precision == 128)
>       {
> +      /* FIXME: why are we assuming that this type has IEEE
> +      representation?  That's implied by associating it with the
> +      C type __float128.  */
>         info->c_float128 = 1;

First, a lot of code implicitly assumes x86(-64) with the i387
80bit long double and __float128 being the true 128bit floating type.

In terms of the code, there are builtins for float, double, and
long double but for kind(16) > long double, no builtin exists but
a library call has to be done. Likewise, there is the assumption
that in this case, the functions end in 'q', i.e. 'sinq' besides
the known sinf, sin, and sinl.

Thus, in terms of the FE, info->c_float128 implies 'q' suffix and
library calls for functions where for other types a built-in exists.

Thus, by itself, it is unrelated to __float128.

However, as libquadmath uses __float128, the C decl dependency
appears, unless some other library provides 'sinq' etc. for the
non-__float128 128bit type.

  * * *

In terms of Fortran, REAL types do not need to follow IEEE
(there are IEEE intrinsic modules to handle IEEE); thus, REAL(16)
does not need to be an IEEE type – albeit most users implicitly
expect it.

Likewise, kind numbers have no meaning, but there is plenty of
code which expects that kind=4 = 32bit and kind=8 = 64bit,
especially when used in older code as '<type>*<kind>' (e.g. 'real*8')
but also quite some code using the newer syntax '<type>(<kind>)' or
'<type>(kind=<kind>') (e.g. 'real(8)' or 'real(kind=8)').

For real, kind=10 (i387's 80bit type) is a specialty of gfortran
(most? all?) other compilers do not support it; kind=16 is more widely
supported, albeit some simply map it to 'long double'.

There is no reason why the different PowerPC TF modes couldn't be
mapped to, e.g., the kinds 17, 18, 19, 20 – except that the Fortran FE,
libgfortran current assumes that only 4, 8, 10 and 16 exist and if
10 exists, 16 is the 'q'/libquadmath version. – Additionally, those
17-20 kinds will also confuse users and using '16' has to be mapped
somehow to one of the TF modes in a way that it still works with
interface kind checks and .mod module files and PowerPC's -m flags.

  * * *

Back to:

> On 8/5/21 2:09 PM, Michael Meissner wrote:
>
>> All PowerPC systems that I'm aware of that use 128-bit floating point
>> use the
>> IBM format.  It is anticipated that one or more Linux distributions
>> in the
>> future may move to IEEE 128-bit format, but right now, I'm not aware
>> that any
>> have moved.
>
> OK.  I now think it's correct that the Fortran front end doesn't
> support c_float128 and c_float128_complex on this target, but that the
> code that initializes those constants is still buggy. The reason why
> it shouldn't support them is that all 3 128-bit floating-point modes
> on PowerPC would map onto kind=16,

Side note: in rs6000-modes.h, there is:
   #define FLOAT_PRECISION_IFmode  128
   #define FLOAT_PRECISION_TFmode  127
   #define FLOAT_PRECISION_KFmode  126
with IFmode (IBM 128-bit floating point), TFmode (long double mode), KFmode (explicit __float128).

As written above, there is nothing in Fortran (the language) which
prevents those to be mapped to, e.g., kind=14, 15, 16. Thus, I do not
see the conclusion that all of them would be kind=16 – neither from the code
(which filters out all but TFmode for kind=16) nor from the language.
(On the other hand, support for multiple 128bit FP is also not in the FE - nor
the support for real kind != 4,8,10,16.)

Actually, kind=11 (= ia64's long double alias RFmode) is also supported,
but I am not sure it really works as it not well tested; it is accessible
via the REAL_KINDS array, which enables access to all kind numbers or
via selected_real_kinds() or ...


> and we can only support one of them unless we make some exception to
> the formula for mapping precision -> kind.  And the mode the Fortran
> front end already prefers is the one that corresponds to long double
> or TFmode.
I concur.
> So the reason why the current code is wrong is that
> gfc_float128_type_node only gets set if there is a type with 128-bit
> precision that is not long double, so c_float128 wouldn't be supported
> on a target where __float128 is equivalent to long double.  Moreover,
> on targets where it does define gfc_float128_type_node, it's not doing
> anything to ensure that it's actually the same IEEE representation as
> __float128.  Both problems can be fixed by just using
> float128_type_node to get the type corresponding to __float128.  If
> that's not a mode the Fortran front end knows about,
> get_real_kind_from_node will detect that.
That sounds right.
> I suspect there are some similar lurking bugs in other uses of
> gfc_float128_type_node in the Fortran front end, but that's out of
> scope for my current project focusing on interoperability features.
> I'll file an issue about it, though.

Besides the general issue ('q' + libquadmath, calling library
functions), I think the current code should be fine and IEEE is not
really needed. – Actually, the co-processor i387 also does not proper
IEEE rounding (contrary to SSE) and it is still used with 'kind=10' or
'long double'. – Still, there might be issues, especially thinking about
IA-64's kind=11 + when we want to support all PowerPC 128-bit modes.

  * * *

> commit 073dd403d11553c199610b038285b203c130cee5
> Author: Sandra Loosemore<sandra@codesourcery.com>
> Date:   Tue Aug 3 16:21:16 2021 -0700
>
>      Fix c_float128 and c_float128_complex definitions.
>
>      gfc_float128_type_node is only non-NULL on targets that support a
>      128-bit type that is not long double.  Use float128_type_node instead
>      when computing the value of the kind constants c_float128 and
>      c_float128_complex from the ISO_C_BINDING intrinsic module; this also
>      ensures it actually corresponds to __float128 (the IEEE encoding) and
>      not some other 128-bit floating-point type.
>
>      2021-08-09  Sandra Loosemore<sandra@codesourcery.com>
>
>      gcc/fortran/
>       * iso-c-binding.def (c_float128, c_float128_complex): Check
>       float128_type_node instead of gfc_float128_type_node.
>       * trans-types.c (gfc_init_kinds, gfc_build_real_type):
>       Update comments re supported 128-bit floating-point types.
>
> diff --git a/gcc/fortran/iso-c-binding.def b/gcc/fortran/iso-c-binding.def
> index 8bf69ef..e65c750 100644
> --- a/gcc/fortran/iso-c-binding.def
> +++ b/gcc/fortran/iso-c-binding.def
> @@ -114,9 +114,14 @@ NAMED_REALCST (ISOCBINDING_DOUBLE, "c_double", \
>                  get_real_kind_from_node (double_type_node), GFC_STD_F2003)
>   NAMED_REALCST (ISOCBINDING_LONG_DOUBLE, "c_long_double", \
>                  get_real_kind_from_node (long_double_type_node), GFC_STD_F2003)
> +
> +/* GNU Extension.  Note that the equivalence here is specifically to
> +   the IEEE 128-bit type __float128; if that does not map onto a type
> +   otherwise supported by the Fortran front end, get_real_kind_from_node
> +   will reject it as unsupported.  */
>   NAMED_REALCST (ISOCBINDING_FLOAT128, "c_float128", \
> -            gfc_float128_type_node == NULL_TREE \
> -               ? -4 : get_real_kind_from_node (gfc_float128_type_node), \
> +             (float128_type_node == NULL_TREE \
> +              ? -4 : get_real_kind_from_node (float128_type_node)), \
>              GFC_STD_GNU)
>   NAMED_CMPXCST (ISOCBINDING_FLOAT_COMPLEX, "c_float_complex", \
>                  get_real_kind_from_node (float_type_node), GFC_STD_F2003)
> @@ -124,9 +129,11 @@ NAMED_CMPXCST (ISOCBINDING_DOUBLE_COMPLEX, "c_double_complex", \
>                  get_real_kind_from_node (double_type_node), GFC_STD_F2003)
>   NAMED_CMPXCST (ISOCBINDING_LONG_DOUBLE_COMPLEX, "c_long_double_complex", \
>                  get_real_kind_from_node (long_double_type_node), GFC_STD_F2003)
> +
> +/* GNU Extension.  Similar issues to c_float128 above.  */
>   NAMED_CMPXCST (ISOCBINDING_FLOAT128_COMPLEX, "c_float128_complex", \
> -            gfc_float128_type_node == NULL_TREE \
> -               ? -4 : get_real_kind_from_node (gfc_float128_type_node), \
> +             (float128_type_node == NULL_TREE \
> +              ? -4 : get_real_kind_from_node (float128_type_node)), \
>              GFC_STD_GNU)
>
>   NAMED_LOGCST (ISOCBINDING_BOOL, "c_bool", \
> diff --git a/gcc/fortran/trans-types.c b/gcc/fortran/trans-types.c
> index 50fda43..8250219 100644
> --- a/gcc/fortran/trans-types.c
> +++ b/gcc/fortran/trans-types.c
> @@ -446,7 +446,7 @@ gfc_init_kinds (void)
>         if (!targetm.scalar_mode_supported_p (mode))
>       continue;
>
> -      /* Only let float, double, long double and __float128 go through.
> +      /* Only let float, double, long double and TFmode go through.
>        Runtime support for others is not provided, so they would be
>        useless.  */
>         if (!targetm.libgcc_floating_mode_supported_p (mode))
All changes above are fine. But:
> @@ -471,7 +471,15 @@ gfc_init_kinds (void)
>        We round up so as to handle IA-64 __floatreg (RFmode), which is an
>        82 bit type.  Not to be confused with __float80 (XFmode), which is
>        an 80 bit type also supported by IA-64.  So XFmode should come out
> -      to be kind=10, and RFmode should come out to be kind=11.  Egads.  */
> +      to be kind=10, and RFmode should come out to be kind=11.  Egads.
> +
> +      One consequence of this mapping is that all 3 128-bit
> +      floating-point modes on PowerPC would have kind 16 in spite of
> +      having incompatible representations.  But we have filtered out
> +      IFmode (the explicit IBM format) and KFmode (the explicit IEEE
> +      format) already in the code just above, leaving only whichever
> +      representation has been designated for TFmode as kind=16.
> +      */

First, I am not sure about the last bit as both TFmode and
TYPE_MODE (long_double_type_node) can reach this code – and I am not
sure whether they are always the same.

And additionally, the comment above for IA-64 talks about
actual results – while you talk about something hypothetical
(if IFmode/KFmode reached that code, it would map to kind=16).

I think a comment like the following is clearer – describing a pitfall
and a to-do item:

"TODO: The kind calculation has to be modified to support all three
128-bit floating-point modes on PowerPC as IFmode, KFmode, and TFmode
as the following line would all map to kind=16. However, currently only
float, double, long double, and TFmode reach this code."

>         kind = (GET_MODE_PRECISION (mode) + 7) / 8;
>
> @@ -851,6 +859,9 @@ gfc_build_real_type (gfc_real_info *info)
>       info->c_long_double = 1;
>     if (mode_precision != LONG_DOUBLE_TYPE_SIZE && mode_precision == 128)
>       {
> +      /* FIXME: why are we assuming that this type has IEEE
> +      representation?  That's implied by associating it with the
> +      C type __float128.  */
>         info->c_float128 = 1;
>         gfc_real16_is_float128 = true;
>       }
I think the question has been answered above.

Given the dependency on intrinsics:
libc/libm provide float/double/long double functions and
lib<somthing> (like libquadmath) has to provide the suffix 'q' version;
As both ligfortran and libquadmath use __float128, we effectively do
depend on having a data type which is compatible with C's __float128.

As the "why" has been answered, can you turn this into a note about
issues with this or a to-do item?

  * * *

To conclude: I like the code changes (LGTM); the
'__float128' -> 'TFmode' comment change also matches the code.

However, I think both longer comments need to be updated.

  * * *

And I concur that some overhaul of the kind handling is needed
for PowerPC's 128-bit floats – but the main issue there is less the
FE but how to handle it on the library side as libm-like math
functions are needed by almost every Fortran code – and,
additionally, libgfortran has to be updated as well as it provides
somes REAL functions, which also need to support additional kinds.

Tobias

-----------------
Siemens Electronic Design Automation GmbH; Anschrift: Arnulfstraße 201, 80634 München; Gesellschaft mit beschränkter Haftung; Geschäftsführer: Thomas Heurung, Frank Thürauf; Sitz der Gesellschaft: München; Registergericht München, HRB 106955

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [Patch v2 Fortran] Fix c_float128 and c_float128_complex on targets with 128-bit long double.
  2021-08-10  8:29         ` Tobias Burnus
@ 2021-08-10 11:59           ` Segher Boessenkool
  2021-08-10 15:58           ` Sandra Loosemore
  2021-08-10 22:46           ` [Patch v3 " Sandra Loosemore
  2 siblings, 0 replies; 15+ messages in thread
From: Segher Boessenkool @ 2021-08-10 11:59 UTC (permalink / raw)
  To: Tobias Burnus
  Cc: Sandra Loosemore, Michael Meissner, fortran, gcc-patches, David Edelsohn

Hi!

On Tue, Aug 10, 2021 at 10:29:08AM +0200, Tobias Burnus wrote:
> On 09.08.21 23:42, Sandra Loosemore wrote:
> In terms of Fortran, REAL types do not need to follow IEEE
> (there are IEEE intrinsic modules to handle IEEE); thus, REAL(16)
> does not need to be an IEEE type – albeit most users implicitly
> expect it.
>
> Likewise, kind numbers have no meaning, but there is plenty of
> code which expects that kind=4 = 32bit and kind=8 = 64bit,
> especially when used in older code as '<type>*<kind>' (e.g. 'real*8')
> but also quite some code using the newer syntax '<type>(<kind>)' or
> '<type>(kind=<kind>') (e.g. 'real(8)' or 'real(kind=8)').
> 
> For real, kind=10 (i387's 80bit type) is a specialty of gfortran
> (most? all?) other compilers do not support it; kind=16 is more widely
> supported, albeit some simply map it to 'long double'.

So, make 16 always mean IEEE QP float for us, and 15 mean double-double?
(Or whatever other number you prefer -- as you explain, 16 should be the
preferred one though, and that is the IEEE float of course).

> There is no reason why the different PowerPC TF modes couldn't be
> mapped to, e.g., the kinds 17, 18, 19, 20 – except that the Fortran FE,
> libgfortran current assumes that only 4, 8, 10 and 16 exist and if
> 10 exists, 16 is the 'q'/libquadmath version. – Additionally, those
> 17-20 kinds will also confuse users and using '16' has to be mapped
> somehow to one of the TF modes in a way that it still works with
> interface kind checks and .mod module files and PowerPC's -m flags.

There are only two 16-byte float modes: IFmode is double-double, and
KFmode is IEEE QP float.  Those modes mean the same thing whatever
options the compiler has, and whatever the default is.  TFmode is
another name for one of those two modes, and that one can vary.

Also, of course, a mode is not a type, and a type is not a mode, they
are different concepts.  IEEE QP float is always available (if enabled)
via __ieee128, and double-double is always available via __ibm128.

> >code that initializes those constants is still buggy. The reason why
> >it shouldn't support them is that all 3 128-bit floating-point modes
> >on PowerPC would map onto kind=16,

So fix that?  16 should be the IEEE kind, and then something else for
the double-double kind?

> Side note: in rs6000-modes.h, there is:
>   #define FLOAT_PRECISION_IFmode  128
>   #define FLOAT_PRECISION_TFmode  127
>   #define FLOAT_PRECISION_KFmode  126
> with IFmode (IBM 128-bit floating point), TFmode (long double mode), KFmode 
> (explicit __float128).

This is a workaround for a fundamental problem in GCC internals, which
requires all floating point modes to be ordered.  This is not true for
QP float and double-double: each of those can represent values the other
can not.

And it is only a workaround, and it will change some day.

> >and we can only support one of them unless we make some exception to
> >the formula for mapping precision -> kind.  And the mode the Fortran
> >front end already prefers is the one that corresponds to long double
> >or TFmode.
> I concur.

A kind number should always map to the same floating point format, it
should not depend on unrelated compiler flags.  It should not matter at
all what "long double" maps to.  Anything else leads to more insanity
than needed.


Segher

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [Patch v2 Fortran] Fix c_float128 and c_float128_complex on targets with 128-bit long double.
  2021-08-10  8:29         ` Tobias Burnus
  2021-08-10 11:59           ` Segher Boessenkool
@ 2021-08-10 15:58           ` Sandra Loosemore
  2021-08-10 22:46           ` [Patch v3 " Sandra Loosemore
  2 siblings, 0 replies; 15+ messages in thread
From: Sandra Loosemore @ 2021-08-10 15:58 UTC (permalink / raw)
  To: Tobias Burnus, Michael Meissner, fortran, gcc-patches, segher,
	David Edelsohn

On 8/10/21 2:29 AM, Tobias Burnus wrote:
> 
> [snip]
> 
>> OK.  I now think it's correct that the Fortran front end doesn't 
>> support c_float128 and c_float128_complex on this target, but that the 
>> code that initializes those constants is still buggy. The reason why 
>> it shouldn't support them is that all 3 128-bit floating-point modes 
>> on PowerPC would map onto kind=16,
> 
> Side note: in rs6000-modes.h, there is:
>    #define FLOAT_PRECISION_IFmode  128
>    #define FLOAT_PRECISION_TFmode  127
>    #define FLOAT_PRECISION_KFmode  126
> with IFmode (IBM 128-bit floating point), TFmode (long double mode), 
> KFmode (explicit __float128).
> 
> As written above, there is nothing in Fortran (the language) which
> prevents those to be mapped to, e.g., kind=14, 15, 16. Thus, I do not
> see the conclusion that all of them would be kind=16 – neither from the 
> code
> (which filters out all but TFmode for kind=16) nor from the language.
> (On the other hand, support for multiple 128bit FP is also not in the FE 
> - nor
> the support for real kind != 4,8,10,16.)

Just to quickly address this one point:

It's not in Fortran (the language), but gfc_init_kinds says:

/* Let the kind equal the precision divided by 8, rounding up.  Again,
    this insulates the programmer from the underlying byte size. [...]  */

kind = (GET_MODE_PRECISION (mode) + 7) / 8;

and indeed all 3 of those modes would map onto kind 16 -- unless we want 
to make some exception in the general formula, e.g. using a target hook. 
  I'm not terribly inclined to go down that path, myself.  All I really 
want to do is make c_float128 and c_float128_complex get defined 
properly for the types Fortran already supports.

I need to think some more about your other comments but I'll try to come 
up with a revised patch to address them.

-Sandra

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [Patch v3 Fortran] Fix c_float128 and c_float128_complex on targets with 128-bit long double.
  2021-08-10  8:29         ` Tobias Burnus
  2021-08-10 11:59           ` Segher Boessenkool
  2021-08-10 15:58           ` Sandra Loosemore
@ 2021-08-10 22:46           ` Sandra Loosemore
  2021-08-11  8:05             ` Tobias Burnus
  2021-08-11 10:55             ` Segher Boessenkool
  2 siblings, 2 replies; 15+ messages in thread
From: Sandra Loosemore @ 2021-08-10 22:46 UTC (permalink / raw)
  To: Tobias Burnus, Michael Meissner, fortran, gcc-patches, segher,
	David Edelsohn

[-- Attachment #1: Type: text/plain, Size: 928 bytes --]

On 8/10/21 2:29 AM, Tobias Burnus wrote:
> 
> [snip]
> 
> To conclude: I like the code changes (LGTM); the
> '__float128' -> 'TFmode' comment change also matches the code.
> 
> However, I think both longer comments need to be updated.

OK.  I used your wording verbatim for the first one.  For the second 
one, I'm still pretty confused as I think it is at least theoretically 
possible on PowerPC to have a target with 64-bit long double (AIX?) that 
also supports the __ibm128 format, and it would be wrong to assume that 
*any* 128-bit mode that's not long double is IEEE.  So I decided the 
best thing is just to replace the FIXME with a pointer to the issue I 
opened yesterday

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101835

and folks who actually understand this stuff can add some more 
discussion there.

Here's a new version of the patch with changes to the two comments only. 
  OK to commit this one?

-Sandra

[-- Attachment #2: c_float128-v3.patch --]
[-- Type: text/x-patch, Size: 4377 bytes --]

commit e496723ec6ee0fcf5b0c58920c74b1c9afa831de
Author: Sandra Loosemore <sandra@codesourcery.com>
Date:   Tue Aug 3 16:21:16 2021 -0700

    Fix c_float128 and c_float128_complex definitions.
    
    gfc_float128_type_node is only non-NULL on targets that support a
    128-bit type that is not long double.  Use float128_type_node instead
    when computing the value of the kind constants c_float128 and
    c_float128_complex from the ISO_C_BINDING intrinsic module; this also
    ensures it actually corresponds to __float128 (the IEEE encoding) and
    not some other 128-bit floating-point type.
    
    2021-08-10  Sandra Loosemore  <sandra@codesourcery.com>
    
    gcc/fortran/
    	* iso-c-binding.def (c_float128, c_float128_complex): Check
    	float128_type_node instead of gfc_float128_type_node.
    	* trans-types.c (gfc_init_kinds, gfc_build_real_type):
    	Update comments re supported 128-bit floating-point types.

diff --git a/gcc/fortran/iso-c-binding.def b/gcc/fortran/iso-c-binding.def
index 8bf69ef..e65c750 100644
--- a/gcc/fortran/iso-c-binding.def
+++ b/gcc/fortran/iso-c-binding.def
@@ -114,9 +114,14 @@ NAMED_REALCST (ISOCBINDING_DOUBLE, "c_double", \
                get_real_kind_from_node (double_type_node), GFC_STD_F2003)
 NAMED_REALCST (ISOCBINDING_LONG_DOUBLE, "c_long_double", \
                get_real_kind_from_node (long_double_type_node), GFC_STD_F2003)
+
+/* GNU Extension.  Note that the equivalence here is specifically to
+   the IEEE 128-bit type __float128; if that does not map onto a type
+   otherwise supported by the Fortran front end, get_real_kind_from_node
+   will reject it as unsupported.  */
 NAMED_REALCST (ISOCBINDING_FLOAT128, "c_float128", \
-	       gfc_float128_type_node == NULL_TREE \
-		  ? -4 : get_real_kind_from_node (gfc_float128_type_node), \
+		(float128_type_node == NULL_TREE \
+		 ? -4 : get_real_kind_from_node (float128_type_node)), \
 	       GFC_STD_GNU)
 NAMED_CMPXCST (ISOCBINDING_FLOAT_COMPLEX, "c_float_complex", \
                get_real_kind_from_node (float_type_node), GFC_STD_F2003)
@@ -124,9 +129,11 @@ NAMED_CMPXCST (ISOCBINDING_DOUBLE_COMPLEX, "c_double_complex", \
                get_real_kind_from_node (double_type_node), GFC_STD_F2003)
 NAMED_CMPXCST (ISOCBINDING_LONG_DOUBLE_COMPLEX, "c_long_double_complex", \
                get_real_kind_from_node (long_double_type_node), GFC_STD_F2003)
+
+/* GNU Extension.  Similar issues to c_float128 above.  */
 NAMED_CMPXCST (ISOCBINDING_FLOAT128_COMPLEX, "c_float128_complex", \
-	       gfc_float128_type_node == NULL_TREE \
-		  ? -4 : get_real_kind_from_node (gfc_float128_type_node), \
+		(float128_type_node == NULL_TREE \
+		 ? -4 : get_real_kind_from_node (float128_type_node)), \
 	       GFC_STD_GNU)
 
 NAMED_LOGCST (ISOCBINDING_BOOL, "c_bool", \
diff --git a/gcc/fortran/trans-types.c b/gcc/fortran/trans-types.c
index 50fda43..26dbbd8 100644
--- a/gcc/fortran/trans-types.c
+++ b/gcc/fortran/trans-types.c
@@ -446,7 +446,7 @@ gfc_init_kinds (void)
       if (!targetm.scalar_mode_supported_p (mode))
 	continue;
 
-      /* Only let float, double, long double and __float128 go through.
+      /* Only let float, double, long double and TFmode go through.
 	 Runtime support for others is not provided, so they would be
 	 useless.  */
       if (!targetm.libgcc_floating_mode_supported_p (mode))
@@ -471,7 +471,14 @@ gfc_init_kinds (void)
 	 We round up so as to handle IA-64 __floatreg (RFmode), which is an
 	 82 bit type.  Not to be confused with __float80 (XFmode), which is
 	 an 80 bit type also supported by IA-64.  So XFmode should come out
-	 to be kind=10, and RFmode should come out to be kind=11.  Egads.  */
+	 to be kind=10, and RFmode should come out to be kind=11.  Egads.
+
+	 TODO: The kind calculation has to be modified to support all
+	 three 128-bit floating-point modes on PowerPC as IFmode, KFmode,
+	 and TFmode since the following line would all map to kind=16.
+	 However, currently only float, double, long double, and TFmode
+	 reach this code.
+      */
 
       kind = (GET_MODE_PRECISION (mode) + 7) / 8;
 
@@ -851,6 +858,7 @@ gfc_build_real_type (gfc_real_info *info)
     info->c_long_double = 1;
   if (mode_precision != LONG_DOUBLE_TYPE_SIZE && mode_precision == 128)
     {
+      /* See PR101835.  */
       info->c_float128 = 1;
       gfc_real16_is_float128 = true;
     }

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [Patch v3 Fortran] Fix c_float128 and c_float128_complex on targets with 128-bit long double.
  2021-08-10 22:46           ` [Patch v3 " Sandra Loosemore
@ 2021-08-11  8:05             ` Tobias Burnus
  2021-08-11 14:38               ` Sandra Loosemore
  2021-08-11 10:55             ` Segher Boessenkool
  1 sibling, 1 reply; 15+ messages in thread
From: Tobias Burnus @ 2021-08-11  8:05 UTC (permalink / raw)
  To: Sandra Loosemore, Tobias Burnus, Michael Meissner, fortran,
	gcc-patches, segher, David Edelsohn

On 11.08.21 00:46, Sandra Loosemore wrote:
> On 8/10/21 2:29 AM, Tobias Burnus wrote:
>>
>> [snip]
>>
>> To conclude: I like the code changes (LGTM); the
>> '__float128' -> 'TFmode' comment change also matches the code.
>>
>> However, I think both longer comments need to be updated.
>
> OK.  I used your wording verbatim for the first one.  For the second
> one, I'm still pretty confused as I think it is at least theoretically
> possible on PowerPC to have a target with 64-bit long double (AIX?)
> that also supports the __ibm128 format, and it would be wrong to
> assume that *any* 128-bit mode that's not long double is IEEE.  So I
> decided the best thing is just to replace the FIXME with a pointer to
> the issue I opened yesterday
>
> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101835

LGTM – but ...

> +      /* See PR101835.  */

... I wonder whether your PR reference should have a TODO or FIXME
prefix – or a "for some issue" suffix. Currently, it can be read as if
the PR describes why the code was added – and not for questioning the code.

Tobias

PS: I added some more notes to the PR + extended the subject to make it
easier to find.

-----------------
Siemens Electronic Design Automation GmbH; Anschrift: Arnulfstraße 201, 80634 München; Gesellschaft mit beschränkter Haftung; Geschäftsführer: Thomas Heurung, Frank Thürauf; Sitz der Gesellschaft: München; Registergericht München, HRB 106955

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [Patch v3 Fortran] Fix c_float128 and c_float128_complex on targets with 128-bit long double.
  2021-08-10 22:46           ` [Patch v3 " Sandra Loosemore
  2021-08-11  8:05             ` Tobias Burnus
@ 2021-08-11 10:55             ` Segher Boessenkool
  2021-08-11 11:29               ` Iain Sandoe
  2021-08-11 20:47               ` Michael Meissner
  1 sibling, 2 replies; 15+ messages in thread
From: Segher Boessenkool @ 2021-08-11 10:55 UTC (permalink / raw)
  To: Sandra Loosemore
  Cc: Tobias Burnus, Michael Meissner, fortran, gcc-patches, David Edelsohn

Hi!

On Tue, Aug 10, 2021 at 04:46:11PM -0600, Sandra Loosemore wrote:
> OK.  I used your wording verbatim for the first one.  For the second 
> one, I'm still pretty confused as I think it is at least theoretically 
> possible on PowerPC to have a target with 64-bit long double (AIX?) that 

Some embedded and embedded-like subtargets use 64-bit long double by
default.  You can also configure this on any Power target (not that it
will necessarily work ;-) )

I don't know if any subtarget with default 64-bit long double supports
Fortran.

> also supports the __ibm128 format, and it would be wrong to assume that 
> *any* 128-bit mode that's not long double is IEEE.

Absolutely.  Modes are not types, and types are not modes.  There are
128-bit floating point modes that are not IEEE, there are that are, and
either can be used for long double, or neither.


Segher

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [Patch v3 Fortran] Fix c_float128 and c_float128_complex on targets with 128-bit long double.
  2021-08-11 10:55             ` Segher Boessenkool
@ 2021-08-11 11:29               ` Iain Sandoe
  2021-08-11 11:55                 ` Segher Boessenkool
  2021-08-11 20:47               ` Michael Meissner
  1 sibling, 1 reply; 15+ messages in thread
From: Iain Sandoe @ 2021-08-11 11:29 UTC (permalink / raw)
  To: Segher Boessenkool
  Cc: Sandra Loosemore, Tobias Burnus, gcc-patches, David Edelsohn, fortran

Hi Folks

> On 11 Aug 2021, at 11:55, Segher Boessenkool <segher@kernel.crashing.org> wrote:

> On Tue, Aug 10, 2021 at 04:46:11PM -0600, Sandra Loosemore wrote:
>> OK.  I used your wording verbatim for the first one.  For the second 
>> one, I'm still pretty confused as I think it is at least theoretically 
>> possible on PowerPC to have a target with 64-bit long double (AIX?) that 
> 
> Some embedded and embedded-like subtargets use 64-bit long double by
> default.  You can also configure this on any Power target (not that it
> will necessarily work ;-) )
> 
> I don't know if any subtarget with default 64-bit long double supports
> Fortran.

I realize that this is not directly relevant to unscrambling the PPC 128bit stuff,
but aarch64-apple-darwin2x has only 64b long double and supports gfortran.
(on both the new M1 desktop macOS and embedded iOS)

 - it is not clear to me yet if there will at some point be a transition to a 128b
   long double for at least the desktop version.

So the permutation definitely exists for at least one non-legacy, non-embedded
platform (and gfortran is very much in demand from the new M1 users).

Iain

>> also supports the __ibm128 format, and it would be wrong to assume that 
>> *any* 128-bit mode that's not long double is IEEE.
> 
> Absolutely.  Modes are not types, and types are not modes.  There are
> 128-bit floating point modes that are not IEEE, there are that are, and
> either can be used for long double, or neither.
> 
> 
> Segher


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [Patch v3 Fortran] Fix c_float128 and c_float128_complex on targets with 128-bit long double.
  2021-08-11 11:29               ` Iain Sandoe
@ 2021-08-11 11:55                 ` Segher Boessenkool
  0 siblings, 0 replies; 15+ messages in thread
From: Segher Boessenkool @ 2021-08-11 11:55 UTC (permalink / raw)
  To: Iain Sandoe
  Cc: Sandra Loosemore, Tobias Burnus, gcc-patches, David Edelsohn, fortran

Hi!

On Wed, Aug 11, 2021 at 12:29:06PM +0100, Iain Sandoe wrote:
> > On 11 Aug 2021, at 11:55, Segher Boessenkool <segher@kernel.crashing.org> wrote:
> > On Tue, Aug 10, 2021 at 04:46:11PM -0600, Sandra Loosemore wrote:
> >> OK.  I used your wording verbatim for the first one.  For the second 
> >> one, I'm still pretty confused as I think it is at least theoretically 
> >> possible on PowerPC to have a target with 64-bit long double (AIX?) that 
> > 
> > Some embedded and embedded-like subtargets use 64-bit long double by
> > default.  You can also configure this on any Power target (not that it
> > will necessarily work ;-) )
> > 
> > I don't know if any subtarget with default 64-bit long double supports
> > Fortran.
> 
> I realize that this is not directly relevant to unscrambling the PPC 128bit stuff,
> but aarch64-apple-darwin2x has only 64b long double and supports gfortran.
> (on both the new M1 desktop macOS and embedded iOS)

Yes, but aarch64-apple-darwin2x is not an rs6000 subtarget :-)  There
certainly are many targets with a 64b long double.

>  - it is not clear to me yet if there will at some point be a transition to a 128b
>    long double for at least the desktop version.

Yeah.  I recommend any new target (or target for which this is new) to
use an IEEE QP float as long double, even if just as soft float -- the
advantages are just too great.

> So the permutation definitely exists for at least one non-legacy, non-embedded
> platform (and gfortran is very much in demand from the new M1 users).

M1 is not embedded?  :-)


Segher

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [Patch v3 Fortran] Fix c_float128 and c_float128_complex on targets with 128-bit long double.
  2021-08-11  8:05             ` Tobias Burnus
@ 2021-08-11 14:38               ` Sandra Loosemore
  0 siblings, 0 replies; 15+ messages in thread
From: Sandra Loosemore @ 2021-08-11 14:38 UTC (permalink / raw)
  To: Tobias Burnus, Michael Meissner, fortran, gcc-patches, segher,
	David Edelsohn

On 8/11/21 2:05 AM, Tobias Burnus wrote:
> On 11.08.21 00:46, Sandra Loosemore wrote:
>> On 8/10/21 2:29 AM, Tobias Burnus wrote:
>>>
>>> [snip]
>>>
>>> To conclude: I like the code changes (LGTM); the
>>> '__float128' -> 'TFmode' comment change also matches the code.
>>>
>>> However, I think both longer comments need to be updated.
>>
>> OK.  I used your wording verbatim for the first one.  For the second 
>> one, I'm still pretty confused as I think it is at least theoretically 
>> possible on PowerPC to have a target with 64-bit long double (AIX?) 
>> that also supports the __ibm128 format, and it would be wrong to 
>> assume that *any* 128-bit mode that's not long double is IEEE.  So I 
>> decided the best thing is just to replace the FIXME with a pointer to 
>> the issue I opened yesterday
>>
>> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101835
> 
> LGTM – but ...
> 
>> +      /* See PR101835.  */
> 
> ... I wonder whether your PR reference should have a TODO or FIXME 
> prefix – or a "for some issue" suffix. Currently, it can be read as if 
> the PR describes why the code was added – and not for questioning the code.

OK, thank you.  I've pushed the patch with the addition of "TODO" to 
that comment.

-Sandra

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [Patch v3 Fortran] Fix c_float128 and c_float128_complex on targets with 128-bit long double.
  2021-08-11 10:55             ` Segher Boessenkool
  2021-08-11 11:29               ` Iain Sandoe
@ 2021-08-11 20:47               ` Michael Meissner
  1 sibling, 0 replies; 15+ messages in thread
From: Michael Meissner @ 2021-08-11 20:47 UTC (permalink / raw)
  To: Segher Boessenkool
  Cc: Sandra Loosemore, Tobias Burnus, Michael Meissner, fortran,
	gcc-patches, David Edelsohn

On Wed, Aug 11, 2021 at 05:55:39AM -0500, Segher Boessenkool wrote:
> Hi!
> 
> On Tue, Aug 10, 2021 at 04:46:11PM -0600, Sandra Loosemore wrote:
> > OK.  I used your wording verbatim for the first one.  For the second 
> > one, I'm still pretty confused as I think it is at least theoretically 
> > possible on PowerPC to have a target with 64-bit long double (AIX?) that 
> 
> Some embedded and embedded-like subtargets use 64-bit long double by
> default.  You can also configure this on any Power target (not that it
> will necessarily work ;-) )

It will work on Linux LE systems with glibc 2.32 (it may work with earlier
glibcs).  I've built parallel toolchains with all 3 long double formats.  There
are some tests in the test suite that fail if you configure 64-bit long doubles.

-- 
Michael Meissner, IBM
IBM, M/S 2506R, 550 King Street, Littleton, MA 01460-6245, USA
email: meissner@linux.ibm.com, phone: +1 (978) 899-4797

^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2021-08-11 20:47 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-08-04 20:14 [RFC, Fortran] Fix c_float128 and c_float128_complex on targets with 128-bit long double Sandra Loosemore
2021-08-05 17:33 ` Michael Meissner
2021-08-05 18:19   ` Sandra Loosemore
2021-08-05 20:09     ` Michael Meissner
2021-08-09 21:42       ` [Patch v2 " Sandra Loosemore
2021-08-10  8:29         ` Tobias Burnus
2021-08-10 11:59           ` Segher Boessenkool
2021-08-10 15:58           ` Sandra Loosemore
2021-08-10 22:46           ` [Patch v3 " Sandra Loosemore
2021-08-11  8:05             ` Tobias Burnus
2021-08-11 14:38               ` Sandra Loosemore
2021-08-11 10:55             ` Segher Boessenkool
2021-08-11 11:29               ` Iain Sandoe
2021-08-11 11:55                 ` Segher Boessenkool
2021-08-11 20:47               ` Michael Meissner

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).