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 <jakub@redhat.com> 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.
This commit is contained in:
parent
ff060ef08c
commit
6f8abf2b9f
8 changed files with 96 additions and 40 deletions
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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],
|
||||
|
|
|
@ -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])
|
||||
|
|
7
gcc/testsuite/gcc.dg/pr99708.c
Normal file
7
gcc/testsuite/gcc.dg/pr99708.c
Normal file
|
@ -0,0 +1,7 @@
|
|||
/* PR target/99708 */
|
||||
/* { dg-do compile } */
|
||||
|
||||
#ifdef __SIZEOF_FLOAT128__
|
||||
__float128 f = 1.0;
|
||||
#endif
|
||||
long double l = 1.0;
|
|
@ -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
|
||||
|
|
22
gcc/testsuite/gcc.target/powerpc/pr99708-2.c
Normal file
22
gcc/testsuite/gcc.target/powerpc/pr99708-2.c
Normal file
|
@ -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;
|
||||
}
|
Loading…
Add table
Reference in a new issue