From 6f8abf2b9ff4f165a61295cdb3525ce1da2a77c6 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Thu, 10 Mar 2022 10:22:27 +0100 Subject: [PATCH] rs6000: Fix up __SIZEOF_{FLOAT,IBM}128__ defines [PR99708] As mentioned in the PR, right now on powerpc* __SIZEOF_{FLOAT,IBM}128__ macros are predefined unconditionally, because {ieee,ibm}128_float_type_node is always non-NULL, doesn't reflect whether __ieee128 or __ibm128 are actually supported or not. Based on patch review discussions, the following patch: 1) allows __ibm128 to be used in the sources even when !TARGET_FLOAT128_TYPE, as long as long double is double double 2) ensures ibm128_float_type_node is non-NULL only if __ibm128 is supported 3) ensures ieee128_float_type_node is non-NULL only if __ieee128 is supported (aka when TARGET_FLOAT128_TYPE) 4) predefines __SIZEOF_IBM128__ only when ibm128_float_type_node != NULL 5) newly predefines __SIZEOF_IEEE128__ if ieee128_float_type_node != NULL 6) predefines __SIZEOF_FLOAT128__ whenever ieee128_float_type_node != NULL and __float128 macro is predefined to __ieee128 7) removes ptr_*128_float_type_node which nothing uses 8) in order not to ICE during builtin initialization when ibm128_float_type_node == NULL, uses long_double_type_node as fallback for the __builtin_{,un}pack_ibm128 builtins 9) errors when those builtins are called used when ibm128_float_type_node == NULL (during their expansion) 10) moves the {,un}packif -> {,un}packtf remapping for these builtins in expansion earlier, so that we don't ICE on them if not -mabi=ieeelongdouble 2022-03-10 Jakub Jelinek PR target/99708 * config/rs6000/rs6000.h (enum rs6000_builtin_type_index): Remove RS6000_BTI_ptr_ieee128_float and RS6000_BTI_ptr_ibm128_float. (ptr_ieee128_float_type_node, ptr_ibm128_float_type_node): Remove. * config/rs6000/rs6000-builtin.cc (rs6000_type_string): Return "**NULL**" if type_node is NULL first. Handle ieee128_float_type_node. (rs6000_init_builtins): Don't initialize ptr_ieee128_float_type_node and ptr_ibm128_float_type_node. Set ibm128_float_type_node and ieee128_float_type_node to NULL rather than long_double_type_node if they aren't supported. Do support __ibm128 even if !TARGET_FLOAT128_TYPE when long double is double double. (rs6000_expand_builtin): Error if bif_is_ibm128 and !ibm128_float_type_node. Remap RS6000_BIF_{,UN}PACK_IF to RS6000_BIF_{,UN}PACK_TF much earlier and only use bif_is_ibm128 check for it. * config/rs6000/rs6000-c.cc (rs6000_target_modify_macros): Define __SIZEOF_FLOAT128__ here and only iff __float128 macro is defined. (rs6000_cpu_cpp_builtins): Don't define __SIZEOF_FLOAT128__ here. Define __SIZEOF_IBM128__=16 if ieee128_float_type_node is non-NULL. Formatting fix. * config/rs6000/rs6000-gen-builtins.cc: Document ibm128 attribute. (struct attrinfo): Add isibm128 member. (TYPE_MAP_SIZE): Remove. (type_map): Use [] instead of [TYPE_MAP_SIZE]. For "if" use ibm128_float_type_node only if it is non-NULL, otherwise fall back to long_double_type_node. Remove "pif" entry. (parse_bif_attrs): Handle ibm128 attribute and print it for debugging. (write_decls): Output bif_ibm128_bit and bif_is_ibm128. (write_type_node): Use sizeof type_map / sizeof type_map[0] instead of TYPE_MAP_SIZE. (write_bif_static_init): Handle isibm128. * config/rs6000/rs6000-builtins.def: Document ibm128 attribute. (__builtin_pack_ibm128, __builtin_unpack_ibm128): Add ibm128 attribute. * gcc.dg/pr99708.c: New test. * gcc.target/powerpc/pr99708-2.c: New test. * gcc.target/powerpc/convert-fp-128.c (mode_kf): Define only if __FLOAT128_TYPE__ is defined. --- gcc/config/rs6000/rs6000-builtin.cc | 59 ++++++++++++++--------- gcc/config/rs6000/rs6000-builtins.def | 5 +- gcc/config/rs6000/rs6000-c.cc | 8 ++- gcc/config/rs6000/rs6000-gen-builtins.cc | 29 ++++++++--- gcc/config/rs6000/rs6000.h | 4 -- gcc/testsuite/gcc.dg/pr99708.c | 7 +++ gcc/testsuite/gcc.target/powerpc/convert-fp-128.c | 2 + gcc/testsuite/gcc.target/powerpc/pr99708-2.c | 22 +++++++++ 8 files changed, 96 insertions(+), 40 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/pr99708.c create mode 100644 gcc/testsuite/gcc.target/powerpc/pr99708-2.c diff --git a/gcc/config/rs6000/rs6000-builtin.cc b/gcc/config/rs6000/rs6000-builtin.cc index 5d34c1b..e925ba9 100644 --- a/gcc/config/rs6000/rs6000-builtin.cc +++ b/gcc/config/rs6000/rs6000-builtin.cc @@ -402,7 +402,9 @@ rs6000_vector_type (const char *name, tree elt_type, unsigned num_elts) static const char *rs6000_type_string (tree type_node) { - if (type_node == void_type_node) + if (type_node == NULL_TREE) + return "**NULL**"; + else if (type_node == void_type_node) return "void"; else if (type_node == long_integer_type_node) return "long"; @@ -432,6 +434,8 @@ const char *rs6000_type_string (tree type_node) return "ss"; else if (type_node == ibm128_float_type_node) return "__ibm128"; + else if (type_node == ieee128_float_type_node) + return "__ieee128"; else if (type_node == opaque_V4SI_type_node) return "opaque"; else if (POINTER_TYPE_P (type_node)) @@ -709,9 +713,9 @@ rs6000_init_builtins (void) For IEEE 128-bit floating point, always create the type __ieee128. If the user used -mfloat128, rs6000-c.cc will create a define from __float128 to __ieee128. */ - if (TARGET_FLOAT128_TYPE) + if (TARGET_LONG_DOUBLE_128 && (!TARGET_IEEEQUAD || TARGET_FLOAT128_TYPE)) { - if (!TARGET_IEEEQUAD && TARGET_LONG_DOUBLE_128) + if (!TARGET_IEEEQUAD) ibm128_float_type_node = long_double_type_node; else { @@ -721,22 +725,24 @@ rs6000_init_builtins (void) layout_type (ibm128_float_type_node); } t = build_qualified_type (ibm128_float_type_node, TYPE_QUAL_CONST); - ptr_ibm128_float_type_node = build_pointer_type (t); lang_hooks.types.register_builtin_type (ibm128_float_type_node, "__ibm128"); + } + else + ibm128_float_type_node = NULL_TREE; + if (TARGET_FLOAT128_TYPE) + { if (TARGET_IEEEQUAD && TARGET_LONG_DOUBLE_128) ieee128_float_type_node = long_double_type_node; else ieee128_float_type_node = float128_type_node; t = build_qualified_type (ieee128_float_type_node, TYPE_QUAL_CONST); - ptr_ieee128_float_type_node = build_pointer_type (t); lang_hooks.types.register_builtin_type (ieee128_float_type_node, "__ieee128"); } - else - ieee128_float_type_node = ibm128_float_type_node = long_double_type_node; + ieee128_float_type_node = NULL_TREE; /* Vector pair and vector quad support. */ vector_pair_type_node = make_node (OPAQUE_TYPE); @@ -3418,6 +3424,13 @@ rs6000_expand_builtin (tree exp, rtx target, rtx /* subtarget */, return const0_rtx; } + if (bif_is_ibm128 (*bifaddr) && !ibm128_float_type_node) + { + error ("%qs requires %<__ibm128%> type support", + bifaddr->bifname); + return const0_rtx; + } + if (bif_is_cpu (*bifaddr)) return cpu_expand_builtin (fcode, exp, target); @@ -3498,6 +3511,21 @@ rs6000_expand_builtin (tree exp, rtx target, rtx /* subtarget */, gcc_unreachable (); } + if (bif_is_ibm128 (*bifaddr) && TARGET_LONG_DOUBLE_128 && !TARGET_IEEEQUAD) + { + if (fcode == RS6000_BIF_PACK_IF) + { + icode = CODE_FOR_packtf; + fcode = RS6000_BIF_PACK_TF; + uns_fcode = (size_t) fcode; + } + else if (fcode == RS6000_BIF_UNPACK_IF) + { + icode = CODE_FOR_unpacktf; + fcode = RS6000_BIF_UNPACK_TF; + uns_fcode = (size_t) fcode; + } + } /* TRUE iff the built-in function returns void. */ bool void_func = TREE_TYPE (TREE_TYPE (fndecl)) == void_type_node; @@ -3642,23 +3670,6 @@ rs6000_expand_builtin (tree exp, rtx target, rtx /* subtarget */, if (bif_is_mma (*bifaddr)) return mma_expand_builtin (exp, target, icode, fcode); - if (fcode == RS6000_BIF_PACK_IF - && TARGET_LONG_DOUBLE_128 - && !TARGET_IEEEQUAD) - { - icode = CODE_FOR_packtf; - fcode = RS6000_BIF_PACK_TF; - uns_fcode = (size_t) fcode; - } - else if (fcode == RS6000_BIF_UNPACK_IF - && TARGET_LONG_DOUBLE_128 - && !TARGET_IEEEQUAD) - { - icode = CODE_FOR_unpacktf; - fcode = RS6000_BIF_UNPACK_TF; - uns_fcode = (size_t) fcode; - } - if (TREE_TYPE (TREE_TYPE (fndecl)) == void_type_node) target = NULL_RTX; else if (target == 0 diff --git a/gcc/config/rs6000/rs6000-builtins.def b/gcc/config/rs6000/rs6000-builtins.def index ae2760c..221bbc7 100644 --- a/gcc/config/rs6000/rs6000-builtins.def +++ b/gcc/config/rs6000/rs6000-builtins.def @@ -138,6 +138,7 @@ ; lxvrze Needs special handling for load-rightmost, zero-extended ; endian Needs special handling for endianness ; ibmld Restrict usage to the case when TFmode is IBM-128 +; ibm128 Restrict usage to the case where __ibm128 is supported or if ibmld ; ; Each attribute corresponds to extra processing required when ; the built-in is expanded. All such special processing should @@ -234,13 +235,13 @@ MTFSF rs6000_mtfsf {} const __ibm128 __builtin_pack_ibm128 (double, double); - PACK_IF packif {} + PACK_IF packif {ibm128} void __builtin_set_fpscr_rn (const int[0,3]); SET_FPSCR_RN rs6000_set_fpscr_rn {} const double __builtin_unpack_ibm128 (__ibm128, const int<1>); - UNPACK_IF unpackif {} + UNPACK_IF unpackif {ibm128} ; This is redundant with __builtin_unpack_ibm128, as it requires long ; double to be __ibm128. Should probably be deprecated. diff --git a/gcc/config/rs6000/rs6000-c.cc b/gcc/config/rs6000/rs6000-c.cc index d2e480a..3b62b49 100644 --- a/gcc/config/rs6000/rs6000-c.cc +++ b/gcc/config/rs6000/rs6000-c.cc @@ -584,6 +584,10 @@ rs6000_target_modify_macros (bool define_p, HOST_WIDE_INT flags, rs6000_define_or_undefine_macro (true, "__float128=__ieee128"); else rs6000_define_or_undefine_macro (false, "__float128"); + if (ieee128_float_type_node && define_p) + rs6000_define_or_undefine_macro (true, "__SIZEOF_FLOAT128__=16"); + else + rs6000_define_or_undefine_macro (false, "__SIZEOF_FLOAT128__"); } /* OPTION_MASK_FLOAT128_HARDWARE can be turned on if -mcpu=power9 is used or via the target attribute/pragma. */ @@ -623,11 +627,11 @@ rs6000_cpu_cpp_builtins (cpp_reader *pfile) if (TARGET_FRSQRTES) builtin_define ("__RSQRTEF__"); if (TARGET_FLOAT128_TYPE) - builtin_define ("__FLOAT128_TYPE__"); + builtin_define ("__FLOAT128_TYPE__"); if (ibm128_float_type_node) builtin_define ("__SIZEOF_IBM128__=16"); if (ieee128_float_type_node) - builtin_define ("__SIZEOF_FLOAT128__=16"); + builtin_define ("__SIZEOF_IEEE128__=16"); #ifdef TARGET_LIBC_PROVIDES_HWCAP_IN_TCB builtin_define ("__BUILTIN_CPU_SUPPORTS__"); #endif diff --git a/gcc/config/rs6000/rs6000-gen-builtins.cc b/gcc/config/rs6000/rs6000-gen-builtins.cc index 629ead9..0bd7a53 100644 --- a/gcc/config/rs6000/rs6000-gen-builtins.cc +++ b/gcc/config/rs6000/rs6000-gen-builtins.cc @@ -93,6 +93,8 @@ along with GCC; see the file COPYING3. If not see lxvrze Needs special handling for load-rightmost, zero-extended endian Needs special handling for endianness ibmld Restrict usage to the case when TFmode is IBM-128 + ibm128 Restrict usage to the case where __ibm128 is supported or + if ibmld An example stanza might look like this: @@ -392,6 +394,7 @@ struct attrinfo bool islxvrze; bool isendian; bool isibmld; + bool isibm128; }; /* Fields associated with a function prototype (bif or overload). */ @@ -492,8 +495,7 @@ struct typemap maps tokens from a fntype string to a tree type. For example, in "si_ftype_hi" we would map "si" to "intSI_type_node" and map "hi" to "intHI_type_node". */ -#define TYPE_MAP_SIZE 86 -static typemap type_map[TYPE_MAP_SIZE] = +static typemap type_map[] = { { "bi", "bool_int" }, { "bv16qi", "bool_V16QI" }, @@ -506,7 +508,9 @@ static typemap type_map[TYPE_MAP_SIZE] = { "df", "double" }, { "di", "long_long_integer" }, { "hi", "intHI" }, - { "if", "ibm128_float" }, + { "if", "ibm128_float_type_node " + "? ibm128_float_type_node " + ": long_double" }, { "ld", "long_double" }, { "lg", "long_integer" }, { "pbv16qi", "ptr_bool_V16QI" }, @@ -519,7 +523,6 @@ static typemap type_map[TYPE_MAP_SIZE] = { "pdf", "ptr_double" }, { "pdi", "ptr_long_long_integer" }, { "phi", "ptr_intHI" }, - { "pif", "ptr_ibm128_float" }, { "pld", "ptr_long_double" }, { "plg", "ptr_long_integer" }, { "pqi", "ptr_intQI" }, @@ -1439,6 +1442,8 @@ parse_bif_attrs (attrinfo *attrptr) attrptr->isendian = 1; else if (!strcmp (attrname, "ibmld")) attrptr->isibmld = 1; + else if (!strcmp (attrname, "ibm128")) + attrptr->isibm128 = 1; else { diag (oldpos, "unknown attribute.\n"); @@ -1472,14 +1477,15 @@ parse_bif_attrs (attrinfo *attrptr) "ldvec = %d, stvec = %d, reve = %d, pred = %d, htm = %d, " "htmspr = %d, htmcr = %d, mma = %d, quad = %d, pair = %d, " "mmaint = %d, no32bit = %d, 32bit = %d, cpu = %d, ldstmask = %d, " - "lxvrse = %d, lxvrze = %d, endian = %d, ibmdld= %d.\n", + "lxvrse = %d, lxvrze = %d, endian = %d, ibmdld = %d, ibm128 = %d.\n", attrptr->isinit, attrptr->isset, attrptr->isextract, attrptr->isnosoft, attrptr->isldvec, attrptr->isstvec, attrptr->isreve, attrptr->ispred, attrptr->ishtm, attrptr->ishtmspr, attrptr->ishtmcr, attrptr->ismma, attrptr->isquad, attrptr->ispair, attrptr->ismmaint, attrptr->isno32bit, attrptr->is32bit, attrptr->iscpu, attrptr->isldstmask, attrptr->islxvrse, - attrptr->islxvrze, attrptr->isendian, attrptr->isibmld); + attrptr->islxvrze, attrptr->isendian, attrptr->isibmld, + attrptr->isibm128); #endif return PC_OK; @@ -2294,6 +2300,7 @@ write_decls (void) fprintf (header_file, "#define bif_lxvrze_bit\t\t(0x00100000)\n"); fprintf (header_file, "#define bif_endian_bit\t\t(0x00200000)\n"); fprintf (header_file, "#define bif_ibmld_bit\t\t(0x00400000)\n"); + fprintf (header_file, "#define bif_ibm128_bit\t\t(0x00800000)\n"); fprintf (header_file, "\n"); fprintf (header_file, "#define bif_is_init(x)\t\t((x).bifattrs & bif_init_bit)\n"); @@ -2341,6 +2348,8 @@ write_decls (void) "#define bif_is_endian(x)\t((x).bifattrs & bif_endian_bit)\n"); fprintf (header_file, "#define bif_is_ibmld(x)\t((x).bifattrs & bif_ibmld_bit)\n"); + fprintf (header_file, + "#define bif_is_ibm128(x)\t((x).bifattrs & bif_ibm128_bit)\n"); fprintf (header_file, "\n"); fprintf (header_file, @@ -2385,8 +2394,10 @@ write_type_node (char *tok, bool indent) { if (indent) fprintf (init_file, " "); - typemap *entry = (typemap *) bsearch (tok, type_map, TYPE_MAP_SIZE, - sizeof (typemap), typemap_cmp); + typemap *entry + = (typemap *) bsearch (tok, type_map, + sizeof type_map / sizeof type_map[0], + sizeof (typemap), typemap_cmp); if (!entry) fatal ("Type map is inconsistent."); fprintf (init_file, "%s_type_node", entry->value); @@ -2535,6 +2546,8 @@ write_bif_static_init (void) fprintf (init_file, " | bif_endian_bit"); if (bifp->attrs.isibmld) fprintf (init_file, " | bif_ibmld_bit"); + if (bifp->attrs.isibm128) + fprintf (init_file, " | bif_ibm128_bit"); fprintf (init_file, ",\n"); fprintf (init_file, " /* restr_opnd */\t{%d, %d, %d},\n", bifp->proto.restr_opnd[0], bifp->proto.restr_opnd[1], diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h index 17af314..523256a5 100644 --- a/gcc/config/rs6000/rs6000.h +++ b/gcc/config/rs6000/rs6000.h @@ -2444,8 +2444,6 @@ enum rs6000_builtin_type_index RS6000_BTI_ptr_long_double, RS6000_BTI_ptr_dfloat64, RS6000_BTI_ptr_dfloat128, - RS6000_BTI_ptr_ieee128_float, - RS6000_BTI_ptr_ibm128_float, RS6000_BTI_ptr_vector_pair, RS6000_BTI_ptr_vector_quad, RS6000_BTI_ptr_long_long, @@ -2541,8 +2539,6 @@ enum rs6000_builtin_type_index #define ptr_long_double_type_node (rs6000_builtin_types[RS6000_BTI_ptr_long_double]) #define ptr_dfloat64_type_node (rs6000_builtin_types[RS6000_BTI_ptr_dfloat64]) #define ptr_dfloat128_type_node (rs6000_builtin_types[RS6000_BTI_ptr_dfloat128]) -#define ptr_ieee128_float_type_node (rs6000_builtin_types[RS6000_BTI_ptr_ieee128_float]) -#define ptr_ibm128_float_type_node (rs6000_builtin_types[RS6000_BTI_ptr_ibm128_float]) #define ptr_vector_pair_type_node (rs6000_builtin_types[RS6000_BTI_ptr_vector_pair]) #define ptr_vector_quad_type_node (rs6000_builtin_types[RS6000_BTI_ptr_vector_quad]) #define ptr_long_long_integer_type_node (rs6000_builtin_types[RS6000_BTI_ptr_long_long]) diff --git a/gcc/testsuite/gcc.dg/pr99708.c b/gcc/testsuite/gcc.dg/pr99708.c new file mode 100644 index 0000000..b1eaf13 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr99708.c @@ -0,0 +1,7 @@ +/* PR target/99708 */ +/* { dg-do compile } */ + +#ifdef __SIZEOF_FLOAT128__ +__float128 f = 1.0; +#endif +long double l = 1.0; diff --git a/gcc/testsuite/gcc.target/powerpc/convert-fp-128.c b/gcc/testsuite/gcc.target/powerpc/convert-fp-128.c index 69f4a02..3e47334 100644 --- a/gcc/testsuite/gcc.target/powerpc/convert-fp-128.c +++ b/gcc/testsuite/gcc.target/powerpc/convert-fp-128.c @@ -7,7 +7,9 @@ #define mode_sf float #define mode_df double typedef float __attribute__((mode(IF))) mode_if; +#ifdef __FLOAT128_TYPE__ typedef float __attribute__((mode(KF))) mode_kf; +#endif #define mode_sd _Decimal32 #define mode_dd _Decimal64 #define mode_td _Decimal128 diff --git a/gcc/testsuite/gcc.target/powerpc/pr99708-2.c b/gcc/testsuite/gcc.target/powerpc/pr99708-2.c new file mode 100644 index 0000000..e6f9358 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/pr99708-2.c @@ -0,0 +1,22 @@ +/* PR target/99708 */ +/* { dg-do compile } */ + +#ifdef __SIZEOF_IBM128__ +__ibm128 f = 1.0; +#endif +#ifdef __SIZEOF_IEEE128__ +__ieee128 g = 1.0; +#endif +long double h = 1.0; + +void +foo (void) +{ +#ifdef __SIZEOF_IBM128__ + f += 2.0; +#endif +#ifdef __SIZEOF_IEEE128__ + g += 2.0; +#endif + h += 2.0; +} -- 2.7.4