Re: [power-ieee128] gfortran, v2: Introduce gfc_type_abi_kind

2021-12-31 Thread Thomas Koenig via Gcc-patches



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


[power-ieee128] gfortran, v2: Introduce gfc_type_abi_kind

2021-12-31 Thread Jakub Jelinek via Gcc-patches
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 &&