[PATCH, committed] PR 89639, fix testcase for targets without REAL128
Attached patch pushed as cb48166e52c0f159eb80a0666c4847825e294ec0 Confirmed by Dave to make the testcase pass on hppa-unknown-linux-gnu FX 0001-Fortran-Fix-test-on-targets-without-REAL128.patch Description: Binary data
Re: [power-ieee128] gfortran, v2: Introduce gfc_type_abi_kind
Hi Jakub, Actually playing with that (e.g. for matmul) revealed a brown paper bag bug in the previous patch, fixed thusly: OK. Thanks a lot! Best regards Thomas
Re: [power-ieee128] libgfortran: Small progress on the library side
Hi Jakub, Ok for power-ieee128 branch? OK. Thanks for stepping up! I am a little distracted right now, but I think I will also continue working on this for a bit. Best regards Thomas
[power-ieee128] gfortran, v2: Introduce gfc_type_abi_kind
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 &&
[power-ieee128] gfortran: Introduce gfc_type_abi_kind
Hi! The following patch detects the powerpc64le-linux kind == 16 cases and for the -mabi=ieeelongdouble case (no matter whether it is the configured in default or just option used on the command line) uses _r17 or _c17 instead of _r16 or _c17 in the library API names. >From what I can see, e.g. calls to sin on real(kind = 16) works fine with or without this patch (we call __builtin_sinl and the backend uses rs6000_mangle_decl_assembler_name which ensures __sinieee128 is called). 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. What is clearly still broken is IO, where for real(kind=16) a a = 1.0 print *, a end we call _gfortran_transfer_real_write (_parm.0, , 16); for both -mabi=ibmlongdouble and -mabi=ieeelongdouble I don't remember what was the agreement, do we want _gfortran_transfer_real_write (_parm.0, , 17); for the ieeelongdouble case, or some new entrypoint for the abi_kind == 17 real/complex IO? Also, what about kind stored in array descriptors? Shall we use there the abi_kind or kind? I guess at least before the IO case is solved there is no point in checking the testsuite, too many things will be majorly broken... 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): Use gfc_real_kinds[rkinds[rkind]].abi_kind instead of rkinds[rkind]. --- 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,7 @@ 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 (gfc_typespec *); 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 ||
[power-ieee128] libgfortran: Small progress on the library side
Hi! The following patch quiets ../../../libgfortran/generated/in_pack_r17.c:35:1: warning: no previous prototype for ‘internal_pack_r17’ [-Wmissing-prototypes] ../../../libgfortran/generated/in_pack_c17.c:35:1: warning: no previous prototype for ‘internal_pack_c17’ [-Wmissing-prototypes] ../../../libgfortran/generated/in_unpack_r17.c:33:1: warning: no previous prototype for ‘internal_unpack_r17’ [-Wmissing-prototypes] ../../../libgfortran/generated/in_unpack_c17.c:33:1: warning: no previous prototype for ‘internal_unpack_c17’ [-Wmissing-prototypes] ../../../libgfortran/generated/pack_r17.c:73:1: warning: no previous prototype for ‘pack_r17’ [-Wmissing-prototypes] ../../../libgfortran/generated/pack_c17.c:73:1: warning: no previous prototype for ‘pack_c17’ [-Wmissing-prototypes] ../../../libgfortran/generated/unpack_r17.c:34:1: warning: no previous prototype for ‘unpack0_r17’ [-Wmissing-prototypes] ../../../libgfortran/generated/unpack_r17.c:178:1: warning: no previous prototype for ‘unpack1_r17’ [-Wmissing-prototypes] ../../../libgfortran/generated/unpack_c17.c:34:1: warning: no previous prototype for ‘unpack0_c17’ [-Wmissing-prototypes] ../../../libgfortran/generated/unpack_c17.c:178:1: warning: no previous prototype for ‘unpack1_c17’ [-Wmissing-prototypes] ../../../libgfortran/generated/spread_r17.c:34:1: warning: no previous prototype for ‘spread_r17’ [-Wmissing-prototypes] ../../../libgfortran/generated/spread_r17.c:230:1: warning: no previous prototype for ‘spread_scalar_r17’ [-Wmissing-prototypes] ../../../libgfortran/generated/spread_c17.c:34:1: warning: no previous prototype for ‘spread_c17’ [-Wmissing-prototypes] ../../../libgfortran/generated/spread_c17.c:230:1: warning: no previous prototype for ‘spread_scalar_c17’ [-Wmissing-prototypes] ../../../libgfortran/generated/cshift0_r17.c:33:1: warning: no previous prototype for ‘cshift0_r17’ [-Wmissing-prototypes] ../../../libgfortran/generated/cshift0_c17.c:33:1: warning: no previous prototype for ‘cshift0_c17’ [-Wmissing-prototypes] ../../../libgfortran/generated/cshift1_4_r17.c:32:1: warning: no previous prototype for ‘cshift1_4_r17’ [-Wmissing-prototypes] ../../../libgfortran/generated/cshift1_4_c17.c:32:1: warning: no previous prototype for ‘cshift1_4_c17’ [-Wmissing-prototypes] ../../../libgfortran/generated/cshift1_8_r17.c:32:1: warning: no previous prototype for ‘cshift1_8_r17’ [-Wmissing-prototypes] ../../../libgfortran/generated/cshift1_8_c17.c:32:1: warning: no previous prototype for ‘cshift1_8_c17’ [-Wmissing-prototypes] ../../../libgfortran/generated/cshift1_16_r17.c:32:1: warning: no previous prototype for ‘cshift1_16_r17’ [-Wmissing-prototypes] ../../../libgfortran/generated/cshift1_16_c17.c:32:1: warning: no previous prototype for ‘cshift1_16_c17’ [-Wmissing-prototypes] warnings during libgfortran build and exports the new entrypoints. Note, not all of them, clearly e.g. there are fewer *_r17* entrypoints than *_r16* entrypoints, so more work is needed. Ok for power-ieee128 branch? 2021-12-31 Jakub Jelinek * libgfortran.h (internal_pack_r17, internal_pack_c17, internal_unpack_r17, internal_unpack_c17, pack_r17, pack_c17, unpack0_r17, unpack0_c17, unpack1_r17, unpack1_c17, spread_r17, spread_c17, spread_scalar_r17, spread_scalar_c17, cshift0_r17, cshift0_c17, cshift1_4_r17, cshift1_8_r17, cshift1_16_r17, cshift1_4_c17, cshift1_8_c17, cshift1_16_c17): Declare. * gfortran.map (GFORTRAN_12): Export *_r17 and *_c17. --- libgfortran/libgfortran.h +++ libgfortran/libgfortran.h @@ -968,6 +968,11 @@ GFC_REAL_16 *internal_pack_r16 (gfc_array_r16 *); internal_proto(internal_pack_r16); #endif +#if defined HAVE_GFC_REAL_17 +GFC_REAL_17 *internal_pack_r17 (gfc_array_r17 *); +internal_proto(internal_pack_r17); +#endif + GFC_COMPLEX_4 *internal_pack_c4 (gfc_array_c4 *); internal_proto(internal_pack_c4); @@ -984,6 +989,11 @@ GFC_COMPLEX_16 *internal_pack_c16 (gfc_array_c16 *); internal_proto(internal_pack_c16); #endif +#if defined HAVE_GFC_COMPLEX_17 +GFC_COMPLEX_17 *internal_pack_c17 (gfc_array_c17 *); +internal_proto(internal_pack_c17); +#endif + extern void internal_unpack_1 (gfc_array_i1 *, const GFC_INTEGER_1 *); internal_proto(internal_unpack_1); @@ -1017,6 +1027,11 @@ extern void internal_unpack_r16 (gfc_array_r16 *, const GFC_REAL_16 *); internal_proto(internal_unpack_r16); #endif +#if defined HAVE_GFC_REAL_17 +extern void internal_unpack_r17 (gfc_array_r17 *, const GFC_REAL_17 *); +internal_proto(internal_unpack_r17); +#endif + extern void internal_unpack_c4 (gfc_array_c4 *, const GFC_COMPLEX_4 *); internal_proto(internal_unpack_c4); @@ -1033,6 +1048,11 @@ extern void internal_unpack_c16 (gfc_array_c16 *, const GFC_COMPLEX_16 *); internal_proto(internal_unpack_c16); #endif +#if defined HAVE_GFC_COMPLEX_17 +extern void internal_unpack_c17 (gfc_array_c17 *, const GFC_COMPLEX_17 *); +internal_proto(internal_unpack_c17); +#endif +
[pushed] libgfortran: Fix bootstrap on targets without static_assert macro.
Although we build the library with GCC which is known to support _Static_assert this might be done on a system without the macro mapping static_assert to the compiler keyword. The use of static_assert introduced with r12-6126-g3430132f3e82 causes bootstrap to fail on such targets, fixed by using the keyword directly. tested on i686-darwin9 and x86_64-darwin18, without regressions, pushed to master as an obvious bootstrap fix (and as approved by FX). thanks Iain Signed-off-by: Iain Sandoe libgfortran/ChangeLog: * runtime/string.c (gfc_itoa): Use _Static_assert directly instead of via the static_assert macro. --- libgfortran/runtime/string.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libgfortran/runtime/string.c b/libgfortran/runtime/string.c index 21585f48dc9..5bc202320c0 100644 --- a/libgfortran/runtime/string.c +++ b/libgfortran/runtime/string.c @@ -242,8 +242,8 @@ gfc_itoa (GFC_UINTEGER_LARGEST n, char *buffer, size_t len) integers (we would need three calls), but they do suffice for all values up to 2^127, which is the largest that Fortran can produce (-HUGE(0_16)-1) with its signed integer types. */ - static_assert(sizeof(GFC_UINTEGER_LARGEST) <= 2 * sizeof(uint64_t), - "integer too large"); + _Static_assert (sizeof(GFC_UINTEGER_LARGEST) <= 2 * sizeof(uint64_t), + "integer too large"); GFC_UINTEGER_LARGEST r; r = n % TEN19; -- 2.24.3 (Apple Git-128)