public inbox for gcc-patches@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

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