aboutsummaryrefslogtreecommitdiff
path: root/gcc/fortran
diff options
context:
space:
mode:
authorKewen Lin <linkw@linux.ibm.com>2024-07-17 00:16:59 -0500
committerKewen Lin <linkw@gcc.gnu.org>2024-07-17 00:16:59 -0500
commitde6969fd311307e34904fc1f85603a9d92938974 (patch)
tree1945501bc280d94fcabfe6e5291cb2b8a5f15f4b /gcc/fortran
parent33dca0a4c1c421625cedb2d6105ef1c05f6b774e (diff)
downloadgcc-de6969fd311307e34904fc1f85603a9d92938974.zip
gcc-de6969fd311307e34904fc1f85603a9d92938974.tar.gz
gcc-de6969fd311307e34904fc1f85603a9d92938974.tar.bz2
fortran: Teach get_real_kind_from_node for Power 128 fp modes [PR112993]
Previously effective target fortran_real_c_float128 never passes on Power regardless of the default 128 long double is ibmlongdouble or ieeelongdouble. It's due to that TF mode is always used for kind 16 real, which has precision 127, while the node float128_type_node for c_float128 has 128 type precision, get_real_kind_from_node can't find a matching as it only checks gfc_real_kinds[i].mode_precision and type precision. With changing TFmode/IFmode/KFmode to have the same mode precision 128, now fortran_real_c_float12 can pass with ieeelongdouble enabled by default and test cases guarded with it get tested accordingly. But with ibmlongdouble enabled by default, since TFmode has precision 128 which is the same as type precision 128 of float128_type_node, get_real_kind_from_node considers kind for TFmode matches float128_type_node, but it's wrong as at this time point TFmode is with ibm extended format. So this patch is to teach get_real_kind_from_node to check one more field which can be differentiable from the underlying real format, it can avoid the unexpected matching when there more than one modes have the same precisoin. PR target/112993 gcc/fortran/ChangeLog: * trans-types.cc (get_real_kind_from_node): Consider the case where more than one modes have the same precision.
Diffstat (limited to 'gcc/fortran')
-rw-r--r--gcc/fortran/trans-types.cc16
1 files changed, 15 insertions, 1 deletions
diff --git a/gcc/fortran/trans-types.cc b/gcc/fortran/trans-types.cc
index 0ef6772..f7b80a9 100644
--- a/gcc/fortran/trans-types.cc
+++ b/gcc/fortran/trans-types.cc
@@ -183,7 +183,21 @@ get_real_kind_from_node (tree type)
for (i = 0; gfc_real_kinds[i].kind != 0; i++)
if (gfc_real_kinds[i].mode_precision == TYPE_PRECISION (type))
- return gfc_real_kinds[i].kind;
+ {
+ /* On Power, we have three 128-bit scalar floating-point modes
+ and all of their types have 128 bit type precision, so we
+ should check underlying real format details further. */
+#if defined(HAVE_TFmode) && defined(HAVE_IFmode) && defined(HAVE_KFmode)
+ if (gfc_real_kinds[i].kind == 16)
+ {
+ machine_mode mode = TYPE_MODE (type);
+ const struct real_format *fmt = REAL_MODE_FORMAT (mode);
+ if (fmt->p != gfc_real_kinds[i].digits)
+ continue;
+ }
+#endif
+ return gfc_real_kinds[i].kind;
+ }
return -4;
}