On Fri, Dec 31, 2021 at 03:16:47PM +0100, Jakub Jelinek via Gcc-patches wrote:
> Haven't played enough with it to see if the various *_r17 or *_c17
> API entrypoints are called (but verified abi_kind is right in the
> debugger), in all my attempts so far everything was emitted inline.
Actually playing with that (e.g. for matmul) revealed a brown paper bag
bug in the previous patch, fixed thusly:
2021-12-31 Jakub Jelinek
* gfortran.h (gfc_real_info): Add abi_kind member.
(gfc_type_abi_kind): Declare.
* trans-types.c (gfc_init_kinds): Initialize abi_kind.
* intrinsic.c (gfc_type_abi_kind): New function.
(conv_name): Use it.
* iresolve.c (resolve_transformational, gfc_resolve_abs,
gfc_resolve_char_achar, gfc_resolve_acos, gfc_resolve_acosh,
gfc_resolve_aimag, gfc_resolve_and, gfc_resolve_aint, gfc_resolve_all,
gfc_resolve_anint, gfc_resolve_any, gfc_resolve_asin,
gfc_resolve_asinh, gfc_resolve_atan, gfc_resolve_atanh,
gfc_resolve_atan2, gfc_resolve_bessel_n2, gfc_resolve_ceiling,
gfc_resolve_cmplx, gfc_resolve_complex, gfc_resolve_cos,
gfc_resolve_cosh, gfc_resolve_count, gfc_resolve_dble,
gfc_resolve_dim, gfc_resolve_dot_product, gfc_resolve_dprod,
gfc_resolve_exp, gfc_resolve_floor, gfc_resolve_hypot,
gfc_resolve_int, gfc_resolve_int2, gfc_resolve_int8, gfc_resolve_long,
gfc_resolve_log, gfc_resolve_log10, gfc_resolve_logical,
gfc_resolve_matmul, gfc_resolve_minmax, gfc_resolve_maxloc,
gfc_resolve_findloc, gfc_resolve_maxval, gfc_resolve_merge,
gfc_resolve_minloc, gfc_resolve_minval, gfc_resolve_mod,
gfc_resolve_modulo, gfc_resolve_nearest, gfc_resolve_or,
gfc_resolve_real, gfc_resolve_realpart, gfc_resolve_reshape,
gfc_resolve_sign, gfc_resolve_sin, gfc_resolve_sinh, gfc_resolve_sqrt,
gfc_resolve_tan, gfc_resolve_tanh, gfc_resolve_transpose,
gfc_resolve_trigd, gfc_resolve_xor, gfc_resolve_random_number):
Likewise.
* trans-decl.c (gfc_build_intrinsic_function_decls): Likewise.
--- gcc/fortran/gfortran.h
+++ gcc/fortran/gfortran.h
@@ -2643,7 +2643,7 @@ extern gfc_logical_info gfc_logical_kinds[];
typedef struct
{
mpfr_t epsilon, huge, tiny, subnormal;
- int kind, radix, digits, min_exponent, max_exponent;
+ int kind, abi_kind, radix, digits, min_exponent, max_exponent;
int range, precision;
/* The precision of the type as reported by GET_MODE_PRECISION. */
@@ -3499,6 +3499,12 @@ void gfc_intrinsic_init_1 (void);
void gfc_intrinsic_done_1 (void);
char gfc_type_letter (bt, bool logical_equals_int = false);
+int gfc_type_abi_kind (bt, int);
+static inline int
+gfc_type_abi_kind (gfc_typespec *ts)
+{
+ return gfc_type_abi_kind (ts->type, ts->kind);
+}
gfc_symbol * gfc_get_intrinsic_sub_symbol (const char *);
gfc_symbol *gfc_get_intrinsic_function_symbol (gfc_expr *);
gfc_symbol *gfc_find_intrinsic_symbol (gfc_expr *);
--- gcc/fortran/trans-types.c
+++ gcc/fortran/trans-types.c
@@ -363,6 +363,8 @@ gfc_init_kinds (void)
int i_index, r_index, kind;
bool saw_i4 = false, saw_i8 = false;
bool saw_r4 = false, saw_r8 = false, saw_r10 = false, saw_r16 = false;
+ scalar_mode r16_mode = QImode;
+ scalar_mode composite_mode = QImode;
i_index = 0;
FOR_EACH_MODE_IN_CLASS (int_mode_iter, MODE_INT)
@@ -428,6 +430,10 @@ gfc_init_kinds (void)
if (!targetm.scalar_mode_supported_p (mode))
continue;
+ if (MODE_COMPOSITE_P (mode)
+ && (GET_MODE_PRECISION (mode) + 7) / 8 == 16)
+ composite_mode = mode;
+
/* Only let float, double, long double and TFmode go through.
Runtime support for others is not provided, so they would be
useless. */
@@ -471,7 +477,10 @@ gfc_init_kinds (void)
if (kind == 10)
saw_r10 = true;
if (kind == 16)
- saw_r16 = true;
+ {
+ saw_r16 = true;
+ r16_mode = mode;
+ }
/* Careful we don't stumble a weird internal mode. */
gcc_assert (r_index <= 0 || gfc_real_kinds[r_index-1].kind != kind);
@@ -479,6 +488,7 @@ gfc_init_kinds (void)
gcc_assert (r_index != MAX_REAL_KINDS);
gfc_real_kinds[r_index].kind = kind;
+ gfc_real_kinds[r_index].abi_kind = kind;
gfc_real_kinds[r_index].radix = fmt->b;
gfc_real_kinds[r_index].digits = fmt->p;
gfc_real_kinds[r_index].min_exponent = fmt->emin;
@@ -496,6 +506,19 @@ gfc_init_kinds (void)
r_index += 1;
}
+ /* Detect the powerpc64le-linux case with -mabi=ieeelongdouble, where
+ the long double type is non-MODE_COMPOSITE_P TFmode but one can use
+ -mabi=ibmlongdouble too and get MODE_COMPOSITE_P TFmode with the same
+ precision. For libgfortran calls pretend the IEEE 754 quad TFmode has
+ kind 17 rather than 16 and use kind 16 for the IBM extended format
+ TFmode. */
+ if (composite_mode != QImode && saw_r16 &&