From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-yb1-xb29.google.com (mail-yb1-xb29.google.com [IPv6:2607:f8b0:4864:20::b29]) by sourceware.org (Postfix) with ESMTPS id 3ED15385801A for ; Thu, 13 Oct 2022 21:12:08 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 3ED15385801A Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=gmail.com Received: by mail-yb1-xb29.google.com with SMTP id r3so3505750yba.5 for ; Thu, 13 Oct 2022 14:12:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:from:to:cc:subject:date:message-id:reply-to; bh=LbFMREdN8Oc8zSkMUZVnVc0MI8UYo4LJ55ARNVJd5iw=; b=Jb/ZeshVjHKahz0vGesuvXp8pSBBgxjGV1K6t9OS283KHysyg/yEgQq3KVtmf4s/Cn 7rFfX1iasgVdL1EZF2cchHAKWh/e7pMj70SKj9iyAN82Y7spHhM+ORpJ2x9KWGjiTyUD /si6ZIenP6VYdlw0VeHb/WWZds5oprcg023WylcqxVuyoEGNs7ppVfbtjXgSm2d/17PF ERPhVgPVN+WOqnivgX4HihhTVNY5QE8SyC277i8xpEMEw59u5LbuMWisxIj2nHlF7ept Pp2UmJ6c7nSM6U4YfZouleS1w28/U1KTotcXRx4JXXGnO1A7MgKjOzPBG3WkXAK698EH BmtA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=LbFMREdN8Oc8zSkMUZVnVc0MI8UYo4LJ55ARNVJd5iw=; b=R5ow0Xm4doMdV/7FzxjAjooDlF+Ky1Z3g9qPISkOrE7DHcu6Ttc6DCM0j6C25lCtqu w3W0mri6igJTJk4LaFkop8k7rvA/RFeMT2qMMJIVKu4pJtIVpTuE0Ql1PNRIl6EUliu8 +mmGvnOCcXMRjfnAQWXXUpN54pHb1uKS8MiBcw6TB+L+2RKJ8EkppEzW5zmS/YEk1mda WR+03eBXuupmtiYEVVTldVHGGAZXv0cLAZi4Xwq+IPH10ScPnX67wsyevDsKgK4z7P35 FxS8HN+r1Ubn18bDEX0mkq/MM1coIftfSivrN+sKtuSomcOTRgkH7FSsOgH8M5bIoxLC DGmg== X-Gm-Message-State: ACrzQf3iGBy3WReatjQwCHDi6ACcuDEk0jjOUuONYzCHHG1t0/rPGCfh fuBXXMC34kR8LNWCC41eip5mbPxAvi7A+Pjudnk= X-Google-Smtp-Source: AMsMyM6gCKC4pupQxr4Gkf1LiIq/hqZSNeHHcI6zi6glu5M8PHyyvWPv6xgr2Ani1eguMazOvw9kj/v9cczp58kXHqk= X-Received: by 2002:a5b:105:0:b0:6bc:e5d0:445c with SMTP id 5-20020a5b0105000000b006bce5d0445cmr1649251ybx.261.1665695526010; Thu, 13 Oct 2022 14:12:06 -0700 (PDT) MIME-Version: 1.0 References: <37522634-319a-b471-aa35-87e711b0479e@redhat.com> <55062a15-79a1-f8cf-ed20-25ca8ff42abe@redhat.com> <95f2abba-afb4-bb73-a9f0-b1578b28713a@redhat.com> <5598547f-ce63-6b4d-31e4-a15f57b8f224@redhat.com> In-Reply-To: <5598547f-ce63-6b4d-31e4-a15f57b8f224@redhat.com> From: Uros Bizjak Date: Thu, 13 Oct 2022 23:11:53 +0200 Message-ID: Subject: Re: [PATCH] middle-end, c++, i386, libgcc, v2: std::bfloat16_t and __bf16 arithmetic support To: Jason Merrill Cc: Jakub Jelinek , "Joseph S. Myers" , Richard Biener , Jeff Law , gcc-patches@gcc.gnu.org Content-Type: text/plain; charset="UTF-8" X-Spam-Status: No, score=-1.7 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM,KAM_SHORT,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS,TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: On Thu, Oct 13, 2022 at 9:38 PM Jason Merrill wrote: > > On 10/13/22 12:50, Jakub Jelinek wrote: > > Hi! > > > > On Wed, Oct 05, 2022 at 04:02:25PM -0400, Jason Merrill wrote: > >>> As I wrote earlier, I think we need at least one, __builtin_nans variant > >>> which would be used in libstdc++ > >>> std::numeric_limits::signaling_NaN() implementation. > >>> I think > >>> std::numeric_limits::infinity() can be implemented as > >>> return (__bf16) __builtin_huge_valf (); > >>> and similarly > >>> std::numeric_limits::quiet_NaN() as > >>> return (__bf16) __builtin_nanf (""); > >>> but > >>> return (__bf16) __builtin_nansf (""); > >>> would loose the signaling NaN on the conversion and raise exception, > >>> and as the method is constexpr, > >>> union { unsigned short a; __bf16 b; } u = { 0x7f81 }; > >>> return u.b; > >>> wouldn't work. I can certainly restrict the builtins to the single > >>> one, but wonder whether the suffix for that builtin shouldn't be chosen > >>> such that eventually we could add more builtins if we need to > >>> and don't run into the log with bf16 suffix vs. logb with f16 suffix > >>> ambiguity. > >>> As you said, most of the libstdc++ overloads for std::bfloat16_t then > >>> can use float builtins or library calls under the hood, but std::nextafter > >>> is another case where I think we'll need to have something bfloat16_t > >>> specific, because float ulp isn't bfloat16_t ulp, the latter is much larger. > >> > >> Makes sense. > > > > So, this updated version of the patch adds just a single __builtin_nansf16b > > builtin (or do you want __builtin_nansbf16?). > > 16b sounds fine. > > >>> Based on what Joseph wrote, I'll add bf16/BF16 suffix support for C too > >>> in the next iteration (always with pedwarn in that case). > > > > And implements bf16/BF16 suffixes for C too. > > > >>> I'm afraid too many places rely on all modes of a certain class to be > >>> visible when walking from "narrowest" to "widest" mode, say > >>> FOR_EACH_MODE_IN_CLASS/FOR_EACH_MODE/FOR_EACH_MODE_UNTIL/FOR_EACH_WIDER_MODE > >>> etc. wouldn't work at all if GET_MODE_WIDER_MODE (BFmode) == SFmode > >>> && GET_MODE_WIDER_MODE (HFmode) == SFmode. > >> > >> Yes, it seems they need to change now that their assumptions have been > >> violated. I suppose FOR_EACH_MODE_IN_CLASS would need to change to not use > >> get_wider, and users of FOR_EACH_MODE/FOR_EACH_MODE_UNTIL need to decide > >> whether they want an iteration that uses get_wider (likely with a new name) > >> or not. > > > > And now that the GET_MODE_WIDER_MODE vs. GET_MODE_NEXT_MODE patch is in, > > is updated on top of those changes. > > > > So far lightly tested on x86_64-linux, ok for trunk if it passes full > > bootstrap/regtest on both x86_64-linux and i686-linux? > > LGTM, but a i386 maintainer should review it as well. OK with two changes to cbranch and cstore expanders, as explained inline. Thanks, Uros. > > 2022-10-13 Jakub Jelinek > > > > gcc/ > > * tree-core.h (enum tree_index): Add TI_BFLOAT16_TYPE. > > * tree.h (bfloat16_type_node): Define. > > * tree.cc (excess_precision_type): Promote bfloat16_type_mode > > like float16_type_mode. > > (build_common_tree_nodes): Initialize bfloat16_type_node if > > BFmode is supported. > > * expmed.h (maybe_expand_shift): Declare. > > * expmed.cc (maybe_expand_shift): No longer static. > > * expr.cc (convert_mode_scalar): Don't ICE on BF -> HF or HF -> BF > > conversions. If there is no optab, handle BF -> {DF,XF,TF,HF} > > conversions as separate BF -> SF -> {DF,XF,TF,HF} conversions, add > > -ffast-math generic implementation for BF -> SF and SF -> BF > > conversions. > > * builtin-types.def (BT_BFLOAT16, BT_FN_BFLOAT16_CONST_STRING): New. > > * builtins.def (BUILT_IN_NANSF16B): New builtin. > > * fold-const-call.cc (fold_const_call): Handle CFN_BUILT_IN_NANSF16B. > > * config/i386/i386.cc (classify_argument): Handle E_BCmode. > > (ix86_libgcc_floating_mode_supported_p): Also return true for BFmode > > for -msse2. > > (ix86_mangle_type): Mangle BFmode as DF16b. > > (ix86_invalid_conversion, ix86_invalid_unary_op, > > ix86_invalid_binary_op): Remove. > > (TARGET_INVALID_CONVERSION, TARGET_INVALID_UNARY_OP, > > TARGET_INVALID_BINARY_OP): Don't redefine. > > * config/i386/i386-builtins.cc (ix86_bf16_type_node): Remove. > > (ix86_register_bf16_builtin_type): Use bfloat16_type_node rather than > > ix86_bf16_type_node, only create it if still NULL. > > * config/i386/i386-builtin-types.def (BFLOAT16): Likewise. > > * config/i386/i386.md (cbranchbf4, cstorebf4): New expanders. > > gcc/c-family/ > > * c-cppbuiltin.cc (c_cpp_builtins): If bfloat16_type_node, > > predefine __BFLT16_*__ macros and for C++23 also > > __STDCPP_BFLOAT16_T__. Predefine bfloat16_type_node related > > macros for -fbuilding-libgcc. > > * c-lex.cc (interpret_float): Handle CPP_N_BFLOAT16. > > gcc/c/ > > * c-typeck.cc (convert_arguments): Don't promote __bf16 to > > double. > > gcc/cp/ > > * cp-tree.h (extended_float_type_p): Return true for > > bfloat16_type_node. > > * typeck.cc (cp_compare_floating_point_conversion_ranks): Set > > extended{1,2} if mv{1,2} is bfloat16_type_node. Adjust comment. > > gcc/testsuite/ > > * lib/target-supports.exp (check_effective_target_bfloat16, > > check_effective_target_bfloat16_runtime, add_options_for_bfloat16): > > New. > > * gcc.dg/torture/bfloat16-basic.c: New test. > > * gcc.dg/torture/bfloat16-builtin.c: New test. > > * gcc.dg/torture/bfloat16-builtin-issignaling-1.c: New test. > > * gcc.dg/torture/bfloat16-complex.c: New test. > > * gcc.dg/torture/builtin-issignaling-1.c: Allow to be includable > > from bfloat16-builtin-issignaling-1.c. > > * gcc.dg/torture/floatn-basic.h: Allow to be includable from > > bfloat16-basic.c. > > * gcc.target/i386/vect-bfloat16-typecheck_2.c: Adjust expected > > diagnostics. > > * gcc.target/i386/sse2-bfloat16-scalar-typecheck.c: Likewise. > > * gcc.target/i386/vect-bfloat16-typecheck_1.c: Likewise. > > * g++.target/i386/bfloat_cpp_typecheck.C: Likewise. > > libcpp/ > > * include/cpplib.h (CPP_N_BFLOAT16): Define. > > * expr.cc (interpret_float_suffix): Handle bf16 and BF16 suffixes for > > C++. > > libgcc/ > > * config/i386/t-softfp (softfp_extensions): Add bfsf. > > (softfp_truncations): Add tfbf xfbf dfbf sfbf hfbf. > > (CFLAGS-extendbfsf2.c, CFLAGS-truncsfbf2.c, CFLAGS-truncdfbf2.c, > > CFLAGS-truncxfbf2.c, CFLAGS-trunctfbf2.c, CFLAGS-trunchfbf2.c): Add > > -msse2. > > * config/i386/libgcc-glibc.ver (GCC_13.0.0): Export > > __extendbfsf2 and __trunc{s,d,x,t,h}fbf2. > > * config/i386/sfp-machine.h (_FP_NANSIGN_B): Define. > > * config/i386/64/sfp-machine.h (_FP_NANFRAC_B): Define. > > * config/i386/32/sfp-machine.h (_FP_NANFRAC_B): Define. > > * soft-fp/brain.h: New file. > > * soft-fp/truncsfbf2.c: New file. > > * soft-fp/truncdfbf2.c: New file. > > * soft-fp/truncxfbf2.c: New file. > > * soft-fp/trunctfbf2.c: New file. > > * soft-fp/trunchfbf2.c: New file. > > * soft-fp/truncbfhf2.c: New file. > > * soft-fp/extendbfsf2.c: New file. > > libiberty/ > > * cp-demangle.h (D_BUILTIN_TYPE_COUNT): Increment. > > * cp-demangle.c (cplus_demangle_builtin_types): Add std::bfloat16_t > > entry. > > (cplus_demangle_type): Demangle DF16b. > > * testsuite/demangle-expected (_Z3xxxDF16b): New test. > > > > --- gcc/tree-core.h.jj 2022-10-10 09:31:57.683981308 +0200 > > +++ gcc/tree-core.h 2022-10-13 16:57:08.953775013 +0200 > > @@ -665,6 +665,9 @@ enum tree_index { > > TI_DOUBLE_TYPE, > > TI_LONG_DOUBLE_TYPE, > > > > + /* __bf16 type if supported (used in C++ as std::bfloat16_t). */ > > + TI_BFLOAT16_TYPE, > > + > > /* The _FloatN and _FloatNx types must be consecutive, and in the > > same sequence as the corresponding complex types, which must also > > be consecutive; _FloatN must come before _FloatNx; the order must > > --- gcc/tree.h.jj 2022-10-10 09:31:57.766980149 +0200 > > +++ gcc/tree.h 2022-10-13 17:22:14.728207071 +0200 > > @@ -4291,6 +4291,7 @@ tree_strip_any_location_wrapper (tree ex > > #define float_type_node global_trees[TI_FLOAT_TYPE] > > #define double_type_node global_trees[TI_DOUBLE_TYPE] > > #define long_double_type_node global_trees[TI_LONG_DOUBLE_TYPE] > > +#define bfloat16_type_node global_trees[TI_BFLOAT16_TYPE] > > > > /* Nodes for particular _FloatN and _FloatNx types in sequence. */ > > #define FLOATN_TYPE_NODE(IDX) global_trees[TI_FLOATN_TYPE_FIRST + (IDX)] > > --- gcc/tree.cc.jj 2022-10-10 09:31:57.743980470 +0200 > > +++ gcc/tree.cc 2022-10-13 16:57:08.956774972 +0200 > > @@ -7711,7 +7711,7 @@ excess_precision_type (tree type) > > = (flag_excess_precision == EXCESS_PRECISION_FAST > > ? EXCESS_PRECISION_TYPE_FAST > > : (flag_excess_precision == EXCESS_PRECISION_FLOAT16 > > - ? EXCESS_PRECISION_TYPE_FLOAT16 :EXCESS_PRECISION_TYPE_STANDARD)); > > + ? EXCESS_PRECISION_TYPE_FLOAT16 : EXCESS_PRECISION_TYPE_STANDARD)); > > > > enum flt_eval_method target_flt_eval_method > > = targetm.c.excess_precision (requested_type); > > @@ -7736,6 +7736,9 @@ excess_precision_type (tree type) > > machine_mode float16_type_mode = (float16_type_node > > ? TYPE_MODE (float16_type_node) > > : VOIDmode); > > + machine_mode bfloat16_type_mode = (bfloat16_type_node > > + ? TYPE_MODE (bfloat16_type_node) > > + : VOIDmode); > > machine_mode float_type_mode = TYPE_MODE (float_type_node); > > machine_mode double_type_mode = TYPE_MODE (double_type_node); > > > > @@ -7747,16 +7750,19 @@ excess_precision_type (tree type) > > switch (target_flt_eval_method) > > { > > case FLT_EVAL_METHOD_PROMOTE_TO_FLOAT: > > - if (type_mode == float16_type_mode) > > + if (type_mode == float16_type_mode > > + || type_mode == bfloat16_type_mode) > > return float_type_node; > > break; > > case FLT_EVAL_METHOD_PROMOTE_TO_DOUBLE: > > if (type_mode == float16_type_mode > > + || type_mode == bfloat16_type_mode > > || type_mode == float_type_mode) > > return double_type_node; > > break; > > case FLT_EVAL_METHOD_PROMOTE_TO_LONG_DOUBLE: > > if (type_mode == float16_type_mode > > + || type_mode == bfloat16_type_mode > > || type_mode == float_type_mode > > || type_mode == double_type_mode) > > return long_double_type_node; > > @@ -7774,16 +7780,19 @@ excess_precision_type (tree type) > > switch (target_flt_eval_method) > > { > > case FLT_EVAL_METHOD_PROMOTE_TO_FLOAT: > > - if (type_mode == float16_type_mode) > > + if (type_mode == float16_type_mode > > + || type_mode == bfloat16_type_mode) > > return complex_float_type_node; > > break; > > case FLT_EVAL_METHOD_PROMOTE_TO_DOUBLE: > > if (type_mode == float16_type_mode > > + || type_mode == bfloat16_type_mode > > || type_mode == float_type_mode) > > return complex_double_type_node; > > break; > > case FLT_EVAL_METHOD_PROMOTE_TO_LONG_DOUBLE: > > if (type_mode == float16_type_mode > > + || type_mode == bfloat16_type_mode > > || type_mode == float_type_mode > > || type_mode == double_type_mode) > > return complex_long_double_type_node; > > @@ -9462,6 +9471,17 @@ build_common_tree_nodes (bool signed_cha > > SET_TYPE_MODE (FLOATN_NX_TYPE_NODE (i), mode); > > } > > float128t_type_node = float128_type_node; > > +#ifdef HAVE_BFmode > > + if (REAL_MODE_FORMAT (BFmode) == &arm_bfloat_half_format > > + && targetm.scalar_mode_supported_p (BFmode) > > + && targetm.libgcc_floating_mode_supported_p (BFmode)) > > + { > > + bfloat16_type_node = make_node (REAL_TYPE); > > + TYPE_PRECISION (bfloat16_type_node) = GET_MODE_PRECISION (BFmode); > > + layout_type (bfloat16_type_node); > > + SET_TYPE_MODE (bfloat16_type_node, BFmode); > > + } > > +#endif > > > > float_ptr_type_node = build_pointer_type (float_type_node); > > double_ptr_type_node = build_pointer_type (double_type_node); > > --- gcc/expmed.h.jj 2022-10-03 18:00:53.046735271 +0200 > > +++ gcc/expmed.h 2022-10-13 16:57:08.957774958 +0200 > > @@ -707,6 +707,8 @@ extern rtx expand_variable_shift (enum t > > rtx, tree, rtx, int); > > extern rtx expand_shift (enum tree_code, machine_mode, rtx, poly_int64, rtx, > > int); > > +extern rtx maybe_expand_shift (enum tree_code, machine_mode, rtx, int, rtx, > > + int); > > #ifdef GCC_OPTABS_H > > extern rtx expand_divmod (int, enum tree_code, machine_mode, rtx, rtx, > > rtx, int, enum optab_methods = OPTAB_LIB_WIDEN); > > --- gcc/expmed.cc.jj 2022-10-13 16:22:17.755496384 +0200 > > +++ gcc/expmed.cc 2022-10-13 16:57:08.957774958 +0200 > > @@ -2705,7 +2705,7 @@ expand_shift (enum tree_code code, machi > > > > /* Likewise, but return 0 if that cannot be done. */ > > > > -static rtx > > +rtx > > maybe_expand_shift (enum tree_code code, machine_mode mode, rtx shifted, > > int amount, rtx target, int unsignedp) > > { > > --- gcc/expr.cc.jj 2022-10-06 17:43:47.941502119 +0200 > > +++ gcc/expr.cc 2022-10-13 16:57:09.022774066 +0200 > > @@ -344,7 +344,11 @@ convert_mode_scalar (rtx to, rtx from, i > > gcc_assert ((GET_MODE_PRECISION (from_mode) > > != GET_MODE_PRECISION (to_mode)) > > || (DECIMAL_FLOAT_MODE_P (from_mode) > > - != DECIMAL_FLOAT_MODE_P (to_mode))); > > + != DECIMAL_FLOAT_MODE_P (to_mode)) > > + || (REAL_MODE_FORMAT (from_mode) == &arm_bfloat_half_format > > + && REAL_MODE_FORMAT (to_mode) == &ieee_half_format) > > + || (REAL_MODE_FORMAT (to_mode) == &arm_bfloat_half_format > > + && REAL_MODE_FORMAT (from_mode) == &ieee_half_format)); > > > > if (GET_MODE_PRECISION (from_mode) == GET_MODE_PRECISION (to_mode)) > > /* Conversion between decimal float and binary float, same size. */ > > @@ -364,6 +368,150 @@ convert_mode_scalar (rtx to, rtx from, i > > return; > > } > > > > +#ifdef HAVE_SFmode > > + if (REAL_MODE_FORMAT (from_mode) == &arm_bfloat_half_format > > + && REAL_MODE_FORMAT (SFmode) == &ieee_single_format) > > + { > > + if (GET_MODE_PRECISION (to_mode) > GET_MODE_PRECISION (SFmode)) > > + { > > + /* To cut down on libgcc size, implement > > + BFmode -> {DF,XF,TF}mode conversions by > > + BFmode -> SFmode -> {DF,XF,TF}mode conversions. */ > > + rtx temp = gen_reg_rtx (SFmode); > > + convert_mode_scalar (temp, from, unsignedp); > > + convert_mode_scalar (to, temp, unsignedp); > > + return; > > + } > > + if (REAL_MODE_FORMAT (to_mode) == &ieee_half_format) > > + { > > + /* Similarly, implement BFmode -> HFmode as > > + BFmode -> SFmode -> HFmode conversion where SFmode > > + has superset of BFmode values. We don't need > > + to handle sNaNs by raising exception and turning > > + into into qNaN though, as that can be done in the > > + SFmode -> HFmode conversion too. */ > > + rtx temp = gen_reg_rtx (SFmode); > > + int save_flag_finite_math_only = flag_finite_math_only; > > + flag_finite_math_only = true; > > + convert_mode_scalar (temp, from, unsignedp); > > + flag_finite_math_only = save_flag_finite_math_only; > > + convert_mode_scalar (to, temp, unsignedp); > > + return; > > + } > > + if (to_mode == SFmode > > + && !HONOR_NANS (from_mode) > > + && !HONOR_NANS (to_mode) > > + && optimize_insn_for_speed_p ()) > > + { > > + /* If we don't expect sNaNs, for BFmode -> SFmode we can just > > + shift the bits up. */ > > + machine_mode fromi_mode, toi_mode; > > + if (int_mode_for_size (GET_MODE_BITSIZE (from_mode), > > + 0).exists (&fromi_mode) > > + && int_mode_for_size (GET_MODE_BITSIZE (to_mode), > > + 0).exists (&toi_mode)) > > + { > > + start_sequence (); > > + rtx fromi = lowpart_subreg (fromi_mode, from, from_mode); > > + rtx tof = NULL_RTX; > > + if (fromi) > > + { > > + rtx toi = gen_reg_rtx (toi_mode); > > + convert_mode_scalar (toi, fromi, 1); > > + toi > > + = maybe_expand_shift (LSHIFT_EXPR, toi_mode, toi, > > + GET_MODE_PRECISION (to_mode) > > + - GET_MODE_PRECISION (from_mode), > > + NULL_RTX, 1); > > + if (toi) > > + { > > + tof = lowpart_subreg (to_mode, toi, toi_mode); > > + if (tof) > > + emit_move_insn (to, tof); > > + } > > + } > > + insns = get_insns (); > > + end_sequence (); > > + if (tof) > > + { > > + emit_insn (insns); > > + return; > > + } > > + } > > + } > > + } > > + if (REAL_MODE_FORMAT (from_mode) == &ieee_single_format > > + && REAL_MODE_FORMAT (to_mode) == &arm_bfloat_half_format > > + && !HONOR_NANS (from_mode) > > + && !HONOR_NANS (to_mode) > > + && !flag_rounding_math > > + && optimize_insn_for_speed_p ()) > > + { > > + /* If we don't expect qNaNs nor sNaNs and can assume rounding > > + to nearest, we can expand the conversion inline as > > + (fromi + 0x7fff + ((fromi >> 16) & 1)) >> 16. */ > > + machine_mode fromi_mode, toi_mode; > > + if (int_mode_for_size (GET_MODE_BITSIZE (from_mode), > > + 0).exists (&fromi_mode) > > + && int_mode_for_size (GET_MODE_BITSIZE (to_mode), > > + 0).exists (&toi_mode)) > > + { > > + start_sequence (); > > + rtx fromi = lowpart_subreg (fromi_mode, from, from_mode); > > + rtx tof = NULL_RTX; > > + do > > + { > > + if (!fromi) > > + break; > > + int shift = (GET_MODE_PRECISION (from_mode) > > + - GET_MODE_PRECISION (to_mode)); > > + rtx temp1 > > + = maybe_expand_shift (RSHIFT_EXPR, fromi_mode, fromi, > > + shift, NULL_RTX, 1); > > + if (!temp1) > > + break; > > + rtx temp2 > > + = expand_binop (fromi_mode, and_optab, temp1, const1_rtx, > > + NULL_RTX, 1, OPTAB_DIRECT); > > + if (!temp2) > > + break; > > + rtx temp3 > > + = expand_binop (fromi_mode, add_optab, fromi, > > + gen_int_mode ((HOST_WIDE_INT_1U > > + << (shift - 1)) - 1, > > + fromi_mode), NULL_RTX, > > + 1, OPTAB_DIRECT); > > + if (!temp3) > > + break; > > + rtx temp4 > > + = expand_binop (fromi_mode, add_optab, temp3, temp2, > > + NULL_RTX, 1, OPTAB_DIRECT); > > + if (!temp4) > > + break; > > + rtx temp5 = maybe_expand_shift (RSHIFT_EXPR, fromi_mode, > > + temp4, shift, NULL_RTX, 1); > > + if (!temp5) > > + break; > > + rtx temp6 = lowpart_subreg (toi_mode, temp5, fromi_mode); > > + if (!temp6) > > + break; > > + tof = lowpart_subreg (to_mode, force_reg (toi_mode, temp6), > > + toi_mode); > > + if (tof) > > + emit_move_insn (to, tof); > > + } > > + while (0); > > + insns = get_insns (); > > + end_sequence (); > > + if (tof) > > + { > > + emit_insn (insns); > > + return; > > + } > > + } > > + } > > +#endif > > + > > /* Otherwise use a libcall. */ > > libcall = convert_optab_libfunc (tab, to_mode, from_mode); > > > > --- gcc/builtin-types.def.jj 2022-10-03 18:00:52.658740505 +0200 > > +++ gcc/builtin-types.def 2022-10-13 17:09:52.930317869 +0200 > > @@ -82,6 +82,9 @@ DEF_PRIMITIVE_TYPE (BT_UNWINDWORD, (*lan > > DEF_PRIMITIVE_TYPE (BT_FLOAT, float_type_node) > > DEF_PRIMITIVE_TYPE (BT_DOUBLE, double_type_node) > > DEF_PRIMITIVE_TYPE (BT_LONGDOUBLE, long_double_type_node) > > +DEF_PRIMITIVE_TYPE (BT_BFLOAT16, (bfloat16_type_node > > + ? bfloat16_type_node > > + : error_mark_node)) > > DEF_PRIMITIVE_TYPE (BT_FLOAT16, (float16_type_node > > ? float16_type_node > > : error_mark_node)) > > @@ -264,6 +267,7 @@ DEF_FUNCTION_TYPE_1 (BT_FN_FLOAT_CONST_S > > DEF_FUNCTION_TYPE_1 (BT_FN_DOUBLE_CONST_STRING, BT_DOUBLE, BT_CONST_STRING) > > DEF_FUNCTION_TYPE_1 (BT_FN_LONGDOUBLE_CONST_STRING, > > BT_LONGDOUBLE, BT_CONST_STRING) > > +DEF_FUNCTION_TYPE_1 (BT_FN_BFLOAT16_CONST_STRING, BT_BFLOAT16, BT_CONST_STRING) > > DEF_FUNCTION_TYPE_1 (BT_FN_FLOAT16_CONST_STRING, BT_FLOAT16, BT_CONST_STRING) > > DEF_FUNCTION_TYPE_1 (BT_FN_FLOAT32_CONST_STRING, BT_FLOAT32, BT_CONST_STRING) > > DEF_FUNCTION_TYPE_1 (BT_FN_FLOAT64_CONST_STRING, BT_FLOAT64, BT_CONST_STRING) > > --- gcc/builtins.def.jj 2022-10-03 18:00:52.679740221 +0200 > > +++ gcc/builtins.def 2022-10-13 17:09:05.633962625 +0200 > > @@ -514,6 +514,7 @@ DEF_GCC_BUILTIN (BUILT_IN_NANSF, > > DEF_GCC_BUILTIN (BUILT_IN_NANSL, "nansl", BT_FN_LONGDOUBLE_CONST_STRING, ATTR_CONST_NOTHROW_NONNULL) > > DEF_GCC_FLOATN_NX_BUILTINS (BUILT_IN_NANS, "nans", NAN_TYPE, ATTR_CONST_NOTHROW_NONNULL) > > #undef NAN_TYPE > > +DEF_GCC_BUILTIN (BUILT_IN_NANSF16B, "nansf16b", BT_FN_BFLOAT16_CONST_STRING, ATTR_CONST_NOTHROW_NONNULL) > > DEF_GCC_BUILTIN (BUILT_IN_NANSD32, "nansd32", BT_FN_DFLOAT32_CONST_STRING, ATTR_CONST_NOTHROW_NONNULL) > > DEF_GCC_BUILTIN (BUILT_IN_NANSD64, "nansd64", BT_FN_DFLOAT64_CONST_STRING, ATTR_CONST_NOTHROW_NONNULL) > > DEF_GCC_BUILTIN (BUILT_IN_NANSD128, "nansd128", BT_FN_DFLOAT128_CONST_STRING, ATTR_CONST_NOTHROW_NONNULL) > > --- gcc/fold-const-call.cc.jj 2022-09-03 09:35:41.107989686 +0200 > > +++ gcc/fold-const-call.cc 2022-10-13 17:20:59.579229947 +0200 > > @@ -1301,6 +1301,7 @@ fold_const_call (combined_fn fn, tree ty > > > > CASE_CFN_NANS: > > CASE_FLT_FN_FLOATN_NX (CFN_BUILT_IN_NANS): > > + case CFN_BUILT_IN_NANSF16B: > > case CFN_BUILT_IN_NANSD32: > > case CFN_BUILT_IN_NANSD64: > > case CFN_BUILT_IN_NANSD128: > > --- gcc/config/i386/i386.cc.jj 2022-10-03 18:00:52.942736674 +0200 > > +++ gcc/config/i386/i386.cc 2022-10-13 16:57:09.092773105 +0200 > > @@ -2423,6 +2423,7 @@ classify_argument (machine_mode mode, co > > classes[1] = X86_64_SSEUP_CLASS; > > return 2; > > case E_HCmode: > > + case E_BCmode: > > classes[0] = X86_64_SSE_CLASS; > > if (!(bit_offset % 64)) > > return 1; > > @@ -22428,7 +22429,7 @@ ix86_libgcc_floating_mode_supported_p (s > > be defined by the C front-end for AVX512FP16 intrinsics. We will > > issue an error in ix86_expand_move for HFmode if AVX512FP16 isn't > > enabled. */ > > - return ((mode == HFmode && TARGET_SSE2) > > + return (((mode == HFmode || mode == BFmode) && TARGET_SSE2) > > ? true > > : default_libgcc_floating_mode_supported_p (mode)); > > } > > @@ -22731,7 +22732,7 @@ ix86_mangle_type (const_tree type) > > switch (TYPE_MODE (type)) > > { > > case E_BFmode: > > - return "u6__bf16"; > > + return "DF16b"; > > case E_HFmode: > > /* _Float16 is "DF16_". > > Align with clang's decision in https://reviews.llvm.org/D33719. */ > > @@ -22747,55 +22748,6 @@ ix86_mangle_type (const_tree type) > > } > > } > > > > -/* Return the diagnostic message string if conversion from FROMTYPE to > > - TOTYPE is not allowed, NULL otherwise. */ > > - > > -static const char * > > -ix86_invalid_conversion (const_tree fromtype, const_tree totype) > > -{ > > - if (element_mode (fromtype) != element_mode (totype)) > > - { > > - /* Do no allow conversions to/from BFmode scalar types. */ > > - if (TYPE_MODE (fromtype) == BFmode) > > - return N_("invalid conversion from type %<__bf16%>"); > > - if (TYPE_MODE (totype) == BFmode) > > - return N_("invalid conversion to type %<__bf16%>"); > > - } > > - > > - /* Conversion allowed. */ > > - return NULL; > > -} > > - > > -/* Return the diagnostic message string if the unary operation OP is > > - not permitted on TYPE, NULL otherwise. */ > > - > > -static const char * > > -ix86_invalid_unary_op (int op, const_tree type) > > -{ > > - /* Reject all single-operand operations on BFmode except for &. */ > > - if (element_mode (type) == BFmode && op != ADDR_EXPR) > > - return N_("operation not permitted on type %<__bf16%>"); > > - > > - /* Operation allowed. */ > > - return NULL; > > -} > > - > > -/* Return the diagnostic message string if the binary operation OP is > > - not permitted on TYPE1 and TYPE2, NULL otherwise. */ > > - > > -static const char * > > -ix86_invalid_binary_op (int op ATTRIBUTE_UNUSED, const_tree type1, > > - const_tree type2) > > -{ > > - /* Reject all 2-operand operations on BFmode. */ > > - if (element_mode (type1) == BFmode > > - || element_mode (type2) == BFmode) > > - return N_("operation not permitted on type %<__bf16%>"); > > - > > - /* Operation allowed. */ > > - return NULL; > > -} > > - > > static GTY(()) tree ix86_tls_stack_chk_guard_decl; > > > > static tree > > @@ -24853,15 +24805,6 @@ ix86_libgcc_floating_mode_supported_p > > #undef TARGET_MANGLE_TYPE > > #define TARGET_MANGLE_TYPE ix86_mangle_type > > > > -#undef TARGET_INVALID_CONVERSION > > -#define TARGET_INVALID_CONVERSION ix86_invalid_conversion > > - > > -#undef TARGET_INVALID_UNARY_OP > > -#define TARGET_INVALID_UNARY_OP ix86_invalid_unary_op > > - > > -#undef TARGET_INVALID_BINARY_OP > > -#define TARGET_INVALID_BINARY_OP ix86_invalid_binary_op > > - > > #undef TARGET_STACK_PROTECT_GUARD > > #define TARGET_STACK_PROTECT_GUARD ix86_stack_protect_guard > > > > --- gcc/config/i386/i386-builtins.cc.jj 2022-10-03 18:00:52.918736997 +0200 > > +++ gcc/config/i386/i386-builtins.cc 2022-10-13 16:57:09.119772735 +0200 > > @@ -126,7 +126,6 @@ BDESC_VERIFYS (IX86_BUILTIN_MAX, > > static GTY(()) tree ix86_builtin_type_tab[(int) IX86_BT_LAST_CPTR + 1]; > > > > tree ix86_float16_type_node = NULL_TREE; > > -tree ix86_bf16_type_node = NULL_TREE; > > tree ix86_bf16_ptr_type_node = NULL_TREE; > > > > /* Retrieve an element from the above table, building some of > > @@ -1372,16 +1371,18 @@ ix86_register_float16_builtin_type (void > > static void > > ix86_register_bf16_builtin_type (void) > > { > > - ix86_bf16_type_node = make_node (REAL_TYPE); > > - TYPE_PRECISION (ix86_bf16_type_node) = 16; > > - SET_TYPE_MODE (ix86_bf16_type_node, BFmode); > > - layout_type (ix86_bf16_type_node); > > + if (bfloat16_type_node == NULL_TREE) > > + { > > + bfloat16_type_node = make_node (REAL_TYPE); > > + TYPE_PRECISION (bfloat16_type_node) = 16; > > + SET_TYPE_MODE (bfloat16_type_node, BFmode); > > + layout_type (bfloat16_type_node); > > + } > > > > if (!maybe_get_identifier ("__bf16") && TARGET_SSE2) > > { > > - lang_hooks.types.register_builtin_type (ix86_bf16_type_node, > > - "__bf16"); > > - ix86_bf16_ptr_type_node = build_pointer_type (ix86_bf16_type_node); > > + lang_hooks.types.register_builtin_type (bfloat16_type_node, "__bf16"); > > + ix86_bf16_ptr_type_node = build_pointer_type (bfloat16_type_node); > > } > > } > > > > --- gcc/config/i386/i386-builtin-types.def.jj 2022-10-03 18:00:52.894737321 +0200 > > +++ gcc/config/i386/i386-builtin-types.def 2022-10-13 16:57:09.139772460 +0200 > > @@ -69,7 +69,7 @@ DEF_PRIMITIVE_TYPE (UINT16, short_unsign > > DEF_PRIMITIVE_TYPE (INT64, long_long_integer_type_node) > > DEF_PRIMITIVE_TYPE (UINT64, long_long_unsigned_type_node) > > DEF_PRIMITIVE_TYPE (FLOAT16, ix86_float16_type_node) > > -DEF_PRIMITIVE_TYPE (BFLOAT16, ix86_bf16_type_node) > > +DEF_PRIMITIVE_TYPE (BFLOAT16, bfloat16_type_node) > > DEF_PRIMITIVE_TYPE (FLOAT, float_type_node) > > DEF_PRIMITIVE_TYPE (DOUBLE, double_type_node) > > DEF_PRIMITIVE_TYPE (FLOAT80, float80_type_node) > > --- gcc/config/i386/i386.md.jj 2022-10-11 15:57:05.005762022 +0200 > > +++ gcc/config/i386/i386.md 2022-10-13 16:57:09.187771801 +0200 > > @@ -1644,6 +1644,48 @@ (define_expand "cbranch4" > > DONE; > > }) > > > > +(define_expand "cbranchbf4" > > + [(set (reg:CC FLAGS_REG) > > + (compare:CC (match_operand:BF 1 "cmp_fp_expander_operand") > > + (match_operand:BF 2 "cmp_fp_expander_operand"))) > > + (set (pc) (if_then_else > > + (match_operator 0 "comparison_operator" > > + [(reg:CC FLAGS_REG) > > + (const_int 0)]) > > + (label_ref (match_operand 3)) > > + (pc)))] > > + "" > > +{ > > + rtx op1 = gen_lowpart (HImode, operands[1]); > > + if (CONST_INT_P (op1)) > > + op1 = simplify_const_unary_operation (FLOAT_EXTEND, SFmode, > > + operands[1], BFmode); > > + else > > + { > > + rtx t1 = gen_reg_rtx (SImode); > > + emit_insn (gen_zero_extendhisi2 (t1, op1)); > > + emit_insn (gen_ashlsi3 (t1, t1, GEN_INT (16))); > > + op1 = gen_lowpart (SFmode, t1); > > + } > > + rtx op2 = gen_lowpart (HImode, operands[2]); > > + if (CONST_INT_P (op2)) > > + op2 = simplify_const_unary_operation (FLOAT_EXTEND, SFmode, > > + operands[2], BFmode); > > + else > > + { > > + rtx t2 = gen_reg_rtx (SImode); > > + emit_insn (gen_zero_extendhisi2 (t2, op2)); > > + emit_insn (gen_ashlsi3 (t2, t2, GEN_INT (16))); > > + op2 = gen_lowpart (SFmode, t2); > > + } > > + do_compare_rtx_and_jump (op1, op2, GET_CODE (operands[0]), 0, > > + SFmode, NULL_RTX, NULL, > > + as_a (operands[3]), > > + /* Unfortunately this isn't propagated. */ > > + profile_probability::even ()); You could use ix86_expand_branch instead of do_compare_rtx_and_jump here. This would expand in SFmode, so insn condition from cbranchsf4 should be copied here: "TARGET_80387 || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)" Additionally, ix86_fp_comparison_operator predicate should be used for operator0. Basically, just copy predicates from cbranchsf4 as we are effectively expanding the SFmode compare & branch. > > + DONE; > > +}) > > + > > (define_expand "cstorehf4" > > [(set (reg:CC FLAGS_REG) > > (compare:CC (match_operand:HF 2 "cmp_fp_expander_operand") > > @@ -1659,6 +1701,45 @@ (define_expand "cstorehf4" > > DONE; > > }) > > > > +(define_expand "cstorebf4" > > + [(set (reg:CC FLAGS_REG) > > + (compare:CC (match_operand:BF 2 "cmp_fp_expander_operand") > > + (match_operand:BF 3 "cmp_fp_expander_operand"))) > > + (set (match_operand:QI 0 "register_operand") > > + (match_operator 1 "comparison_operator" > > + [(reg:CC FLAGS_REG) > > + (const_int 0)]))] > > + "" > > +{ > > + rtx op1 = gen_lowpart (HImode, operands[2]); > > + if (CONST_INT_P (op1)) > > + op1 = simplify_const_unary_operation (FLOAT_EXTEND, SFmode, > > + operands[2], BFmode); > > + else > > + { > > + rtx t1 = gen_reg_rtx (SImode); > > + emit_insn (gen_zero_extendhisi2 (t1, op1)); > > + emit_insn (gen_ashlsi3 (t1, t1, GEN_INT (16))); > > + op1 = gen_lowpart (SFmode, t1); > > + } > > + rtx op2 = gen_lowpart (HImode, operands[3]); > > + if (CONST_INT_P (op2)) > > + op2 = simplify_const_unary_operation (FLOAT_EXTEND, SFmode, > > + operands[3], BFmode); > > + else > > + { > > + rtx t2 = gen_reg_rtx (SImode); > > + emit_insn (gen_zero_extendhisi2 (t2, op2)); > > + emit_insn (gen_ashlsi3 (t2, t2, GEN_INT (16))); > > + op2 = gen_lowpart (SFmode, t2); > > + } Similar to cbranch above, use ix86_expand_setcc and copy predicates from cstoresf4. Uros. > > + rtx res = emit_store_flag_force (operands[0], GET_CODE (operands[1]), > > + op1, op2, SFmode, 0, 1); > > + if (!rtx_equal_p (res, operands[0])) > > + emit_move_insn (operands[0], res); > > + DONE; > > +}) > > + > > (define_expand "cstore4" > > [(set (reg:CC FLAGS_REG) > > (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand") > > --- gcc/c-family/c-cppbuiltin.cc.jj 2022-10-13 08:41:04.718165419 +0200 > > +++ gcc/c-family/c-cppbuiltin.cc 2022-10-13 17:51:07.722665421 +0200 > > @@ -1260,6 +1260,13 @@ c_cpp_builtins (cpp_reader *pfile) > > builtin_define_float_constants (prefix, ggc_strdup (csuffix), "%s", > > csuffix, FLOATN_NX_TYPE_NODE (i)); > > } > > + if (bfloat16_type_node) > > + { > > + if (c_dialect_cxx () && cxx_dialect > cxx20) > > + cpp_define (pfile, "__STDCPP_BFLOAT16_T__=1"); > > + builtin_define_float_constants ("BFLT16", "BF16", "%s", > > + "BF16", bfloat16_type_node); > > + } > > > > /* For float.h. */ > > if (targetm.decimal_float_supported_p ()) > > @@ -1370,6 +1377,12 @@ c_cpp_builtins (cpp_reader *pfile) > > suffix[0] = 'l'; > > memcpy (float_h_prefix, "LDBL", 5); > > } > > + else if (bfloat16_type_node > > + && mode == TYPE_MODE (bfloat16_type_node)) > > + { > > + memcpy (suffix, "bf16", 5); > > + memcpy (float_h_prefix, "BFLT16", 7); > > + } > > else > > { > > bool found_suffix = false; > > @@ -1396,22 +1409,28 @@ c_cpp_builtins (cpp_reader *pfile) > > machine_mode float16_type_mode = (float16_type_node > > ? TYPE_MODE (float16_type_node) > > : VOIDmode); > > + machine_mode bfloat16_type_mode = (bfloat16_type_node > > + ? TYPE_MODE (bfloat16_type_node) > > + : VOIDmode); > > switch (targetm.c.excess_precision > > (EXCESS_PRECISION_TYPE_IMPLICIT)) > > { > > case FLT_EVAL_METHOD_UNPREDICTABLE: > > case FLT_EVAL_METHOD_PROMOTE_TO_LONG_DOUBLE: > > excess_precision = (mode == float16_type_mode > > + || mode == bfloat16_type_mode > > || mode == TYPE_MODE (float_type_node) > > || mode == TYPE_MODE (double_type_node)); > > break; > > > > case FLT_EVAL_METHOD_PROMOTE_TO_DOUBLE: > > excess_precision = (mode == float16_type_mode > > + || mode == bfloat16_type_mode > > || mode == TYPE_MODE (float_type_node)); > > break; > > case FLT_EVAL_METHOD_PROMOTE_TO_FLOAT: > > - excess_precision = mode == float16_type_mode; > > + excess_precision = (mode == float16_type_mode > > + || mode == bfloat16_type_mode); > > break; > > case FLT_EVAL_METHOD_PROMOTE_TO_FLOAT16: > > excess_precision = false; > > --- gcc/c-family/c-lex.cc.jj 2022-10-13 16:21:52.548842666 +0200 > > +++ gcc/c-family/c-lex.cc 2022-10-13 16:59:51.778540099 +0200 > > @@ -1000,6 +1000,22 @@ interpret_float (const cpp_token *token, > > pedwarn (input_location, OPT_Wpedantic, > > "non-standard suffix on floating constant"); > > } > > + else if ((flags & CPP_N_BFLOAT16) != 0) > > + { > > + type = bfloat16_type_node; > > + if (type == NULL_TREE) > > + { > > + error ("unsupported non-standard suffix on floating constant"); > > + return error_mark_node; > > + } > > + if (!c_dialect_cxx ()) > > + pedwarn (input_location, OPT_Wpedantic, > > + "non-standard suffix on floating constant"); > > + else if (cxx_dialect < cxx23) > > + pedwarn (input_location, OPT_Wpedantic, > > + "% or % suffix on floating constant only " > > + "available with %<-std=c++2b%> or %<-std=gnu++2b%>"); > > + } > > else if ((flags & CPP_N_WIDTH) == CPP_N_LARGE) > > type = long_double_type_node; > > else if ((flags & CPP_N_WIDTH) == CPP_N_SMALL > > --- gcc/c/c-typeck.cc.jj 2022-10-06 17:43:47.900502672 +0200 > > +++ gcc/c/c-typeck.cc 2022-10-13 16:57:09.226771266 +0200 > > @@ -3678,6 +3678,9 @@ convert_arguments (location_t loc, vec > promote_float_arg = false; > > break; > > } > > + /* Don't promote __bf16 either. */ > > + if (TYPE_MAIN_VARIANT (valtype) == bfloat16_type_node) > > + promote_float_arg = false; > > } > > > > if (type != NULL_TREE) > > --- gcc/cp/cp-tree.h.jj 2022-10-13 16:21:52.600841952 +0200 > > +++ gcc/cp/cp-tree.h 2022-10-13 16:57:09.241771060 +0200 > > @@ -8741,6 +8741,8 @@ extended_float_type_p (tree type) > > for (int i = 0; i < NUM_FLOATN_NX_TYPES; ++i) > > if (type == FLOATN_TYPE_NODE (i)) > > return true; > > + if (type == bfloat16_type_node) > > + return true; > > return false; > > } > > > > --- gcc/cp/typeck.cc.jj 2022-10-13 16:21:52.642841375 +0200 > > +++ gcc/cp/typeck.cc 2022-10-13 16:57:09.269770676 +0200 > > @@ -293,6 +293,10 @@ cp_compare_floating_point_conversion_ran > > if (mv2 == FLOATN_NX_TYPE_NODE (i)) > > extended2 = i + 1; > > } > > + if (mv1 == bfloat16_type_node) > > + extended1 = true; > > + if (mv2 == bfloat16_type_node) > > + extended2 = true; > > if (extended2 && !extended1) > > { > > int ret = cp_compare_floating_point_conversion_ranks (t2, t1); > > @@ -390,7 +394,9 @@ cp_compare_floating_point_conversion_ran > > if (cnt > 1 && mv2 == long_double_type_node) > > return -2; > > /* Otherwise, they have equal rank, but extended types > > - (other than std::bfloat16_t) have higher subrank. */ > > + (other than std::bfloat16_t) have higher subrank. > > + std::bfloat16_t shouldn't have equal rank to any standard > > + floating point type. */ > > return 1; > > } > > > > --- gcc/testsuite/lib/target-supports.exp.jj 2022-10-11 14:50:14.472773574 +0200 > > +++ gcc/testsuite/lib/target-supports.exp 2022-10-13 16:57:09.270770662 +0200 > > @@ -3416,6 +3416,22 @@ proc check_effective_target_base_quadflo > > return 1 > > } > > > > +# Return 1 if the target supports the __bf16 type, 0 otherwise. > > + > > +proc check_effective_target_bfloat16 {} { > > + return [check_no_compiler_messages_nocache bfloat16 object { > > + __bf16 foo (__bf16 x) { return x + x; } > > + } [add_options_for_bfloat16 ""]] > > +} > > + > > +proc check_effective_target_bfloat16_runtime {} { > > + return [check_effective_target_bfloat16] > > +} > > + > > +proc add_options_for_bfloat16 { flags } { > > + return "$flags" > > +} > > + > > # Return 1 if the target supports all four forms of fused multiply-add > > # (fma, fms, fnma, and fnms) for both float and double. > > > > --- gcc/testsuite/gcc.dg/torture/bfloat16-basic.c.jj 2022-10-13 16:57:09.271770648 +0200 > > +++ gcc/testsuite/gcc.dg/torture/bfloat16-basic.c 2022-10-13 17:32:28.531884882 +0200 > > @@ -0,0 +1,11 @@ > > +/* Test __bf16. */ > > +/* { dg-do run } */ > > +/* { dg-options "" } */ > > +/* { dg-add-options bfloat16 } */ > > +/* { dg-require-effective-target bfloat16_runtime } */ > > + > > +#define TYPE __bf16 > > +#define CST(C) CONCAT (C, bf16) > > +#define CSTU(C) CONCAT (C, BF16) > > + > > +#include "floatn-basic.h" > > --- gcc/testsuite/gcc.dg/torture/bfloat16-builtin.c.jj 2022-10-13 16:57:09.271770648 +0200 > > +++ gcc/testsuite/gcc.dg/torture/bfloat16-builtin.c 2022-10-13 18:09:24.288913634 +0200 > > @@ -0,0 +1,47 @@ > > +/* Test __bf16 built-in functions. */ > > +/* { dg-do run } */ > > +/* { dg-options "" } */ > > +/* { dg-add-options bfloat16 } */ > > +/* { dg-add-options ieee } */ > > +/* { dg-require-effective-target bfloat16_runtime } */ > > + > > +extern void exit (int); > > +extern void abort (void); > > + > > +extern __bf16 test_type; > > +extern __typeof (__builtin_nansf16b ("")) test_type; > > + > > +volatile __bf16 inf_cst = (__bf16) __builtin_inff (); > > +volatile __bf16 huge_val_cst = (__bf16) __builtin_huge_valf (); > > +volatile __bf16 nan_cst = (__bf16) __builtin_nanf (""); > > +volatile __bf16 nans_cst = __builtin_nansf16b (""); > > +volatile __bf16 neg0 = -0.0bf16, neg1 = -1.0bf16, one = 1.0; > > + > > +int > > +main (void) > > +{ > > + volatile __bf16 r; > > + if (!__builtin_isinf (inf_cst)) > > + abort (); > > + if (!__builtin_isinf (huge_val_cst)) > > + abort (); > > + if (inf_cst != huge_val_cst) > > + abort (); > > + if (!__builtin_isnan (nan_cst)) > > + abort (); > > + if (!__builtin_isnan (nans_cst)) > > + abort (); > > + r = __builtin_fabsf (neg1); > > + if (r != 1.0bf16) > > + abort (); > > + r = __builtin_copysignf (one, neg0); > > + if (r != neg1) > > + abort (); > > + r = __builtin_copysignf (inf_cst, neg1); > > + if (r != -huge_val_cst) > > + abort (); > > + r = __builtin_copysignf (-inf_cst, one); > > + if (r != huge_val_cst) > > + abort (); > > + exit (0); > > +} > > --- gcc/testsuite/gcc.dg/torture/bfloat16-builtin-issignaling-1.c.jj 2022-10-13 16:57:09.271770648 +0200 > > +++ gcc/testsuite/gcc.dg/torture/bfloat16-builtin-issignaling-1.c 2022-10-13 17:40:15.067555349 +0200 > > @@ -0,0 +1,21 @@ > > +/* Test __bf16 __builtin_issignaling. */ > > +/* { dg-do run } */ > > +/* { dg-options "" } */ > > +/* { dg-add-options bfloat16 } */ > > +/* { dg-add-options ieee } */ > > +/* { dg-require-effective-target bfloat16_runtime } */ > > +/* { dg-additional-options "-fsignaling-nans" } */ > > +/* Workaround for PR57484 on ia32: */ > > +/* { dg-additional-options "-msse2 -mfpmath=sse" { target { ia32 && sse2_runtime } } } */ > > + > > +#define CONCATX(X, Y) X ## Y > > +#define CONCAT(X, Y) CONCATX (X, Y) > > + > > +#define TYPE __bf16 > > +#define CST(C) CONCAT (C, bf16) > > +#define FN(F) CONCAT (F, f16b) > > +#define NAN(x) ((__bf16) __builtin_nanf (x)) > > +#define INF ((__bf16) __builtin_inff ()) > > +#define EXT 0 > > + > > +#include "builtin-issignaling-1.c" > > --- gcc/testsuite/gcc.dg/torture/bfloat16-complex.c.jj 2022-10-13 16:57:09.271770648 +0200 > > +++ gcc/testsuite/gcc.dg/torture/bfloat16-complex.c 2022-10-13 17:46:43.259267724 +0200 > > @@ -0,0 +1,61 @@ > > +/* Test __bf16 complex arithmetic. */ > > +/* { dg-do run } */ > > +/* { dg-options "" } */ > > +/* { dg-add-options bfloat16 } */ > > +/* { dg-require-effective-target bfloat16_runtime } */ > > + > > +extern void exit (int); > > +extern void abort (void); > > + > > +volatile __bf16 a = 1.0bf16; > > +typedef _Complex float __cbf16 __attribute__((__mode__(__BC__))); > > +volatile __cbf16 b = __builtin_complex (2.0bf16, 3.0bf16); > > +volatile __cbf16 c = __builtin_complex (2.0bf16, 3.0bf16); > > +volatile __cbf16 d = __builtin_complex (2.0bf16, 3.0bf16); > > + > > +__cbf16 > > +fn (__cbf16 arg) > > +{ > > + return arg / 4; > > +} > > + > > +int > > +main (void) > > +{ > > + volatile __cbf16 r; > > + if (b != c) > > + abort (); > > + if (b != d) > > + abort (); > > + r = a + b; > > + if (__real__ r != 3.0bf16 || __imag__ r != 3.0bf16) > > + abort (); > > + r += d; > > + if (__real__ r != 5.0bf16 || __imag__ r != 6.0bf16) > > + abort (); > > + r -= a; > > + if (__real__ r != 4.0bf16 || __imag__ r != 6.0bf16) > > + abort (); > > + r /= (a + a); > > + if (__real__ r != 2.0bf16 || __imag__ r != 3.0bf16) > > + abort (); > > + r *= (a + a); > > + if (__real__ r != 4.0bf16 || __imag__ r != 6.0bf16) > > + abort (); > > + r -= b; > > + if (__real__ r != 2.0bf16 || __imag__ r != 3.0bf16) > > + abort (); > > + r *= r; > > + if (__real__ r != -5.0bf16 || __imag__ r != 12.0bf16) > > + abort (); > > + /* Division may not be exact, so round result before comparing. */ > > + r /= b; > > + r += __builtin_complex (100.0bf16, 100.0bf16); > > + r -= __builtin_complex (100.0bf16, 100.0bf16); > > + if (r != b) > > + abort (); > > + r = fn (r); > > + if (__real__ r != 0.5bf16 || __imag__ r != 0.75bf16) > > + abort (); > > + exit (0); > > +} > > --- gcc/testsuite/gcc.dg/torture/builtin-issignaling-1.c.jj 2022-10-03 18:00:53.118734300 +0200 > > +++ gcc/testsuite/gcc.dg/torture/builtin-issignaling-1.c 2022-10-13 17:39:19.387313780 +0200 > > @@ -4,7 +4,7 @@ > > /* Workaround for PR57484 on ia32: */ > > /* { dg-additional-options "-msse2 -mfpmath=sse" { target { ia32 && sse2_runtime } } } */ > > > > -#ifndef EXT > > +#if !defined(EXT) && !defined(TYPE) > > int > > f1 (void) > > { > > @@ -41,31 +41,42 @@ f6 (long double x) > > return __builtin_issignaling (x); > > } > > #else > > -#define CONCATX(X, Y) X ## Y > > -#define CONCAT(X, Y) CONCATX (X, Y) > > -#define CONCAT3(X, Y, Z) CONCAT (CONCAT (X, Y), Z) > > -#define CONCAT4(W, X, Y, Z) CONCAT (CONCAT (CONCAT (W, X), Y), Z) > > - > > -#if EXT > > -# define TYPE CONCAT3 (_Float, WIDTH, x) > > -# define CST(C) CONCAT4 (C, f, WIDTH, x) > > -# define FN(F) CONCAT4 (F, f, WIDTH, x) > > -#else > > -# define TYPE CONCAT (_Float, WIDTH) > > -# define CST(C) CONCAT3 (C, f, WIDTH) > > -# define FN(F) CONCAT3 (F, f, WIDTH) > > +#ifndef TYPE > > +# define CONCATX(X, Y) X ## Y > > +# define CONCAT(X, Y) CONCATX (X, Y) > > +# define CONCAT3(X, Y, Z) CONCAT (CONCAT (X, Y), Z) > > +# define CONCAT4(W, X, Y, Z) CONCAT (CONCAT (CONCAT (W, X), Y), Z) > > + > > +# if EXT > > +# define TYPE CONCAT3 (_Float, WIDTH, x) > > +# define CST(C) CONCAT4 (C, f, WIDTH, x) > > +# define FN(F) CONCAT4 (F, f, WIDTH, x) > > +# else > > +# define TYPE CONCAT (_Float, WIDTH) > > +# define CST(C) CONCAT3 (C, f, WIDTH) > > +# define FN(F) CONCAT3 (F, f, WIDTH) > > +# endif > > +#endif > > +#ifndef NANS > > +# define NANS(x) FN (__builtin_nans) (x) > > +#endif > > +#ifndef NAN > > +# define NAN(x) FN (__builtin_nan) (x) > > +#endif > > +#ifndef INF > > +# define INF FN (__builtin_inf) () > > #endif > > > > int > > f1 (void) > > { > > - return __builtin_issignaling (FN (__builtin_nans) ("")); > > + return __builtin_issignaling (NANS ("")); > > } > > > > int > > f2 (void) > > { > > - return __builtin_issignaling (FN (__builtin_nan) ("")); > > + return __builtin_issignaling (NAN ("")); > > } > > > > int > > @@ -118,10 +129,10 @@ main () > > if (!f6 (z)) > > __builtin_abort (); > > #else > > - if (f4 (w) || !f4 (FN (__builtin_nans) ("0x123")) || f4 (CST (42.0)) || f4 (FN (__builtin_nan) ("0x234")) > > - || f4 (FN (__builtin_inf) ()) || f4 (-FN (__builtin_inf) ()) || f4 (CST (-42.0)) || f4 (CST (-0.0)) || f4 (CST (0.0))) > > + if (f4 (w) || !f4 (NANS ("0x123")) || f4 (CST (42.0)) || f4 (NAN ("0x234")) > > + || f4 (INF) || f4 (-INF) || f4 (CST (-42.0)) || f4 (CST (-0.0)) || f4 (CST (0.0))) > > __builtin_abort (); > > - w = FN (__builtin_nans) (""); > > + w = NANS (""); > > asm volatile ("" : : : "memory"); > > if (!f4 (w)) > > __builtin_abort (); > > --- gcc/testsuite/gcc.dg/torture/floatn-basic.h.jj 2022-10-03 18:00:53.118734300 +0200 > > +++ gcc/testsuite/gcc.dg/torture/floatn-basic.h 2022-10-13 16:57:09.285770456 +0200 > > @@ -9,14 +9,16 @@ > > #define CONCAT3(X, Y, Z) CONCAT (CONCAT (X, Y), Z) > > #define CONCAT4(W, X, Y, Z) CONCAT (CONCAT (CONCAT (W, X), Y), Z) > > > > -#if EXT > > -# define TYPE CONCAT3 (_Float, WIDTH, x) > > -# define CST(C) CONCAT4 (C, f, WIDTH, x) > > -# define CSTU(C) CONCAT4 (C, F, WIDTH, x) > > -#else > > -# define TYPE CONCAT (_Float, WIDTH) > > -# define CST(C) CONCAT3 (C, f, WIDTH) > > -# define CSTU(C) CONCAT3 (C, F, WIDTH) > > +#ifndef TYPE > > +# if EXT > > +# define TYPE CONCAT3 (_Float, WIDTH, x) > > +# define CST(C) CONCAT4 (C, f, WIDTH, x) > > +# define CSTU(C) CONCAT4 (C, F, WIDTH, x) > > +# else > > +# define TYPE CONCAT (_Float, WIDTH) > > +# define CST(C) CONCAT3 (C, f, WIDTH) > > +# define CSTU(C) CONCAT3 (C, F, WIDTH) > > +# endif > > #endif > > > > extern void exit (int); > > --- gcc/testsuite/gcc.target/i386/vect-bfloat16-typecheck_2.c.jj 2022-10-03 18:00:53.137734043 +0200 > > +++ gcc/testsuite/gcc.target/i386/vect-bfloat16-typecheck_2.c 2022-10-13 16:57:09.306770168 +0200 > > @@ -45,19 +45,19 @@ __m256bf16 footest (__m256bf16 vector0) > > __m256bf16 vector2_1 = {}; > > __m256bf16 vector2_2 = { glob_bfloat }; > > __m256bf16 vector2_3 = { glob_bfloat, glob_bfloat, glob_bfloat, glob_bfloat }; > > - __m256bf16 vector2_4 = { 0 }; /* { dg-error {invalid conversion to type '__bf16'} } */ > > - __m256bf16 vector2_5 = { 0.1 }; /* { dg-error {invalid conversion to type '__bf16'} } */ > > - __m256bf16 vector2_6 = { is_a_float16 }; /* { dg-error {invalid conversion to type '__bf16'} } */ > > - __m256bf16 vector2_7 = { is_a_float }; /* { dg-error {invalid conversion to type '__bf16'} } */ > > - __m256bf16 vector2_8 = { is_an_int }; /* { dg-error {invalid conversion to type '__bf16'} } */ > > - __m256bf16 vector2_9 = { is_a_short_int }; /* { dg-error {invalid conversion to type '__bf16'} } */ > > - __m256bf16 vector2_10 = { 0.0, 0, is_a_short_int, is_a_float }; /* { dg-error "invalid conversion to type '__bf16'" } */ > > - > > - __v8si initi_2_1 = { glob_bfloat }; /* { dg-error {invalid conversion from type '__bf16'} } */ > > - __m256 initi_2_2 = { glob_bfloat }; /* { dg-error {invalid conversion from type '__bf16'} } */ > > - __m256h initi_2_3 = { glob_bfloat }; /* { dg-error {invalid conversion from type '__bf16'} } */ > > - __m256i initi_2_5 = { glob_bfloat }; /* { dg-error {invalid conversion from type '__bf16'} } */ > > - __v16hi initi_2_6 = { glob_bfloat }; /* { dg-error {invalid conversion from type '__bf16'} } */ > > + __m256bf16 vector2_4 = { 0 }; > > + __m256bf16 vector2_5 = { 0.1 }; > > + __m256bf16 vector2_6 = { is_a_float16 }; > > + __m256bf16 vector2_7 = { is_a_float }; > > + __m256bf16 vector2_8 = { is_an_int }; > > + __m256bf16 vector2_9 = { is_a_short_int }; > > + __m256bf16 vector2_10 = { 0.0, 0, is_a_short_int, is_a_float }; > > + > > + __v8si initi_2_1 = { glob_bfloat }; > > + __m256 initi_2_2 = { glob_bfloat }; > > + __m256h initi_2_3 = { glob_bfloat }; > > + __m256i initi_2_5 = { glob_bfloat }; > > + __v16hi initi_2_6 = { glob_bfloat }; > > > > /* Assignments to/from vectors. */ > > > > @@ -79,25 +79,25 @@ __m256bf16 footest (__m256bf16 vector0) > > /* Assignments to/from elements. */ > > > > vector2_3[0] = glob_bfloat; > > - vector2_3[0] = is_an_int; /* { dg-error {invalid conversion to type '__bf16'} } */ > > - vector2_3[0] = is_a_short_int; /* { dg-error {invalid conversion to type '__bf16'} } */ > > - vector2_3[0] = is_a_float; /* { dg-error {invalid conversion to type '__bf16'} } */ > > - vector2_3[0] = is_a_float16; /* { dg-error {invalid conversion to type '__bf16'} } */ > > - vector2_3[0] = 0; /* { dg-error {invalid conversion to type '__bf16'} } */ > > - vector2_3[0] = 0.1; /* { dg-error {invalid conversion to type '__bf16'} } */ > > + vector2_3[0] = is_an_int; > > + vector2_3[0] = is_a_short_int; > > + vector2_3[0] = is_a_float; > > + vector2_3[0] = is_a_float16; > > + vector2_3[0] = 0; > > + vector2_3[0] = 0.1; > > > > glob_bfloat = vector2_3[0]; > > - is_an_int = vector2_3[0]; /* { dg-error {invalid conversion from type '__bf16'} } */ > > - is_a_short_int = vector2_3[0]; /* { dg-error {invalid conversion from type '__bf16'} } */ > > - is_a_float = vector2_3[0]; /* { dg-error {invalid conversion from type '__bf16'} } */ > > - is_a_float16 = vector2_3[0]; /* { dg-error {invalid conversion from type '__bf16'} } */ > > + is_an_int = vector2_3[0]; > > + is_a_short_int = vector2_3[0]; > > + is_a_float = vector2_3[0]; > > + is_a_float16 = vector2_3[0]; > > > > /* Compound literals. */ > > > > (__m256bf16) {}; > > > > - (__m256bf16) { 0 }; /* { dg-error {invalid conversion to type '__bf16'} } */ > > - (__m256bf16) { 0.1 }; /* { dg-error {invalid conversion to type '__bf16'} } */ > > + (__m256bf16) { 0 }; > > + (__m256bf16) { 0.1 }; > > (__m256bf16) { is_a_float_vec }; /* { dg-error {incompatible types when initializing type '__bf16' using type '__m256'} } */ > > (__m256bf16) { is_an_int_vec }; /* { dg-error {incompatible types when initializing type '__bf16' using type '__v8si'} } */ > > (__m256bf16) { is_a_long_int_pair }; /* { dg-error {incompatible types when initializing type '__bf16' using type '__m256i'} } */ > > @@ -176,16 +176,16 @@ __m256bf16 footest (__m256bf16 vector0) > > bfloat_ptr = &bfloat_ptr3[1]; > > > > /* Simple comparison. */ > > - vector0 > glob_bfloat_vec; /* { dg-error {operation not permitted on type '__bf16'} } */ > > - glob_bfloat_vec == vector0; /* { dg-error {operation not permitted on type '__bf16'} } */ > > - vector0 > is_a_float_vec; /* { dg-error {operation not permitted on type '__bf16'} } */ > > - is_a_float_vec == vector0; /* { dg-error {operation not permitted on type '__bf16'} } */ > > - vector0 > 0; /* { dg-error {operation not permitted on type '__bf16'} } */ > > - 0 == vector0; /* { dg-error {operation not permitted on type '__bf16'} } */ > > - vector0 > 0.1; /* { dg-error {operation not permitted on type '__bf16'} } */ > > - 0.1 == vector0; /* { dg-error {operation not permitted on type '__bf16'} } */ > > - vector0 > is_an_int_vec; /* { dg-error {operation not permitted on type '__bf16'} } */ > > - is_an_int_vec == vector0; /* { dg-error {operation not permitted on type '__bf16'} } */ > > + vector0 > glob_bfloat_vec; > > + glob_bfloat_vec == vector0; > > + vector0 > is_a_float_vec; /* { dg-error {comparing vectors with different element types} } */ > > + is_a_float_vec == vector0; /* { dg-error {comparing vectors with different element types} } */ > > + vector0 > 0; > > + 0 == vector0; > > + vector0 > 0.1; /* { dg-error {conversion of scalar 'double' to vector '__m256bf16'} } */ > > + 0.1 == vector0; /* { dg-error {conversion of scalar 'double' to vector '__m256bf16'} } */ > > + vector0 > is_an_int_vec; /* { dg-error {comparing vectors with different element types} } */ > > + is_an_int_vec == vector0; /* { dg-error {comparing vectors with different element types} } */ > > > > /* Pointer comparison. */ > > > > @@ -224,24 +224,24 @@ __m256bf16 footest (__m256bf16 vector0) > > > > /* Unary operators. */ > > > > - +vector0; /* { dg-error {operation not permitted on type '__bf16'} } */ > > - -vector0; /* { dg-error {operation not permitted on type '__bf16'} } */ > > - ~vector0; /* { dg-error {operation not permitted on type '__bf16'} } */ > > - !vector0; /* { dg-error {operation not permitted on type '__bf16'} } */ > > + +vector0; > > + -vector0; > > + ~vector0; /* { dg-error {wrong type argument to bit-complement} } */ > > + !vector0; /* { dg-error {wrong type argument to unary exclamation mark} } */ > > *vector0; /* { dg-error {invalid type argument of unary '\*'} } */ > > - __real vector0; /* { dg-error {operation not permitted on type '__bf16'} } */ > > - __imag vector0; /* { dg-error {operation not permitted on type '__bf16'} } */ > > - ++vector0; /* { dg-error {operation not permitted on type '__bf16'} } */ > > - --vector0; /* { dg-error {operation not permitted on type '__bf16'} } */ > > - vector0++; /* { dg-error {operation not permitted on type '__bf16'} } */ > > - vector0--; /* { dg-error {operation not permitted on type '__bf16'} } */ > > + __real vector0; /* { dg-error {wrong type argument to __real} } */ > > + __imag vector0; /* { dg-error {wrong type argument to __imag} } */ > > + ++vector0; > > + --vector0; > > + vector0++; > > + vector0--; > > > > /* Binary arithmetic operations. */ > > > > - vector0 = glob_bfloat_vec + *bfloat_ptr; /* { dg-error {operation not permitted on type '__bf16'} } */ > > - vector0 = glob_bfloat_vec + 0.1; /* { dg-error {operation not permitted on type '__bf16'} } */ > > - vector0 = glob_bfloat_vec + 0; /* { dg-error {operation not permitted on type '__bf16'} } */ > > - vector0 = glob_bfloat_vec + is_a_float_vec; /* { dg-error {operation not permitted on type '__bf16'} } */ > > + vector0 = glob_bfloat_vec + *bfloat_ptr; > > + vector0 = glob_bfloat_vec + 0.1; /* { dg-error {conversion of scalar 'double' to vector '__m256bf16'} } */ > > + vector0 = glob_bfloat_vec + 0; > > + vector0 = glob_bfloat_vec + is_a_float_vec; /* { dg-error {invalid operands to binary \+} } */ > > > > return vector0; > > } > > --- gcc/testsuite/gcc.target/i386/sse2-bfloat16-scalar-typecheck.c.jj 2022-10-03 18:00:53.136734057 +0200 > > +++ gcc/testsuite/gcc.target/i386/sse2-bfloat16-scalar-typecheck.c 2022-10-13 16:57:09.327769880 +0200 > > @@ -12,8 +12,8 @@ double is_a_double; > > > > float *float_ptr; > > > > -__bf16 foo1 (void) { return (__bf16) 0x1234; } /* { dg-error {invalid conversion to type '__bf16'} } */ > > -__bf16 foo2 (void) { return (__bf16) (short) 0x1234; } /* { dg-error {invalid conversion to type '__bf16'} } */ > > +__bf16 foo1 (void) { return (__bf16) 0x1234; } > > +__bf16 foo2 (void) { return (__bf16) (short) 0x1234; } > > > > __bf16 footest (__bf16 scalar0) > > { > > @@ -22,87 +22,87 @@ __bf16 footest (__bf16 scalar0) > > > > __bf16 scalar1_1; > > __bf16 scalar1_2 = glob_bfloat; > > - __bf16 scalar1_3 = 0; /* { dg-error {invalid conversion to type '__bf16'} } */ > > - __bf16 scalar1_4 = 0.1; /* { dg-error {invalid conversion to type '__bf16'} } */ > > - __bf16 scalar1_5 = is_a_float; /* { dg-error {invalid conversion to type '__bf16'} } */ > > - __bf16 scalar1_6 = is_an_int; /* { dg-error {invalid conversion to type '__bf16'} } */ > > - __bf16 scalar1_7 = is_a_float16; /* { dg-error {invalid conversion to type '__bf16'} } */ > > - __bf16 scalar1_8 = is_a_double; /* { dg-error {invalid conversion to type '__bf16'} } */ > > - __bf16 scalar1_9 = is_a_short_int; /* { dg-error {invalid conversion to type '__bf16'} } */ > > - > > - int initi_1_1 = glob_bfloat; /* { dg-error {invalid conversion from type '__bf16'} } */ > > - float initi_1_2 = glob_bfloat; /* { dg-error {invalid conversion from type '__bf16'} } */ > > - _Float16 initi_1_3 = glob_bfloat; /* { dg-error {invalid conversion from type '__bf16'} } */ > > - short initi_1_4 = glob_bfloat; /* { dg-error {invalid conversion from type '__bf16'} } */ > > - double initi_1_5 = glob_bfloat; /* { dg-error {invalid conversion from type '__bf16'} } */ > > + __bf16 scalar1_3 = 0; > > + __bf16 scalar1_4 = 0.1; > > + __bf16 scalar1_5 = is_a_float; > > + __bf16 scalar1_6 = is_an_int; > > + __bf16 scalar1_7 = is_a_float16; > > + __bf16 scalar1_8 = is_a_double; > > + __bf16 scalar1_9 = is_a_short_int; > > + > > + int initi_1_1 = glob_bfloat; > > + float initi_1_2 = glob_bfloat; > > + _Float16 initi_1_3 = glob_bfloat; > > + short initi_1_4 = glob_bfloat; > > + double initi_1_5 = glob_bfloat; > > > > __bf16 scalar2_1 = {}; > > __bf16 scalar2_2 = { glob_bfloat }; > > - __bf16 scalar2_3 = { 0 }; /* { dg-error {invalid conversion to type '__bf16'} } */ > > - __bf16 scalar2_4 = { 0.1 }; /* { dg-error {invalid conversion to type '__bf16'} } */ > > - __bf16 scalar2_5 = { is_a_float }; /* { dg-error {invalid conversion to type '__bf16'} } */ > > - __bf16 scalar2_6 = { is_an_int }; /* { dg-error {invalid conversion to type '__bf16'} } */ > > - __bf16 scalar2_7 = { is_a_float16 }; /* { dg-error {invalid conversion to type '__bf16'} } */ > > - __bf16 scalar2_8 = { is_a_double }; /* { dg-error {invalid conversion to type '__bf16'} } */ > > - __bf16 scalar2_9 = { is_a_short_int }; /* { dg-error {invalid conversion to type '__bf16'} } */ > > - > > - int initi_2_1 = { glob_bfloat }; /* { dg-error {invalid conversion from type '__bf16'} } */ > > - float initi_2_2 = { glob_bfloat }; /* { dg-error {invalid conversion from type '__bf16'} } */ > > - _Float16 initi_2_3 = { glob_bfloat }; /* { dg-error {invalid conversion from type '__bf16'} } */ > > - short initi_2_4 = { glob_bfloat }; /* { dg-error {invalid conversion from type '__bf16'} } */ > > - double initi_2_5 = { glob_bfloat }; /* { dg-error {invalid conversion from type '__bf16'} } */ > > + __bf16 scalar2_3 = { 0 }; > > + __bf16 scalar2_4 = { 0.1 }; > > + __bf16 scalar2_5 = { is_a_float }; > > + __bf16 scalar2_6 = { is_an_int }; > > + __bf16 scalar2_7 = { is_a_float16 }; > > + __bf16 scalar2_8 = { is_a_double }; > > + __bf16 scalar2_9 = { is_a_short_int }; > > + > > + int initi_2_1 = { glob_bfloat }; > > + float initi_2_2 = { glob_bfloat }; > > + _Float16 initi_2_3 = { glob_bfloat }; > > + short initi_2_4 = { glob_bfloat }; > > + double initi_2_5 = { glob_bfloat }; > > > > /* Assignments. */ > > > > glob_bfloat = glob_bfloat; > > - glob_bfloat = 0; /* { dg-error {invalid conversion to type '__bf16'} } */ > > - glob_bfloat = 0.1; /* { dg-error {invalid conversion to type '__bf16'} } */ > > - glob_bfloat = is_a_float; /* { dg-error {invalid conversion to type '__bf16'} } */ > > - glob_bfloat = is_an_int; /* { dg-error {invalid conversion to type '__bf16'} } */ > > - glob_bfloat = is_a_float16; /* { dg-error {invalid conversion to type '__bf16'} } */ > > - glob_bfloat = is_a_double; /* { dg-error {invalid conversion to type '__bf16'} } */ > > - glob_bfloat = is_a_short_int; /* { dg-error {invalid conversion to type '__bf16'} } */ > > - > > - is_an_int = glob_bfloat; /* { dg-error {invalid conversion from type '__bf16'} } */ > > - is_a_float = glob_bfloat; /* { dg-error {invalid conversion from type '__bf16'} } */ > > - is_a_float16 = glob_bfloat; /* { dg-error {invalid conversion from type '__bf16'} } */ > > - is_a_double = glob_bfloat; /* { dg-error {invalid conversion from type '__bf16'} } */ > > - is_a_short_int = glob_bfloat; /* { dg-error {invalid conversion from type '__bf16'} } */ > > + glob_bfloat = 0; > > + glob_bfloat = 0.1; > > + glob_bfloat = is_a_float; > > + glob_bfloat = is_an_int; > > + glob_bfloat = is_a_float16; > > + glob_bfloat = is_a_double; > > + glob_bfloat = is_a_short_int; > > + > > + is_an_int = glob_bfloat; > > + is_a_float = glob_bfloat; > > + is_a_float16 = glob_bfloat; > > + is_a_double = glob_bfloat; > > + is_a_short_int = glob_bfloat; > > > > /* Casting. */ > > > > (void) glob_bfloat; > > (__bf16) glob_bfloat; > > > > - (int) glob_bfloat; /* { dg-error {invalid conversion from type '__bf16'} } */ > > - (float) glob_bfloat; /* { dg-error {invalid conversion from type '__bf16'} } */ > > - (_Float16) glob_bfloat; /* { dg-error {invalid conversion from type '__bf16'} } */ > > - (double) glob_bfloat; /* { dg-error {invalid conversion from type '__bf16'} } */ > > - (short) glob_bfloat; /* { dg-error {invalid conversion from type '__bf16'} } */ > > - > > - (__bf16) is_an_int; /* { dg-error {invalid conversion to type '__bf16'} } */ > > - (__bf16) is_a_float; /* { dg-error {invalid conversion to type '__bf16'} } */ > > - (__bf16) is_a_float16; /* { dg-error {invalid conversion to type '__bf16'} } */ > > - (__bf16) is_a_double; /* { dg-error {invalid conversion to type '__bf16'} } */ > > - (__bf16) is_a_short_int; /* { dg-error {invalid conversion to type '__bf16'} } */ > > + (int) glob_bfloat; > > + (float) glob_bfloat; > > + (_Float16) glob_bfloat; > > + (double) glob_bfloat; > > + (short) glob_bfloat; > > + > > + (__bf16) is_an_int; > > + (__bf16) is_a_float; > > + (__bf16) is_a_float16; > > + (__bf16) is_a_double; > > + (__bf16) is_a_short_int; > > > > /* Compound literals. */ > > > > (__bf16) {}; > > (__bf16) { glob_bfloat }; > > - (__bf16) { 0 }; /* { dg-error {invalid conversion to type '__bf16'} } */ > > - (__bf16) { 0.1 }; /* { dg-error {invalid conversion to type '__bf16'} } */ > > - (__bf16) { is_a_float }; /* { dg-error {invalid conversion to type '__bf16'} } */ > > - (__bf16) { is_an_int }; /* { dg-error {invalid conversion to type '__bf16'} } */ > > - (__bf16) { is_a_float16 }; /* { dg-error {invalid conversion to type '__bf16'} } */ > > - (__bf16) { is_a_double }; /* { dg-error {invalid conversion to type '__bf16'} } */ > > - (__bf16) { is_a_short_int }; /* { dg-error {invalid conversion to type '__bf16'} } */ > > - > > - (int) { glob_bfloat }; /* { dg-error {invalid conversion from type '__bf16'} } */ > > - (float) { glob_bfloat }; /* { dg-error {invalid conversion from type '__bf16'} } */ > > - (_Float16) { glob_bfloat }; /* { dg-error {invalid conversion from type '__bf16'} } */ > > - (double) { glob_bfloat }; /* { dg-error {invalid conversion from type '__bf16'} } */ > > - (short) { glob_bfloat }; /* { dg-error {invalid conversion from type '__bf16'} } */ > > + (__bf16) { 0 }; > > + (__bf16) { 0.1 }; > > + (__bf16) { is_a_float }; > > + (__bf16) { is_an_int }; > > + (__bf16) { is_a_float16 }; > > + (__bf16) { is_a_double }; > > + (__bf16) { is_a_short_int }; > > + > > + (int) { glob_bfloat }; > > + (float) { glob_bfloat }; > > + (_Float16) { glob_bfloat }; > > + (double) { glob_bfloat }; > > + (short) { glob_bfloat }; > > > > /* Arrays and Structs. */ > > > > @@ -145,16 +145,16 @@ __bf16 footest (__bf16 scalar0) > > bfloat_ptr = &bfloat_ptr3[1]; > > > > /* Simple comparison. */ > > - scalar0 > glob_bfloat; /* { dg-error {operation not permitted on type '__bf16'} } */ > > - glob_bfloat == scalar0; /* { dg-error {operation not permitted on type '__bf16'} } */ > > - scalar0 > is_a_float; /* { dg-error {operation not permitted on type '__bf16'} } */ > > - is_a_float == scalar0; /* { dg-error {operation not permitted on type '__bf16'} } */ > > - scalar0 > 0; /* { dg-error {operation not permitted on type '__bf16'} } */ > > - 0 == scalar0; /* { dg-error {operation not permitted on type '__bf16'} } */ > > - scalar0 > 0.1; /* { dg-error {operation not permitted on type '__bf16'} } */ > > - 0.1 == scalar0; /* { dg-error {operation not permitted on type '__bf16'} } */ > > - scalar0 > is_an_int; /* { dg-error {operation not permitted on type '__bf16'} } */ > > - is_an_int == scalar0; /* { dg-error {operation not permitted on type '__bf16'} } */ > > + scalar0 > glob_bfloat; > > + glob_bfloat == scalar0; > > + scalar0 > is_a_float; > > + is_a_float == scalar0; > > + scalar0 > 0; > > + 0 == scalar0; > > + scalar0 > 0.1; > > + 0.1 == scalar0; > > + scalar0 > is_an_int; > > + is_an_int == scalar0; > > > > /* Pointer comparison. */ > > > > @@ -174,41 +174,41 @@ __bf16 footest (__bf16 scalar0) > > /* Conditional expressions. */ > > > > 0 ? scalar0 : scalar0; > > - 0 ? scalar0 : is_a_float; /* { dg-error {invalid conversion from type '__bf16'} } */ > > - 0 ? is_a_float : scalar0; /* { dg-error {invalid conversion from type '__bf16'} } */ > > - 0 ? scalar0 : 0; /* { dg-error {invalid conversion to type '__bf16'} } */ > > - 0 ? 0 : scalar0; /* { dg-error {invalid conversion to type '__bf16'} } */ > > - 0 ? 0.1 : scalar0; /* { dg-error {invalid conversion from type '__bf16'} } */ > > - 0 ? scalar0 : 0.1; /* { dg-error {invalid conversion from type '__bf16'} } */ > > + 0 ? scalar0 : is_a_float; > > + 0 ? is_a_float : scalar0; > > + 0 ? scalar0 : 0; > > + 0 ? 0 : scalar0; > > + 0 ? 0.1 : scalar0; > > + 0 ? scalar0 : 0.1; > > 0 ? bfloat_ptr : bfloat_ptr2; > > 0 ? bfloat_ptr : float_ptr; /* { dg-warning {pointer type mismatch in conditional expression} } */ > > 0 ? float_ptr : bfloat_ptr; /* { dg-warning {pointer type mismatch in conditional expression} } */ > > > > - scalar0 ? scalar0 : scalar0; /* { dg-error {operation not permitted on type '__bf16'} } */ > > - scalar0 ? is_a_float : scalar0; /* { dg-error {operation not permitted on type '__bf16'} } */ > > - scalar0 ? scalar0 : is_a_float; /* { dg-error {operation not permitted on type '__bf16'} } */ > > - scalar0 ? is_a_float : is_a_float; /* { dg-error {operation not permitted on type '__bf16'} } */ > > + scalar0 ? scalar0 : scalar0; > > + scalar0 ? is_a_float : scalar0; > > + scalar0 ? scalar0 : is_a_float; > > + scalar0 ? is_a_float : is_a_float; > > > > /* Unary operators. */ > > > > - +scalar0; /* { dg-error {operation not permitted on type '__bf16'} } */ > > - -scalar0; /* { dg-error {operation not permitted on type '__bf16'} } */ > > - ~scalar0; /* { dg-error {operation not permitted on type '__bf16'} } */ > > - !scalar0; /* { dg-error {operation not permitted on type '__bf16'} } */ > > + +scalar0; > > + -scalar0; > > + ~scalar0; /* { dg-error {wrong type argument to bit-complement} } */ > > + !scalar0; > > *scalar0; /* { dg-error {invalid type argument of unary '\*'} } */ > > - __real scalar0; /* { dg-error {operation not permitted on type '__bf16'} } */ > > - __imag scalar0; /* { dg-error {operation not permitted on type '__bf16'} } */ > > - ++scalar0; /* { dg-error {operation not permitted on type '__bf16'} } */ > > - --scalar0; /* { dg-error {operation not permitted on type '__bf16'} } */ > > - scalar0++; /* { dg-error {operation not permitted on type '__bf16'} } */ > > - scalar0--; /* { dg-error {operation not permitted on type '__bf16'} } */ > > + __real scalar0; > > + __imag scalar0; > > + ++scalar0; > > + --scalar0; > > + scalar0++; > > + scalar0--; > > > > /* Binary arithmetic operations. */ > > > > - scalar0 = glob_bfloat + *bfloat_ptr; /* { dg-error {operation not permitted on type '__bf16'} } */ > > - scalar0 = glob_bfloat + 0.1; /* { dg-error {operation not permitted on type '__bf16'} } */ > > - scalar0 = glob_bfloat + 0; /* { dg-error {operation not permitted on type '__bf16'} } */ > > - scalar0 = glob_bfloat + is_a_float; /* { dg-error {operation not permitted on type '__bf16'} } */ > > + scalar0 = glob_bfloat + *bfloat_ptr; > > + scalar0 = glob_bfloat + 0.1; > > + scalar0 = glob_bfloat + 0; > > + scalar0 = glob_bfloat + is_a_float; > > > > return scalar0; > > } > > --- gcc/testsuite/gcc.target/i386/vect-bfloat16-typecheck_1.c.jj 2022-10-03 18:00:53.136734057 +0200 > > +++ gcc/testsuite/gcc.target/i386/vect-bfloat16-typecheck_1.c 2022-10-13 16:57:09.344769646 +0200 > > @@ -48,20 +48,20 @@ __m128bf16 footest (__m128bf16 vector0) > > __m128bf16 vector2_1 = {}; > > __m128bf16 vector2_2 = { glob_bfloat }; > > __m128bf16 vector2_3 = { glob_bfloat, glob_bfloat, glob_bfloat, glob_bfloat }; > > - __m128bf16 vector2_4 = { 0 }; /* { dg-error {invalid conversion to type '__bf16'} } */ > > - __m128bf16 vector2_5 = { 0.1 }; /* { dg-error {invalid conversion to type '__bf16'} } */ > > - __m128bf16 vector2_6 = { is_a_float16 }; /* { dg-error {invalid conversion to type '__bf16'} } */ > > - __m128bf16 vector2_7 = { is_a_float }; /* { dg-error {invalid conversion to type '__bf16'} } */ > > - __m128bf16 vector2_8 = { is_an_int }; /* { dg-error {invalid conversion to type '__bf16'} } */ > > - __m128bf16 vector2_9 = { is_a_short_int }; /* { dg-error {invalid conversion to type '__bf16'} } */ > > - __m128bf16 vector2_10 = { 0.0, 0, is_a_short_int, is_a_float }; /* { dg-error {invalid conversion to type '__bf16'} } */ > > - > > - __v8si initi_2_1 = { glob_bfloat }; /* { dg-error {invalid conversion from type '__bf16'} } */ > > - __m256 initi_2_2 = { glob_bfloat }; /* { dg-error {invalid conversion from type '__bf16'} } */ > > - __m128h initi_2_3 = { glob_bfloat }; /* { dg-error {invalid conversion from type '__bf16'} } */ > > - __m128 initi_2_4 = { glob_bfloat }; /* { dg-error {invalid conversion from type '__bf16'} } */ > > - __v4si initi_2_5 = { glob_bfloat }; /* { dg-error {invalid conversion from type '__bf16'} } */ > > - __v4hi initi_2_6 = { glob_bfloat }; /* { dg-error {invalid conversion from type '__bf16'} } */ > > + __m128bf16 vector2_4 = { 0 }; > > + __m128bf16 vector2_5 = { 0.1 }; > > + __m128bf16 vector2_6 = { is_a_float16 }; > > + __m128bf16 vector2_7 = { is_a_float }; > > + __m128bf16 vector2_8 = { is_an_int }; > > + __m128bf16 vector2_9 = { is_a_short_int }; > > + __m128bf16 vector2_10 = { 0.0, 0, is_a_short_int, is_a_float }; > > + > > + __v8si initi_2_1 = { glob_bfloat }; > > + __m256 initi_2_2 = { glob_bfloat }; > > + __m128h initi_2_3 = { glob_bfloat }; > > + __m128 initi_2_4 = { glob_bfloat }; > > + __v4si initi_2_5 = { glob_bfloat }; > > + __v4hi initi_2_6 = { glob_bfloat }; > > > > /* Assignments to/from vectors. */ > > > > @@ -85,25 +85,25 @@ __m128bf16 footest (__m128bf16 vector0) > > /* Assignments to/from elements. */ > > > > vector2_3[0] = glob_bfloat; > > - vector2_3[0] = is_an_int; /* { dg-error {invalid conversion to type '__bf16'} } */ > > - vector2_3[0] = is_a_short_int; /* { dg-error {invalid conversion to type '__bf16'} } */ > > - vector2_3[0] = is_a_float; /* { dg-error {invalid conversion to type '__bf16'} } */ > > - vector2_3[0] = is_a_float16; /* { dg-error {invalid conversion to type '__bf16'} } */ > > - vector2_3[0] = 0; /* { dg-error {invalid conversion to type '__bf16'} } */ > > - vector2_3[0] = 0.1; /* { dg-error {invalid conversion to type '__bf16'} } */ > > + vector2_3[0] = is_an_int; > > + vector2_3[0] = is_a_short_int; > > + vector2_3[0] = is_a_float; > > + vector2_3[0] = is_a_float16; > > + vector2_3[0] = 0; > > + vector2_3[0] = 0.1; > > > > glob_bfloat = vector2_3[0]; > > - is_an_int = vector2_3[0]; /* { dg-error {invalid conversion from type '__bf16'} } */ > > - is_a_short_int = vector2_3[0]; /* { dg-error {invalid conversion from type '__bf16'} } */ > > - is_a_float = vector2_3[0]; /* { dg-error {invalid conversion from type '__bf16'} } */ > > - is_a_float16 = vector2_3[0]; /* { dg-error {invalid conversion from type '__bf16'} } */ > > + is_an_int = vector2_3[0]; > > + is_a_short_int = vector2_3[0]; > > + is_a_float = vector2_3[0]; > > + is_a_float16 = vector2_3[0]; > > > > /* Compound literals. */ > > > > (__m128bf16) {}; > > > > - (__m128bf16) { 0 }; /* { dg-error {invalid conversion to type '__bf16'} } */ > > - (__m128bf16) { 0.1 }; /* { dg-error {invalid conversion to type '__bf16'} } */ > > + (__m128bf16) { 0 }; > > + (__m128bf16) { 0.1 }; > > (__m128bf16) { is_a_float_vec }; /* { dg-error {incompatible types when initializing type '__bf16' using type '__m256'} } */ > > (__m128bf16) { is_an_int_vec }; /* { dg-error {incompatible types when initializing type '__bf16' using type '__v8si'} } */ > > (__m128bf16) { is_a_float_pair }; /* { dg-error {incompatible types when initializing type '__bf16' using type '__m128'} } */ > > @@ -186,16 +186,16 @@ __m128bf16 footest (__m128bf16 vector0) > > bfloat_ptr = &bfloat_ptr3[1]; > > > > /* Simple comparison. */ > > - vector0 > glob_bfloat_vec; /* { dg-error {operation not permitted on type '__bf16'} } */ > > - glob_bfloat_vec == vector0; /* { dg-error {operation not permitted on type '__bf16'} } */ > > - vector0 > is_a_float_vec; /* { dg-error {operation not permitted on type '__bf16'} } */ > > - is_a_float_vec == vector0; /* { dg-error {operation not permitted on type '__bf16'} } */ > > - vector0 > 0; /* { dg-error {operation not permitted on type '__bf16'} } */ > > - 0 == vector0; /* { dg-error {operation not permitted on type '__bf16'} } */ > > - vector0 > 0.1; /* { dg-error {operation not permitted on type '__bf16'} } */ > > - 0.1 == vector0; /* { dg-error {operation not permitted on type '__bf16'} } */ > > - vector0 > is_an_int_vec; /* { dg-error {operation not permitted on type '__bf16'} } */ > > - is_an_int_vec == vector0; /* { dg-error {operation not permitted on type '__bf16'} } */ > > + vector0 > glob_bfloat_vec; > > + glob_bfloat_vec == vector0; > > + vector0 > is_a_float_vec; /* { dg-error {comparing vectors with different element types} } */ > > + is_a_float_vec == vector0; /* { dg-error {comparing vectors with different element types} } */ > > + vector0 > 0; > > + 0 == vector0; > > + vector0 > 0.1; /* { dg-error {conversion of scalar 'double' to vector '__m128bf16'} } */ > > + 0.1 == vector0; /* { dg-error {conversion of scalar 'double' to vector '__m128bf16'} } */ > > + vector0 > is_an_int_vec; /* { dg-error {comparing vectors with different element types} } */ > > + is_an_int_vec == vector0; /* { dg-error {comparing vectors with different element types} } */ > > > > /* Pointer comparison. */ > > > > @@ -234,24 +234,24 @@ __m128bf16 footest (__m128bf16 vector0) > > > > /* Unary operators. */ > > > > - +vector0; /* { dg-error {operation not permitted on type '__bf16'} } */ > > - -vector0; /* { dg-error {operation not permitted on type '__bf16'} } */ > > - ~vector0; /* { dg-error {operation not permitted on type '__bf16'} } */ > > - !vector0; /* { dg-error {operation not permitted on type '__bf16'} } */ > > + +vector0; > > + -vector0; > > + ~vector0; /* { dg-error {wrong type argument to bit-complement} } */ > > + !vector0; /* { dg-error {wrong type argument to unary exclamation mark} } */ > > *vector0; /* { dg-error {invalid type argument of unary '\*'} } */ > > - __real vector0; /* { dg-error {operation not permitted on type '__bf16'} } */ > > - __imag vector0; /* { dg-error {operation not permitted on type '__bf16'} } */ > > - ++vector0; /* { dg-error {operation not permitted on type '__bf16'} } */ > > - --vector0; /* { dg-error {operation not permitted on type '__bf16'} } */ > > - vector0++; /* { dg-error {operation not permitted on type '__bf16'} } */ > > - vector0--; /* { dg-error {operation not permitted on type '__bf16'} } */ > > + __real vector0; /* { dg-error {wrong type argument to __real} } */ > > + __imag vector0; /* { dg-error {wrong type argument to __imag} } */ > > + ++vector0; > > + --vector0; > > + vector0++; > > + vector0--; > > > > /* Binary arithmetic operations. */ > > > > - vector0 = glob_bfloat_vec + *bfloat_ptr; /* { dg-error {operation not permitted on type '__bf16'} } */ > > - vector0 = glob_bfloat_vec + 0.1; /* { dg-error {operation not permitted on type '__bf16'} } */ > > - vector0 = glob_bfloat_vec + 0; /* { dg-error {operation not permitted on type '__bf16'} } */ > > - vector0 = glob_bfloat_vec + is_a_float_vec; /* { dg-error {operation not permitted on type '__bf16'} } */ > > + vector0 = glob_bfloat_vec + *bfloat_ptr; > > + vector0 = glob_bfloat_vec + 0.1; /* { dg-error {conversion of scalar 'double' to vector '__m128bf16'} } */ > > + vector0 = glob_bfloat_vec + 0; > > + vector0 = glob_bfloat_vec + is_a_float_vec; /* { dg-error {invalid operands to binary \+} } */ > > > > return vector0; > > } > > --- gcc/testsuite/g++.target/i386/bfloat_cpp_typecheck.C.jj 2022-10-03 18:00:53.109734421 +0200 > > +++ gcc/testsuite/g++.target/i386/bfloat_cpp_typecheck.C 2022-10-13 16:57:09.362769399 +0200 > > @@ -5,6 +5,6 @@ void foo (void) > > { > > __bf16 (); /* { dg-bogus {invalid conversion to type '__bf16'} } */ > > __bf16 a = __bf16(); /* { dg-bogus {invalid conversion to type '__bf16'} } */ > > - __bf16 (0x1234); /* { dg-error {invalid conversion to type '__bf16'} } */ > > - __bf16 (0.1); /* { dg-error {invalid conversion to type '__bf16'} } */ > > + __bf16 (0x1234); /* { dg-bogus {invalid conversion to type '__bf16'} } */ > > + __bf16 (0.1); /* { dg-bogus {invalid conversion to type '__bf16'} } */ > > } > > --- libcpp/include/cpplib.h.jj 2022-10-03 18:00:53.251732506 +0200 > > +++ libcpp/include/cpplib.h 2022-10-13 16:57:09.384769097 +0200 > > @@ -1275,6 +1275,7 @@ struct cpp_num > > #define CPP_N_USERDEF 0x1000000 /* C++11 user-defined literal. */ > > > > #define CPP_N_SIZE_T 0x2000000 /* C++23 size_t literal. */ > > +#define CPP_N_BFLOAT16 0x4000000 /* std::bfloat16_t type. */ > > > > #define CPP_N_WIDTH_FLOATN_NX 0xF0000000 /* _FloatN / _FloatNx value > > of N, divided by 16. */ > > --- libcpp/expr.cc.jj 2022-10-03 18:00:53.221732910 +0200 > > +++ libcpp/expr.cc 2022-10-13 16:58:01.360055690 +0200 > > @@ -91,10 +91,10 @@ interpret_float_suffix (cpp_reader *pfil > > size_t orig_len = len; > > const uchar *orig_s = s; > > size_t flags; > > - size_t f, d, l, w, q, i, fn, fnx, fn_bits; > > + size_t f, d, l, w, q, i, fn, fnx, fn_bits, bf16; > > > > flags = 0; > > - f = d = l = w = q = i = fn = fnx = fn_bits = 0; > > + f = d = l = w = q = i = fn = fnx = fn_bits = bf16 = 0; > > > > /* The following decimal float suffixes, from TR 24732:2009, TS > > 18661-2:2015 and C2X, are supported: > > @@ -131,7 +131,8 @@ interpret_float_suffix (cpp_reader *pfil > > w, W - machine-specific type such as __float80 (GNU extension). > > q, Q - machine-specific type such as __float128 (GNU extension). > > fN, FN - _FloatN (TS 18661-3:2015). > > - fNx, FNx - _FloatNx (TS 18661-3:2015). */ > > + fNx, FNx - _FloatNx (TS 18661-3:2015). > > + bf16, BF16 - std::bfloat16_t (ISO C++23). */ > > > > /* Process decimal float suffixes, which are two letters starting > > with d or D. Order and case are significant. */ > > @@ -239,6 +240,19 @@ interpret_float_suffix (cpp_reader *pfil > > fn++; > > } > > break; > > + case 'b': case 'B': > > + if (len > 2 > > + /* Except for bf16 / BF16 where case is significant. */ > > + && s[1] == (s[0] == 'b' ? 'f' : 'F') > > + && s[2] == '1' > > + && s[3] == '6') > > + { > > + bf16++; > > + len -= 3; > > + s += 3; > > + break; > > + } > > + return 0; > > case 'd': case 'D': d++; break; > > case 'l': case 'L': l++; break; > > case 'w': case 'W': w++; break; > > @@ -257,7 +271,7 @@ interpret_float_suffix (cpp_reader *pfil > > of N larger than can be represented in the return value. The > > caller is responsible for rejecting _FloatN suffixes where > > _FloatN is not supported on the chosen target. */ > > - if (f + d + l + w + q + fn + fnx > 1 || i > 1) > > + if (f + d + l + w + q + fn + fnx + bf16 > 1 || i > 1) > > return 0; > > if (fn_bits > CPP_FLOATN_MAX) > > return 0; > > @@ -295,6 +309,7 @@ interpret_float_suffix (cpp_reader *pfil > > q ? CPP_N_MD_Q : > > fn ? CPP_N_FLOATN | (fn_bits << CPP_FLOATN_SHIFT) : > > fnx ? CPP_N_FLOATNX | (fn_bits << CPP_FLOATN_SHIFT) : > > + bf16 ? CPP_N_BFLOAT16 : > > CPP_N_DEFAULT)); > > } > > > > --- libgcc/config/i386/t-softfp.jj 2022-10-03 18:00:53.314731656 +0200 > > +++ libgcc/config/i386/t-softfp 2022-10-13 16:57:09.426768521 +0200 > > @@ -6,8 +6,9 @@ LIB2FUNCS_EXCLUDE += $(libgcc2-hf-functi > > libgcc2-hf-extras = $(addsuffix .c, $(libgcc2-hf-functions)) > > LIB2ADD += $(addprefix $(srcdir)/config/i386/, $(libgcc2-hf-extras)) > > > > -softfp_extensions := hfsf hfdf hftf hfxf sfdf sftf dftf xftf > > -softfp_truncations := tfhf xfhf dfhf sfhf tfsf dfsf tfdf tfxf > > +softfp_extensions := hfsf hfdf hftf hfxf sfdf sftf dftf xftf bfsf > > +softfp_truncations := tfhf xfhf dfhf sfhf tfsf dfsf tfdf tfxf \ > > + tfbf xfbf dfbf sfbf hfbf > > > > softfp_extras += eqhf2 > > > > @@ -15,11 +16,17 @@ CFLAGS-extendhfsf2.c += -msse2 > > CFLAGS-extendhfdf2.c += -msse2 > > CFLAGS-extendhftf2.c += -msse2 > > CFLAGS-extendhfxf2.c += -msse2 > > +CFLAGS-extendbfsf2.c += -msse2 > > > > CFLAGS-truncsfhf2.c += -msse2 > > CFLAGS-truncdfhf2.c += -msse2 > > CFLAGS-truncxfhf2.c += -msse2 > > CFLAGS-trunctfhf2.c += -msse2 > > +CFLAGS-truncsfbf2.c += -msse2 > > +CFLAGS-truncdfbf2.c += -msse2 > > +CFLAGS-truncxfbf2.c += -msse2 > > +CFLAGS-trunctfbf2.c += -msse2 > > +CFLAGS-trunchfbf2.c += -msse2 > > > > CFLAGS-eqhf2.c += -msse2 > > CFLAGS-_divhc3.c += -msse2 > > --- libgcc/config/i386/libgcc-glibc.ver.jj 2022-10-03 18:00:53.313731670 +0200 > > +++ libgcc/config/i386/libgcc-glibc.ver 2022-10-13 16:57:09.438768356 +0200 > > @@ -214,3 +214,13 @@ GCC_12.0.0 { > > __trunctfhf2 > > __truncxfhf2 > > } > > + > > +%inherit GCC_13.0.0 GCC_12.0.0 > > +GCC_13.0.0 { > > + __extendbfsf2 > > + __truncdfbf2 > > + __truncsfbf2 > > + __trunctfbf2 > > + __truncxfbf2 > > + __trunchfbf2 > > +} > > --- libgcc/config/i386/sfp-machine.h.jj 2022-10-03 18:00:53.313731670 +0200 > > +++ libgcc/config/i386/sfp-machine.h 2022-10-13 16:57:09.441768315 +0200 > > @@ -18,6 +18,7 @@ typedef int __gcc_CMPtype __attribute__ > > #define _FP_QNANNEGATEDP 0 > > > > #define _FP_NANSIGN_H 1 > > +#define _FP_NANSIGN_B 1 > > #define _FP_NANSIGN_S 1 > > #define _FP_NANSIGN_D 1 > > #define _FP_NANSIGN_E 1 > > --- libgcc/config/i386/64/sfp-machine.h.jj 2022-10-03 18:00:53.290731980 +0200 > > +++ libgcc/config/i386/64/sfp-machine.h 2022-10-13 16:57:09.451768178 +0200 > > @@ -14,6 +14,7 @@ typedef unsigned int UTItype __attribute > > #define _FP_DIV_MEAT_Q(R,X,Y) _FP_DIV_MEAT_2_udiv(Q,R,X,Y) > > > > #define _FP_NANFRAC_H _FP_QNANBIT_H > > +#define _FP_NANFRAC_B _FP_QNANBIT_B > > #define _FP_NANFRAC_S _FP_QNANBIT_S > > #define _FP_NANFRAC_D _FP_QNANBIT_D > > #define _FP_NANFRAC_E _FP_QNANBIT_E, 0 > > --- libgcc/config/i386/32/sfp-machine.h.jj 2022-10-03 18:00:53.290731980 +0200 > > +++ libgcc/config/i386/32/sfp-machine.h 2022-10-13 16:57:09.459768068 +0200 > > @@ -87,6 +87,7 @@ > > #define _FP_DIV_MEAT_Q(R,X,Y) _FP_DIV_MEAT_4_udiv(Q,R,X,Y) > > > > #define _FP_NANFRAC_H _FP_QNANBIT_H > > +#define _FP_NANFRAC_B _FP_QNANBIT_B > > #define _FP_NANFRAC_S _FP_QNANBIT_S > > #define _FP_NANFRAC_D _FP_QNANBIT_D, 0 > > /* Even if XFmode is 12byte, we have to pad it to > > --- libgcc/soft-fp/brain.h.jj 2022-10-13 16:57:09.460768054 +0200 > > +++ libgcc/soft-fp/brain.h 2022-10-13 16:57:09.459768068 +0200 > > @@ -0,0 +1,172 @@ > > +/* Software floating-point emulation. > > + Definitions for Brain Floating Point format (bfloat16). > > + Copyright (C) 1997-2022 Free Software Foundation, Inc. > > + This file is part of the GNU C Library. > > + > > + The GNU C Library is free software; you can redistribute it and/or > > + modify it under the terms of the GNU Lesser General Public > > + License as published by the Free Software Foundation; either > > + version 2.1 of the License, or (at your option) any later version. > > + > > + In addition to the permissions in the GNU Lesser General Public > > + License, the Free Software Foundation gives you unlimited > > + permission to link the compiled version of this file into > > + combinations with other programs, and to distribute those > > + combinations without any restriction coming from the use of this > > + file. (The Lesser General Public License restrictions do apply in > > + other respects; for example, they cover modification of the file, > > + and distribution when not linked into a combine executable.) > > + > > + The GNU C Library is distributed in the hope that it will be useful, > > + but WITHOUT ANY WARRANTY; without even the implied warranty of > > + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > > + Lesser General Public License for more details. > > + > > + You should have received a copy of the GNU Lesser General Public > > + License along with the GNU C Library; if not, see > > + . */ > > + > > +#ifndef SOFT_FP_BRAIN_H > > +#define SOFT_FP_BRAIN_H 1 > > + > > +#if _FP_W_TYPE_SIZE < 32 > > +# error "Here's a nickel kid. Go buy yourself a real computer." > > +#endif > > + > > +#define _FP_FRACTBITS_B (_FP_W_TYPE_SIZE) > > + > > +#define _FP_FRACTBITS_DW_B (_FP_W_TYPE_SIZE) > > + > > +#define _FP_FRACBITS_B 8 > > +#define _FP_FRACXBITS_B (_FP_FRACTBITS_B - _FP_FRACBITS_B) > > +#define _FP_WFRACBITS_B (_FP_WORKBITS + _FP_FRACBITS_B) > > +#define _FP_WFRACXBITS_B (_FP_FRACTBITS_B - _FP_WFRACBITS_B) > > +#define _FP_EXPBITS_B 8 > > +#define _FP_EXPBIAS_B 127 > > +#define _FP_EXPMAX_B 255 > > + > > +#define _FP_QNANBIT_B ((_FP_W_TYPE) 1 << (_FP_FRACBITS_B-2)) > > +#define _FP_QNANBIT_SH_B ((_FP_W_TYPE) 1 << (_FP_FRACBITS_B-2+_FP_WORKBITS)) > > +#define _FP_IMPLBIT_B ((_FP_W_TYPE) 1 << (_FP_FRACBITS_B-1)) > > +#define _FP_IMPLBIT_SH_B ((_FP_W_TYPE) 1 << (_FP_FRACBITS_B-1+_FP_WORKBITS)) > > +#define _FP_OVERFLOW_B ((_FP_W_TYPE) 1 << (_FP_WFRACBITS_B)) > > + > > +#define _FP_WFRACBITS_DW_B (2 * _FP_WFRACBITS_B) > > +#define _FP_WFRACXBITS_DW_B (_FP_FRACTBITS_DW_B - _FP_WFRACBITS_DW_B) > > +#define _FP_HIGHBIT_DW_B \ > > + ((_FP_W_TYPE) 1 << (_FP_WFRACBITS_DW_B - 1) % _FP_W_TYPE_SIZE) > > + > > +/* The implementation of _FP_MUL_MEAT_B and _FP_DIV_MEAT_B should be > > + chosen by the target machine. */ > > + > > +typedef float BFtype __attribute__ ((mode (BF))); > > + > > +union _FP_UNION_B > > +{ > > + BFtype flt; > > + struct _FP_STRUCT_LAYOUT > > + { > > +#if __BYTE_ORDER == __BIG_ENDIAN > > + unsigned sign : 1; > > + unsigned exp : _FP_EXPBITS_B; > > + unsigned frac : _FP_FRACBITS_B - (_FP_IMPLBIT_B != 0); > > +#else > > + unsigned frac : _FP_FRACBITS_B - (_FP_IMPLBIT_B != 0); > > + unsigned exp : _FP_EXPBITS_B; > > + unsigned sign : 1; > > +#endif > > + } bits; > > +}; > > + > > +#define FP_DECL_B(X) _FP_DECL (1, X) > > +#define FP_UNPACK_RAW_B(X, val) _FP_UNPACK_RAW_1 (B, X, (val)) > > +#define FP_UNPACK_RAW_BP(X, val) _FP_UNPACK_RAW_1_P (B, X, (val)) > > +#define FP_PACK_RAW_B(val, X) _FP_PACK_RAW_1 (B, (val), X) > > +#define FP_PACK_RAW_BP(val, X) \ > > + do \ > > + { \ > > + if (!FP_INHIBIT_RESULTS) \ > > + _FP_PACK_RAW_1_P (B, (val), X); \ > > + } \ > > + while (0) > > + > > +#define FP_UNPACK_B(X, val) \ > > + do \ > > + { \ > > + _FP_UNPACK_RAW_1 (B, X, (val)); \ > > + _FP_UNPACK_CANONICAL (B, 1, X); \ > > + } \ > > + while (0) > > + > > +#define FP_UNPACK_BP(X, val) \ > > + do \ > > + { \ > > + _FP_UNPACK_RAW_1_P (B, X, (val)); \ > > + _FP_UNPACK_CANONICAL (B, 1, X); \ > > + } \ > > + while (0) > > + > > +#define FP_UNPACK_SEMIRAW_B(X, val) \ > > + do \ > > + { \ > > + _FP_UNPACK_RAW_1 (B, X, (val)); \ > > + _FP_UNPACK_SEMIRAW (B, 1, X); \ > > + } \ > > + while (0) > > + > > +#define FP_UNPACK_SEMIRAW_BP(X, val) \ > > + do \ > > + { \ > > + _FP_UNPACK_RAW_1_P (B, X, (val)); \ > > + _FP_UNPACK_SEMIRAW (B, 1, X); \ > > + } \ > > + while (0) > > + > > +#define FP_PACK_B(val, X) \ > > + do \ > > + { \ > > + _FP_PACK_CANONICAL (B, 1, X); \ > > + _FP_PACK_RAW_1 (B, (val), X); \ > > + } \ > > + while (0) > > + > > +#define FP_PACK_BP(val, X) \ > > + do \ > > + { \ > > + _FP_PACK_CANONICAL (B, 1, X); \ > > + if (!FP_INHIBIT_RESULTS) \ > > + _FP_PACK_RAW_1_P (B, (val), X); \ > > + } \ > > + while (0) > > + > > +#define FP_PACK_SEMIRAW_B(val, X) \ > > + do \ > > + { \ > > + _FP_PACK_SEMIRAW (B, 1, X); \ > > + _FP_PACK_RAW_1 (B, (val), X); \ > > + } \ > > + while (0) > > + > > +#define FP_PACK_SEMIRAW_BP(val, X) \ > > + do \ > > + { \ > > + _FP_PACK_SEMIRAW (B, 1, X); \ > > + if (!FP_INHIBIT_RESULTS) \ > > + _FP_PACK_RAW_1_P (B, (val), X); \ > > + } \ > > + while (0) > > + > > +#define FP_TO_INT_B(r, X, rsz, rsg) _FP_TO_INT (B, 1, (r), X, (rsz), (rsg)) > > +#define FP_TO_INT_ROUND_B(r, X, rsz, rsg) \ > > + _FP_TO_INT_ROUND (B, 1, (r), X, (rsz), (rsg)) > > +#define FP_FROM_INT_B(X, r, rs, rt) _FP_FROM_INT (B, 1, X, (r), (rs), rt) > > + > > +/* BFmode arithmetic is not implemented. */ > > + > > +#define _FP_FRAC_HIGH_B(X) _FP_FRAC_HIGH_1 (X) > > +#define _FP_FRAC_HIGH_RAW_B(X) _FP_FRAC_HIGH_1 (X) > > +#define _FP_FRAC_HIGH_DW_B(X) _FP_FRAC_HIGH_1 (X) > > + > > +#define FP_CMP_EQ_B(r, X, Y, ex) _FP_CMP_EQ (B, 1, (r), X, Y, (ex)) > > + > > +#endif /* !SOFT_FP_BRAIN_H */ > > --- libgcc/soft-fp/truncsfbf2.c.jj 2022-10-13 16:57:09.460768054 +0200 > > +++ libgcc/soft-fp/truncsfbf2.c 2022-10-13 16:57:09.460768054 +0200 > > @@ -0,0 +1,48 @@ > > +/* Software floating-point emulation. > > + Truncate IEEE single into bfloat16. > > + Copyright (C) 2022 Free Software Foundation, Inc. > > + This file is part of the GNU C Library. > > + > > + The GNU C Library is free software; you can redistribute it and/or > > + modify it under the terms of the GNU Lesser General Public > > + License as published by the Free Software Foundation; either > > + version 2.1 of the License, or (at your option) any later version. > > + > > + In addition to the permissions in the GNU Lesser General Public > > + License, the Free Software Foundation gives you unlimited > > + permission to link the compiled version of this file into > > + combinations with other programs, and to distribute those > > + combinations without any restriction coming from the use of this > > + file. (The Lesser General Public License restrictions do apply in > > + other respects; for example, they cover modification of the file, > > + and distribution when not linked into a combine executable.) > > + > > + The GNU C Library is distributed in the hope that it will be useful, > > + but WITHOUT ANY WARRANTY; without even the implied warranty of > > + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > > + Lesser General Public License for more details. > > + > > + You should have received a copy of the GNU Lesser General Public > > + License along with the GNU C Library; if not, see > > + . */ > > + > > +#include "soft-fp.h" > > +#include "brain.h" > > +#include "single.h" > > + > > +BFtype > > +__truncsfbf2 (SFtype a) > > +{ > > + FP_DECL_EX; > > + FP_DECL_S (A); > > + FP_DECL_B (R); > > + BFtype r; > > + > > + FP_INIT_ROUNDMODE; > > + FP_UNPACK_SEMIRAW_S (A, a); > > + FP_TRUNC (B, S, 1, 1, R, A); > > + FP_PACK_SEMIRAW_B (r, R); > > + FP_HANDLE_EXCEPTIONS; > > + > > + return r; > > +} > > --- libgcc/soft-fp/truncdfbf2.c.jj 2022-10-13 16:57:09.460768054 +0200 > > +++ libgcc/soft-fp/truncdfbf2.c 2022-10-13 16:57:09.460768054 +0200 > > @@ -0,0 +1,52 @@ > > +/* Software floating-point emulation. > > + Truncate IEEE double into bfloat16. > > + Copyright (C) 2022 Free Software Foundation, Inc. > > + This file is part of the GNU C Library. > > + > > + The GNU C Library is free software; you can redistribute it and/or > > + modify it under the terms of the GNU Lesser General Public > > + License as published by the Free Software Foundation; either > > + version 2.1 of the License, or (at your option) any later version. > > + > > + In addition to the permissions in the GNU Lesser General Public > > + License, the Free Software Foundation gives you unlimited > > + permission to link the compiled version of this file into > > + combinations with other programs, and to distribute those > > + combinations without any restriction coming from the use of this > > + file. (The Lesser General Public License restrictions do apply in > > + other respects; for example, they cover modification of the file, > > + and distribution when not linked into a combine executable.) > > + > > + The GNU C Library is distributed in the hope that it will be useful, > > + but WITHOUT ANY WARRANTY; without even the implied warranty of > > + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > > + Lesser General Public License for more details. > > + > > + You should have received a copy of the GNU Lesser General Public > > + License along with the GNU C Library; if not, see > > + . */ > > + > > +#include "soft-fp.h" > > +#include "brain.h" > > +#include "double.h" > > + > > +BFtype > > +__truncdfbf2 (DFtype a) > > +{ > > + FP_DECL_EX; > > + FP_DECL_D (A); > > + FP_DECL_B (R); > > + BFtype r; > > + > > + FP_INIT_ROUNDMODE; > > + FP_UNPACK_SEMIRAW_D (A, a); > > +#if _FP_W_TYPE_SIZE < _FP_FRACBITS_D > > + FP_TRUNC (B, D, 1, 2, R, A); > > +#else > > + FP_TRUNC (B, D, 1, 1, R, A); > > +#endif > > + FP_PACK_SEMIRAW_B (r, R); > > + FP_HANDLE_EXCEPTIONS; > > + > > + return r; > > +} > > --- libgcc/soft-fp/truncxfbf2.c.jj 2022-10-13 16:57:09.460768054 +0200 > > +++ libgcc/soft-fp/truncxfbf2.c 2022-10-13 16:57:09.460768054 +0200 > > @@ -0,0 +1,52 @@ > > +/* Software floating-point emulation. > > + Truncate IEEE extended into bfloat16. > > + Copyright (C) 2022 Free Software Foundation, Inc. > > + This file is part of the GNU C Library. > > + > > + The GNU C Library is free software; you can redistribute it and/or > > + modify it under the terms of the GNU Lesser General Public > > + License as published by the Free Software Foundation; either > > + version 2.1 of the License, or (at your option) any later version. > > + > > + In addition to the permissions in the GNU Lesser General Public > > + License, the Free Software Foundation gives you unlimited > > + permission to link the compiled version of this file into > > + combinations with other programs, and to distribute those > > + combinations without any restriction coming from the use of this > > + file. (The Lesser General Public License restrictions do apply in > > + other respects; for example, they cover modification of the file, > > + and distribution when not linked into a combine executable.) > > + > > + The GNU C Library is distributed in the hope that it will be useful, > > + but WITHOUT ANY WARRANTY; without even the implied warranty of > > + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > > + Lesser General Public License for more details. > > + > > + You should have received a copy of the GNU Lesser General Public > > + License along with the GNU C Library; if not, see > > + . */ > > + > > +#include "soft-fp.h" > > +#include "brain.h" > > +#include "extended.h" > > + > > +BFtype > > +__truncxfbf2 (XFtype a) > > +{ > > + FP_DECL_EX; > > + FP_DECL_E (A); > > + FP_DECL_B (R); > > + BFtype r; > > + > > + FP_INIT_ROUNDMODE; > > + FP_UNPACK_SEMIRAW_E (A, a); > > +#if _FP_W_TYPE_SIZE < 64 > > + FP_TRUNC (B, E, 1, 4, R, A); > > +#else > > + FP_TRUNC (B, E, 1, 2, R, A); > > +#endif > > + FP_PACK_SEMIRAW_B (r, R); > > + FP_HANDLE_EXCEPTIONS; > > + > > + return r; > > +} > > --- libgcc/soft-fp/trunctfbf2.c.jj 2022-10-13 16:57:09.460768054 +0200 > > +++ libgcc/soft-fp/trunctfbf2.c 2022-10-13 16:57:09.460768054 +0200 > > @@ -0,0 +1,52 @@ > > +/* Software floating-point emulation. > > + Truncate IEEE quad into bfloat16. > > + Copyright (C) 2022 Free Software Foundation, Inc. > > + This file is part of the GNU C Library. > > + > > + The GNU C Library is free software; you can redistribute it and/or > > + modify it under the terms of the GNU Lesser General Public > > + License as published by the Free Software Foundation; either > > + version 2.1 of the License, or (at your option) any later version. > > + > > + In addition to the permissions in the GNU Lesser General Public > > + License, the Free Software Foundation gives you unlimited > > + permission to link the compiled version of this file into > > + combinations with other programs, and to distribute those > > + combinations without any restriction coming from the use of this > > + file. (The Lesser General Public License restrictions do apply in > > + other respects; for example, they cover modification of the file, > > + and distribution when not linked into a combine executable.) > > + > > + The GNU C Library is distributed in the hope that it will be useful, > > + but WITHOUT ANY WARRANTY; without even the implied warranty of > > + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > > + Lesser General Public License for more details. > > + > > + You should have received a copy of the GNU Lesser General Public > > + License along with the GNU C Library; if not, see > > + . */ > > + > > +#include "soft-fp.h" > > +#include "brain.h" > > +#include "quad.h" > > + > > +BFtype > > +__trunctfbf2 (TFtype a) > > +{ > > + FP_DECL_EX; > > + FP_DECL_Q (A); > > + FP_DECL_B (R); > > + BFtype r; > > + > > + FP_INIT_ROUNDMODE; > > + FP_UNPACK_SEMIRAW_Q (A, a); > > +#if _FP_W_TYPE_SIZE < 64 > > + FP_TRUNC (B, Q, 1, 4, R, A); > > +#else > > + FP_TRUNC (B, Q, 1, 2, R, A); > > +#endif > > + FP_PACK_SEMIRAW_B (r, R); > > + FP_HANDLE_EXCEPTIONS; > > + > > + return r; > > +} > > --- libgcc/soft-fp/trunchfbf2.c.jj 2022-10-13 16:57:09.460768054 +0200 > > +++ libgcc/soft-fp/trunchfbf2.c 2022-10-13 16:57:09.460768054 +0200 > > @@ -0,0 +1,58 @@ > > +/* Software floating-point emulation. > > + Truncate IEEE half into bfloat16. > > + Copyright (C) 2022 Free Software Foundation, Inc. > > + This file is part of the GNU C Library. > > + > > + The GNU C Library is free software; you can redistribute it and/or > > + modify it under the terms of the GNU Lesser General Public > > + License as published by the Free Software Foundation; either > > + version 2.1 of the License, or (at your option) any later version. > > + > > + In addition to the permissions in the GNU Lesser General Public > > + License, the Free Software Foundation gives you unlimited > > + permission to link the compiled version of this file into > > + combinations with other programs, and to distribute those > > + combinations without any restriction coming from the use of this > > + file. (The Lesser General Public License restrictions do apply in > > + other respects; for example, they cover modification of the file, > > + and distribution when not linked into a combine executable.) > > + > > + The GNU C Library is distributed in the hope that it will be useful, > > + but WITHOUT ANY WARRANTY; without even the implied warranty of > > + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > > + Lesser General Public License for more details. > > + > > + You should have received a copy of the GNU Lesser General Public > > + License along with the GNU C Library; if not, see > > + . */ > > + > > +#include "soft-fp.h" > > +#include "brain.h" > > +#include "half.h" > > +#include "single.h" > > + > > +/* BFtype and HFtype are unordered, neither is a superset or subset > > + of each other. Convert HFtype to SFtype (lossless) and then > > + truncate to BFtype. */ > > + > > +BFtype > > +__trunchfbf2 (HFtype a) > > +{ > > + FP_DECL_EX; > > + FP_DECL_H (A); > > + FP_DECL_S (B); > > + FP_DECL_B (R); > > + SFtype b; > > + BFtype r; > > + > > + FP_INIT_ROUNDMODE; > > + FP_UNPACK_RAW_H (A, a); > > + FP_EXTEND (S, H, 1, 1, B, A); > > + FP_PACK_RAW_S (b, B); > > + FP_UNPACK_SEMIRAW_S (B, b); > > + FP_TRUNC (B, S, 1, 1, R, B); > > + FP_PACK_SEMIRAW_B (r, R); > > + FP_HANDLE_EXCEPTIONS; > > + > > + return r; > > +} > > --- libgcc/soft-fp/truncbfhf2.c.jj 2022-10-13 16:57:09.460768054 +0200 > > +++ libgcc/soft-fp/truncbfhf2.c 2022-10-13 16:57:09.460768054 +0200 > > @@ -0,0 +1,75 @@ > > +/* Software floating-point emulation. > > + Truncate bfloat16 into IEEE half. > > + Copyright (C) 2022 Free Software Foundation, Inc. > > + This file is part of the GNU C Library. > > + > > + The GNU C Library is free software; you can redistribute it and/or > > + modify it under the terms of the GNU Lesser General Public > > + License as published by the Free Software Foundation; either > > + version 2.1 of the License, or (at your option) any later version. > > + > > + In addition to the permissions in the GNU Lesser General Public > > + License, the Free Software Foundation gives you unlimited > > + permission to link the compiled version of this file into > > + combinations with other programs, and to distribute those > > + combinations without any restriction coming from the use of this > > + file. (The Lesser General Public License restrictions do apply in > > + other respects; for example, they cover modification of the file, > > + and distribution when not linked into a combine executable.) > > + > > + The GNU C Library is distributed in the hope that it will be useful, > > + but WITHOUT ANY WARRANTY; without even the implied warranty of > > + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > > + Lesser General Public License for more details. > > + > > + You should have received a copy of the GNU Lesser General Public > > + License along with the GNU C Library; if not, see > > + . */ > > + > > +#include "soft-fp.h" > > +#include "half.h" > > +#include "brain.h" > > +#include "single.h" > > + > > +/* BFtype and HFtype are unordered, neither is a superset or subset > > + of each other. Convert BFtype to SFtype (lossless) and then > > + truncate to HFtype. */ > > + > > +HFtype > > +__truncbfhf2 (BFtype a) > > +{ > > + FP_DECL_EX; > > + FP_DECL_H (A); > > + FP_DECL_S (B); > > + FP_DECL_B (R); > > + SFtype b; > > + HFtype r; > > + > > + FP_INIT_ROUNDMODE; > > + /* Optimize BFtype to SFtype conversion to simple left shift > > + by 16 if possible, we don't need to raise exceptions on sNaN > > + here as the SFtype to HFtype truncation should do that too. */ > > + if (sizeof (BFtype) == 2 > > + && sizeof (unsigned short) == 2 > > + && sizeof (SFtype) == 4 > > + && sizeof (unsigned int) == 4) > > + { > > + union { BFtype a; unsigned short b; } u1; > > + union { SFtype a; unsigned int b; } u2; > > + u1.a = a; > > + u2.b = (u1.b << 8) << 8; > > + b = u2.a; > > + } > > + else > > + { > > + FP_UNPACK_RAW_B (A, a); > > + FP_EXTEND (S, B, 1, 1, B, A); > > + FP_PACK_RAW_S (b, B); > > + } > > + FP_UNPACK_SEMIRAW_S (B, b); > > + FP_TRUNC (H, S, 1, 1, R, B); > > + FP_PACK_SEMIRAW_H (r, R); > > + FP_HANDLE_EXCEPTIONS; > > + > > + return r; > > +} > > --- libgcc/soft-fp/extendbfsf2.c.jj 2022-10-13 16:57:09.460768054 +0200 > > +++ libgcc/soft-fp/extendbfsf2.c 2022-10-13 16:57:09.460768054 +0200 > > @@ -0,0 +1,49 @@ > > +/* Software floating-point emulation. > > + Return an bfloat16 converted to IEEE single > > + Copyright (C) 2022 Free Software Foundation, Inc. > > + This file is part of the GNU C Library. > > + > > + The GNU C Library is free software; you can redistribute it and/or > > + modify it under the terms of the GNU Lesser General Public > > + License as published by the Free Software Foundation; either > > + version 2.1 of the License, or (at your option) any later version. > > + > > + In addition to the permissions in the GNU Lesser General Public > > + License, the Free Software Foundation gives you unlimited > > + permission to link the compiled version of this file into > > + combinations with other programs, and to distribute those > > + combinations without any restriction coming from the use of this > > + file. (The Lesser General Public License restrictions do apply in > > + other respects; for example, they cover modification of the file, > > + and distribution when not linked into a combine executable.) > > + > > + The GNU C Library is distributed in the hope that it will be useful, > > + but WITHOUT ANY WARRANTY; without even the implied warranty of > > + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > > + Lesser General Public License for more details. > > + > > + You should have received a copy of the GNU Lesser General Public > > + License along with the GNU C Library; if not, see > > + . */ > > + > > +#define FP_NO_EXACT_UNDERFLOW > > +#include "soft-fp.h" > > +#include "brain.h" > > +#include "single.h" > > + > > +SFtype > > +__extendbfsf2 (BFtype a) > > +{ > > + FP_DECL_EX; > > + FP_DECL_B (A); > > + FP_DECL_S (R); > > + SFtype r; > > + > > + FP_INIT_EXCEPTIONS; > > + FP_UNPACK_RAW_B (A, a); > > + FP_EXTEND (S, B, 1, 1, R, A); > > + FP_PACK_RAW_S (r, R); > > + FP_HANDLE_EXCEPTIONS; > > + > > + return r; > > +} > > --- libiberty/cp-demangle.h.jj 2022-10-03 18:00:53.342731278 +0200 > > +++ libiberty/cp-demangle.h 2022-10-13 16:57:09.488767670 +0200 > > @@ -180,7 +180,7 @@ d_advance (struct d_info *di, int i) > > extern const struct demangle_operator_info cplus_demangle_operators[]; > > #endif > > > > -#define D_BUILTIN_TYPE_COUNT (35) > > +#define D_BUILTIN_TYPE_COUNT (36) > > > > CP_STATIC_IF_GLIBCPP_V3 > > const struct demangle_builtin_type_info > > --- libiberty/cp-demangle.c.jj 2022-10-11 14:50:14.605771753 +0200 > > +++ libiberty/cp-demangle.c 2022-10-13 16:57:09.538766983 +0200 > > @@ -2487,6 +2487,7 @@ cplus_demangle_builtin_types[D_BUILTIN_T > > /* 33 */ { NL ("decltype(nullptr)"), NL ("decltype(nullptr)"), > > D_PRINT_DEFAULT }, > > /* 34 */ { NL ("_Float"), NL ("_Float"), D_PRINT_FLOAT }, > > + /* 35 */ { NL ("std::bfloat16_t"), NL ("std::bfloat16_t"), D_PRINT_FLOAT }, > > }; > > > > CP_STATIC_IF_GLIBCPP_V3 > > @@ -2751,11 +2752,22 @@ cplus_demangle_type (struct d_info *di) > > > > case 'F': > > /* DF_ - _Float. > > - DFx - _Floatx. */ > > + DFx - _Floatx > > + DF16b - std::bfloat16_t. */ > > { > > int arg = d_number (di); > > char buf[12]; > > char suffix = 0; > > + if (d_peek_char (di) == 'b') > > + { > > + if (arg != 16) > > + return NULL; > > + d_advance (di, 1); > > + ret = d_make_builtin_type (di, > > + &cplus_demangle_builtin_types[35]); > > + di->expansion += ret->u.s_builtin.type->len; > > + break; > > + } > > if (d_peek_char (di) == 'x') > > suffix = 'x'; > > if (!suffix && d_peek_char (di) != '_') > > --- libiberty/testsuite/demangle-expected.jj 2022-10-11 14:50:14.618771575 +0200 > > +++ libiberty/testsuite/demangle-expected 2022-10-13 16:57:09.553766778 +0200 > > @@ -1249,6 +1249,10 @@ xxx > > _Z3xxxDF32xDF64xDF128xCDF32xVb > > xxx(_Float32x, _Float64x, _Float128x, _Float32x _Complex, bool volatile) > > xxx > > +--format=auto --no-params > > +_Z3xxxDF16b > > +xxx(std::bfloat16_t) > > +xxx > > # https://sourceware.org/bugzilla/show_bug.cgi?id=16817 > > --format=auto --no-params > > _QueueNotification_QueueController__$4PPPPPPPM_A_INotice___Z > > > > > > Jakub > > >