On Thu, 4 Jun 2026, Jakub Jelinek wrote:

> On Wed, Jun 03, 2026 at 09:01:31PM -0400, Jason Merrill wrote:
> > Since you pass the vec to the new build_... function, why not give this
> > error there along with all the others?
> 
> Done.
> 
> > > +  if (type == char_type_node)
> > > +    {
> > > +      if (complain & tf_error)
> > > + error_at (loc, "argument 1 in call to function "
> > > +                "%qs has %<char%> type", name);
> > 
> > This might suggest using "unsigned char" instead, for clarity.
> 
> I've dropped this instead.  I've copied this over from the __builtin_stdc_*
> handling because it was right above it in c-parser.cc, but actually
> __builtin_{bswap,bitreverse}g should have consistent behavior with
> __builtin_{clz,ctz,parity,popcount}g, not __builtin_stdc_*.  And while
> all the other checks are in both, the is not char is just pedantry
> from the C23 <stdbit.h> requirements on those functions, clz etc. happily
> allow char on -funsigned-char and clrsb/ffs allow char on -fsigned-char
> targets.
> 
> > > @@ -3245,6 +3245,30 @@ cxx_eval_internal_function (const conste
> > >       case IFN_DEFERRED_INIT:
> > >         return build_clobber (TREE_TYPE (t), CLOBBER_OBJECT_BEGIN);
> > > +    case IFN_BSWAP:
> > > +    case IFN_BITREVERSE:
> > > +      {
> > > + tree arg = cxx_eval_constant_expression (ctx, CALL_EXPR_ARG (t, 0),
> > > +                                          vc_prvalue, non_constant_p,
> > > +                                          overflow_p, jump_target);
> > > + if (*jump_target)
> > > +   return NULL_TREE;
> > 
> > I think we want to check *non_constant_p here rather than fall through to
> > giving a redundant error.
> 
> Done.
> 
> Here is an updated version of the patch with those changes.
> Tested on x86_64-linux and i686-linux, also with -funsigned-char on the
> relevant tests.

The middle-end changes are OK.

Thanks,
Richard.

> 2026-06-04  Jakub Jelinek  <[email protected]>
> 
>       PR c/122731
> gcc/
>       * doc/extend.texi (__builtin_bswapg, __builtin_bitreverseg): Document.
>       * internal-fn.def (DEF_INTERNAL_INTSZ_FN): Define.
>       (DEF_INTERNAL_INTSZ_EXT_FN): Define.
>       (BSWAP): New internal fn.
>       (BITREVERSE): Likewise.
>       * internal-fn.h (expand_BSWAP, expand_BITREVERSE): Declare.
>       * internal-fn.cc (DEF_INTERNAL_INTSZ_EXT_FN): Define.
>       (expand_BSWAP, expand_BITREVERSE): New functions.
>       * builtins.h (fold_build_builtin_bswapg_bitreverseg): Declare.
>       * builtins.cc (fold_build_builtin_bswapg_bitreverseg): New function.
>       * wide-int.h (wi::bswap): Fix up docs that only multiple of 8 bits
>       is required.
>       * gimple-match-exports.cc (build_call_internal): Handle IFN_BSWAP
>       and IFN_BITREVERSE.
>       * gencfn-macros.cc (internal_fn_intsz_names): New variable.
>       (intsz_suffixes): Likewise.
>       (suffix_lists): Add intsz_suffixes.
>       (main): Handle internal_fn_intsz_names.
>       * match.pd (BSWAP, BITREVERSE): Remove.
>       (popcount(bswap(x)) is popcount(x)): Use BSWAP BITREVERSE
>       op lists.
>       * tree-ssa-phiopt.cc (empty_bb_or_one_feeding_into_p): Use
>       CASE_CFN_BSWAP and CASE_CFN_BITREVERSE.
>       (cond_removal_in_builtin_zero_pattern): Likewise.
>       * fold-const-call.cc (fold_const_call_ss): Likewise.
>       * fold-const.cc (tree_call_nonnegative_p): Likewise.
>       * gimple-lower-bitint.cc (struct bitint_large_huge): Declare
>       lower_bswap_bitreverse method.
>       (bitint_large_huge::lower_bswap_bitreverse): New method.
>       (bitint_large_huge::lower_call): Call it.
>       (build_bitint_stmt_ssa_conflicts): Set muldiv_p for IFN_BSWAP
>       and IFN_BITREVERSE.
> gcc/c-family/
>       * c-common.h (enum rid): Add RID_BUILTIN_BSWAPG and
>       RID_BUILTIN_BITREVERSEG.
>       * c-common.cc (c_common_reswords): Add __builtin_bswapg
>       and __builtin_bitreverseg.
> gcc/c/
>       * c-parser.cc (c_parser_postfix_expression): Parse
>       __builtin_bswapg and __builtin_bitreverseg.
> gcc/cp/
>       * parser.cc (cp_parser_postfix_expression): Parse
>       __builtin_bswapg and __builtin_bitreverseg.
>       * typeck.cc (build_x_bswapg_bitreverseg): New function.
>       * cp-tree.h (build_x_bswapg_bitreverseg): Declare.
>       * pt.cc (tsubst_expr): Handle IFN_BSWAP and IFN_BITREVERSE.
>       * constexpr.cc (cxx_eval_internal_function): Likewise.
>       (potential_constant_expression_1): Likewise.
>       * cp-gimplify.cc (cp_gimplify_expr): Likewise.
> gcc/testsuite/
>       * c-c++-common/builtin-bswapg-1.c: New test.
>       * c-c++-common/builtin-bswapg-2.c: New test.
>       * c-c++-common/builtin-bswapg-3.c: New test.
>       * c-c++-common/builtin-bitreverseg-1.c: New test.
>       * c-c++-common/builtin-bitreverseg-2.c: New test.
> 
> --- gcc/doc/extend.texi.jj    2026-06-04 08:24:31.113114961 +0200
> +++ gcc/doc/extend.texi       2026-06-04 08:31:41.561392321 +0200
> @@ -16095,6 +16095,12 @@ Similar to @code{__builtin_bswap64}, exc
>  are 128-bit.  Only supported on targets when 128-bit types are supported.
>  @enddefbuiltin
>  
> +@defbuiltin{@var{type} __builtin_bswapg (@var{type} @var{x})}
> +Similar to @code{__builtin_bswap64}, except the argument is type-generic
> +unsigned integer (standard, extended or bit-precise) with width which is
> +multiple of 8.  No integral argument promotions are performed on the 
> argument.
> +@enddefbuiltin
> +
>  @defbuiltin{uint8_t __builtin_bitreverse8 (uint8_t @var{x})}
>  Returns @var{x} with all bits reversed.
>  @enddefbuiltin
> @@ -16119,6 +16125,12 @@ Similar to @code{__builtin_bitreverse64}
>  are 128-bit.  Only supported on targets when 128-bit types are supported.
>  @enddefbuiltin
>  
> +@defbuiltin{@var{type} __builtin_bitreverseg (@var{type} @var{x})}
> +Similar to @code{__builtin_bitreverse64}, except the argument is type-generic
> +unsigned integer (standard, extended or bit-precise).
> +No integral argument promotions are performed on the argument.
> +@enddefbuiltin
> +
>  @node CRC Builtins
>  @subsection CRC Builtins
>  @cindex CRC builtins
> --- gcc/internal-fn.def.jj    2026-06-04 08:24:31.129114748 +0200
> +++ gcc/internal-fn.def       2026-06-04 08:31:41.562941003 +0200
> @@ -36,6 +36,8 @@ along with GCC; see the file COPYING3.
>       DEF_INTERNAL_FLT_FLOATN_FN (NAME, FLAGS, OPTAB, TYPE)
>       DEF_INTERNAL_INT_FN (NAME, FLAGS, OPTAB, TYPE)
>       DEF_INTERNAL_INT_EXT_FN (NAME, FLAGS, OPTAB, TYPE)
> +     DEF_INTERNAL_INTSZ_FN (NAME, FLAGS, OPTAB, TYPE)
> +     DEF_INTERNAL_INTSZ_EXT_FN (NAME, FLAGS, OPTAB, TYPE)
>       DEF_INTERNAL_COND_FN (NAME, FLAGS, OPTAB, TYPE)
>       DEF_INTERNAL_SIGNED_COND_FN (NAME, FLAGS, OPTAB, TYPE)
>       DEF_INTERNAL_WIDENING_OPTAB_FN (NAME, FLAGS, SELECTOR, SOPTAB, UOPTAB,
> @@ -107,6 +109,14 @@ along with GCC; see the file COPYING3.
>     has expand_##NAME defined in internal-fn.cc to override the
>     DEF_INTERNAL_INT_FN expansion behavior.
>  
> +   DEF_INTERNAL_INTSZ_FN is like DEF_INTERNAL_OPTAB_FN, but in addition
> +   says that the function extends the C-level BUILT_IN_<NAME>{8,16,32,64,128}
> +   group of functions to any integral mode (including vector modes).
> +
> +   DEF_INTERNAL_INTSZ_EXT_FN is like DEF_INTERNAL_INTSZ_FN, except that it
> +   has expand_##NAME defined in internal-fn.cc to override the
> +   DEF_INTERNAL_INTSZ_FN expansion behavior.
> +
>     DEF_INTERNAL_WIDENING_OPTAB_FN is a wrapper that defines five internal
>     functions with DEF_INTERNAL_SIGNED_OPTAB_FN:
>     - one that describes a widening operation with the same number of elements
> @@ -175,6 +185,16 @@ along with GCC; see the file COPYING3.
>    DEF_INTERNAL_INT_FN (NAME, FLAGS, OPTAB, TYPE)
>  #endif
>  
> +#ifndef DEF_INTERNAL_INTSZ_FN
> +#define DEF_INTERNAL_INTSZ_FN(NAME, FLAGS, OPTAB, TYPE) \
> +  DEF_INTERNAL_OPTAB_FN (NAME, FLAGS, OPTAB, TYPE)
> +#endif
> +
> +#ifndef DEF_INTERNAL_INTSZ_EXT_FN
> +#define DEF_INTERNAL_INTSZ_EXT_FN(NAME, FLAGS, OPTAB, TYPE) \
> +  DEF_INTERNAL_INTSZ_FN (NAME, FLAGS, OPTAB, TYPE)
> +#endif
> +
>  #ifndef DEF_INTERNAL_WIDENING_OPTAB_FN
>  #define DEF_INTERNAL_WIDENING_OPTAB_FN(NAME, FLAGS, SELECTOR, SOPTAB, 
> UOPTAB, TYPE)              \
>    DEF_INTERNAL_SIGNED_OPTAB_FN (NAME, FLAGS, SELECTOR, SOPTAB, UOPTAB, TYPE) 
>                     \
> @@ -471,6 +491,9 @@ DEF_INTERNAL_INT_EXT_FN (CTZ, ECF_CONST
>  DEF_INTERNAL_INT_EXT_FN (FFS, ECF_CONST | ECF_NOTHROW, ffs, unary)
>  DEF_INTERNAL_INT_EXT_FN (PARITY, ECF_CONST | ECF_NOTHROW, parity, unary)
>  DEF_INTERNAL_INT_EXT_FN (POPCOUNT, ECF_CONST | ECF_NOTHROW, popcount, unary)
> +DEF_INTERNAL_INTSZ_EXT_FN (BSWAP, ECF_CONST | ECF_NOTHROW, bswap, unary)
> +DEF_INTERNAL_INTSZ_EXT_FN (BITREVERSE, ECF_CONST | ECF_NOTHROW, bitreverse,
> +                        unary)
>  
>  DEF_INTERNAL_FN (GOMP_TARGET_REV, ECF_NOVOPS | ECF_LEAF | ECF_NOTHROW, NULL)
>  DEF_INTERNAL_FN (GOMP_USE_SIMT, ECF_NOVOPS | ECF_LEAF | ECF_NOTHROW, NULL)
> @@ -627,6 +650,8 @@ DEF_INTERNAL_OPTAB_FN (BIT_IORN, ECF_CON
>  #undef DEF_INTERNAL_COND_FN
>  #undef DEF_INTERNAL_INT_EXT_FN
>  #undef DEF_INTERNAL_INT_FN
> +#undef DEF_INTERNAL_INTSZ_EXT_FN
> +#undef DEF_INTERNAL_INTSZ_FN
>  #undef DEF_INTERNAL_FLT_FN
>  #undef DEF_INTERNAL_FLT_FLOATN_FN
>  #undef DEF_INTERNAL_SIGNED_OPTAB_FN
> --- gcc/internal-fn.h.jj      2026-06-04 08:24:31.130114735 +0200
> +++ gcc/internal-fn.h 2026-06-04 08:31:41.563173222 +0200
> @@ -285,6 +285,8 @@ extern void expand_CTZ (internal_fn, gca
>  extern void expand_FFS (internal_fn, gcall *);
>  extern void expand_PARITY (internal_fn, gcall *);
>  extern void expand_POPCOUNT (internal_fn, gcall *);
> +extern void expand_BSWAP (internal_fn, gcall *);
> +extern void expand_BITREVERSE (internal_fn, gcall *);
>  
>  extern bool vectorized_internal_fn_supported_p (internal_fn, tree);
>  
> --- gcc/internal-fn.cc.jj     2026-06-04 08:24:31.129114748 +0200
> +++ gcc/internal-fn.cc        2026-06-04 08:31:41.563540062 +0200
> @@ -4765,6 +4765,7 @@ set_edom_supported_p (void)
>      expand_##TYPE##_optab_fn (fn, stmt, OPTAB##_optab);      \
>    }
>  #define DEF_INTERNAL_INT_EXT_FN(CODE, FLAGS, OPTAB, TYPE)
> +#define DEF_INTERNAL_INTSZ_EXT_FN(CODE, FLAGS, OPTAB, TYPE)
>  #define DEF_INTERNAL_SIGNED_OPTAB_FN(CODE, FLAGS, SELECTOR, SIGNED_OPTAB, \
>                                    UNSIGNED_OPTAB, TYPE)              \
>    static void                                                                
> \
> @@ -5930,3 +5931,17 @@ expand_POPCOUNT (internal_fn fn, gcall *
>        emit_insn (all_insns);
>      }
>  }
> +
> +void
> +expand_BSWAP (internal_fn fn, gcall *stmt)
> +{
> +  if (expand_bitquery (fn, stmt))
> +    expand_unary_optab_fn (fn, stmt, bswap_optab);
> +}
> +
> +void
> +expand_BITREVERSE (internal_fn fn, gcall *stmt)
> +{
> +  if (expand_bitquery (fn, stmt))
> +    expand_unary_optab_fn (fn, stmt, bitreverse_optab);
> +}
> --- gcc/builtins.h.jj 2026-06-04 08:24:31.058115692 +0200
> +++ gcc/builtins.h    2026-06-04 08:31:41.563934858 +0200
> @@ -140,6 +140,8 @@ extern rtx expand_builtin (tree, rtx, rt
>  extern enum built_in_function builtin_mathfn_code (const_tree);
>  extern tree fold_builtin_expect (location_t, tree, tree, tree, tree);
>  extern tree fold_builtin_constant_p (tree);
> +extern tree fold_build_builtin_bswapg_bitreverseg (location_t, internal_fn,
> +                                                tree);
>  extern bool avoid_folding_inline_builtin (tree);
>  extern tree fold_call_expr (location_t, tree, bool);
>  extern tree fold_builtin_call_array (location_t, tree, tree, int, tree *);
> --- gcc/builtins.cc.jj        2026-06-04 08:24:31.047115838 +0200
> +++ gcc/builtins.cc   2026-06-04 08:31:41.564569034 +0200
> @@ -10522,6 +10522,53 @@ fold_builtin_bit_query (location_t loc,
>    return call;
>  }
>  
> +/* Fold or build a __builtin_bswapg (ARG) (if IFN is IFN_BSWAP) or
> +   __builtin_bitreverseg (ARG (otherwise) call.  The FE should have
> +   verified earlier that the argument type is unsigned INTEGER_TYPE
> +   or BITINT_TYPE, for __builtin_bswapg with precision divisible by 8.  */
> +
> +tree
> +fold_build_builtin_bswapg_bitreverseg (location_t loc, enum internal_fn ifn,
> +                                    tree arg)
> +{
> +  tree type = TYPE_MAIN_VARIANT (TREE_TYPE (arg));
> +  if (ifn == IFN_BSWAP && TYPE_PRECISION (type) == 8)
> +    return fold_convert_loc (loc, type, arg);
> +  struct { tree type; built_in_function bswap, bitreverse; } fns[]
> +    = { { unsigned_char_type_node, END_BUILTINS, BUILT_IN_BITREVERSE8 },
> +     { uint16_type_node, BUILT_IN_BSWAP16, BUILT_IN_BITREVERSE16 },
> +     { uint32_type_node, BUILT_IN_BSWAP32, BUILT_IN_BITREVERSE32 },
> +     { uint64_type_node, BUILT_IN_BSWAP64, BUILT_IN_BITREVERSE64 },
> +     { uint128_type_node, BUILT_IN_BSWAP128, BUILT_IN_BITREVERSE128 } };
> +  if (TREE_CODE (arg) == INTEGER_CST)
> +    {
> +      wide_int res;
> +      if (ifn == IFN_BSWAP)
> +     res = wi::bswap (wi::to_wide (arg));
> +      else
> +     res = wi::bitreverse (wi::to_wide (arg));
> +      return wide_int_to_tree (type, res);
> +    }
> +  for (unsigned i = 0; i < ARRAY_SIZE (fns); ++i)
> +    if (fns[i].type
> +     && TYPE_PRECISION (fns[i].type) >= TYPE_PRECISION (type))
> +      {
> +     arg = fold_convert_loc (loc, fns[i].type, arg);
> +     tree fndecl
> +       = builtin_decl_explicit (ifn == IFN_BSWAP
> +                                ? fns[i].bswap : fns[i].bitreverse);
> +     tree ret = build_call_expr_loc (loc, fndecl, 1, arg);
> +     if (TYPE_PRECISION (type) != TYPE_PRECISION (fns[i].type))
> +       ret = fold_build2_loc (loc, RSHIFT_EXPR, fns[i].type, ret,
> +                              build_int_cst (unsigned_type_node,
> +                                             TYPE_PRECISION (fns[i].type)
> +                                             - TYPE_PRECISION (type)));
> +     return fold_convert_loc (loc, type, ret);
> +      }
> +  gcc_assert (TREE_CODE (type) == BITINT_TYPE);
> +  return build_call_expr_internal_loc (loc, ifn, type, 1, arg);
> +}
> +
>  /* Fold __builtin_{add,sub}c{,l,ll} into pair of internal functions
>     that return both result of arithmetics and overflowed boolean
>     flag in a complex integer result.  */
> --- gcc/wide-int.h.jj 2026-06-04 08:24:31.136114655 +0200
> +++ gcc/wide-int.h    2026-06-04 08:31:41.565335815 +0200
> @@ -2655,7 +2655,7 @@ wi::set_bit (const T &x, unsigned int bi
>  
>  /* Byte swap the integer X.
>     ??? This always swaps 8-bit octets, regardless of BITS_PER_UNIT.
> -   This function requires X's precision to be a multiple of 16 bits,
> +   This function requires X's precision to be a multiple of 8 bits,
>     so care needs to be taken for targets where BITS_PER_UNIT != 8.  */
>  template <typename T>
>  inline WI_UNARY_RESULT (T)
> --- gcc/gimple-match-exports.cc.jj    2026-06-04 08:24:31.126114788 +0200
> +++ gcc/gimple-match-exports.cc       2026-06-04 08:31:41.565659698 +0200
> @@ -266,7 +266,9 @@ build_call_internal (internal_fn fn, gim
>           case IFN_FFS:
>           case IFN_POPCOUNT:
>           case IFN_PARITY:
> -           /* For these 6 builtins large/huge _BitInt operand is ok
> +         case IFN_BSWAP:
> +         case IFN_BITREVERSE:
> +           /* For these 8 builtins large/huge _BitInt operand is ok
>                before bitint lowering pass.  */
>             if (res_op->num_ops >= 1
>                 && BITINT_TYPE_P (TREE_TYPE (res_op->ops[0]))
> --- gcc/gencfn-macros.cc.jj   2026-06-04 08:24:31.121114854 +0200
> +++ gcc/gencfn-macros.cc      2026-06-04 08:31:41.565842296 +0200
> @@ -154,6 +154,13 @@ const char *const internal_fn_int_names[
>    NULL
>  };
>  
> +const char *const internal_fn_intsz_names[] = {
> +#define DEF_INTERNAL_INTSZ_FN(NAME, FLAGS, OPTAB, TYPE) \
> +  #NAME,
> +#include "internal-fn.def"
> +  NULL
> +};
> +
>  static const char *const flt_suffixes[] = { "F", "", "L", NULL };
>  static const char *const fltfn_suffixes[] = { "F16", "F32", "F64", "F128",
>                                             "F32X", "F64X", "F128X", NULL };
> @@ -161,10 +168,13 @@ static const char *const fltall_suffixes
>                                              "F64", "F128", "F32X", "F64X",
>                                              "F128X", NULL };
>  static const char *const int_suffixes[] = { "", "L", "LL", "IMAX", NULL };
> +static const char *const intsz_suffixes[] = { "8", "16", "32", "64", "128",
> +                                           NULL };
>  
>  static const char *const *const suffix_lists[] = {
>    flt_suffixes,
>    int_suffixes,
> +  intsz_suffixes,
>    NULL
>  };
>  
> @@ -186,6 +196,7 @@ main (int argc, char **argv)
>    add_to_set (&builtins, builtin_names);
>    add_to_set (&internal_fns, internal_fn_flt_names);
>    add_to_set (&internal_fns, internal_fn_int_names);
> +  add_to_set (&internal_fns, internal_fn_intsz_names);
>  
>    /* Check the functions.  */
>    for (unsigned int i = 0; internal_fn_flt_names[i]; ++i)
> @@ -202,6 +213,15 @@ main (int argc, char **argv)
>       error ("DEF_INTERNAL_INT_FN (%s) has no associated built-in"
>              " functions", name);
>      }
> +  for (unsigned int i = 0; internal_fn_intsz_names[i]; ++i)
> +    {
> +      const char *name = internal_fn_intsz_names[i];
> +      if (!is_group (&builtins, name,
> +                  /* There is no BUILT_IN_BSWAP8.  */
> +                  intsz_suffixes + (startswith (name, "BSWAP") ? 1 : 0)))
> +     error ("DEF_INTERNAL_INTSZ_FN (%s) has no associated built-in"
> +            " functions", name);
> +    }
>  
>    /* Go through the built-in functions in declaration order, outputting
>       definitions as appropriate.  */
> @@ -211,10 +231,25 @@ main (int argc, char **argv)
>        if (startswith (name, "BUILT_IN_"))
>       {
>         const char *root = name + 9;
> +       char buf[128];
>         for (unsigned int j = 0; suffix_lists[j]; ++j)
>           {
> -           const char *const *const suffix = suffix_lists[j];
> +           const char *const *suffix = suffix_lists[j];
>  
> +           if (suffix == intsz_suffixes)
> +             {
> +               if (!endswith (root, "32"))
> +                 continue;
> +               size_t len = strlen (root);
> +               if (len > sizeof (buf))
> +                 continue;
> +               /* There is no BUILT_IN_BSWAP8.  */
> +               if (startswith (root, "BSWAP"))
> +                 suffix++;
> +               memcpy (buf, root, len - 2);
> +               buf[len - 2] = '\0';
> +               root = buf;
> +             }
>             if (is_group (&builtins, root, suffix))
>               {
>                 bool internal_p = internal_fns.contains (root);
> --- gcc/match.pd.jj   2026-06-04 08:24:37.630028321 +0200
> +++ gcc/match.pd      2026-06-04 08:31:41.566357636 +0200
> @@ -53,10 +53,6 @@ (define_operator_list swapped_tcc_compar
>    gt   ge   eq ne le   lt   unordered ordered   ungt unge unlt unle uneq 
> ltgt)
>  (define_operator_list simple_comparison         lt   le   eq ne ge   gt)
>  (define_operator_list swapped_simple_comparison gt   ge   eq ne le   lt)
> -(define_operator_list BSWAP BUILT_IN_BSWAP16 BUILT_IN_BSWAP32
> -         BUILT_IN_BSWAP64 BUILT_IN_BSWAP128)
> -(define_operator_list BITREVERSE BUILT_IN_BITREVERSE8 BUILT_IN_BITREVERSE16
> -         BUILT_IN_BITREVERSE32 BUILT_IN_BITREVERSE64 BUILT_IN_BITREVERSE128)
>  
>  #include "cfn-operators.pd"
>  
> @@ -10319,8 +10315,7 @@ (define_operator_list SYNC_FETCH_AND_AND
>  
>  /* popcount(bswap(x)) is popcount(x).  */
>  (for popcount (POPCOUNT)
> -  (for bswap (BUILT_IN_BSWAP16 BUILT_IN_BSWAP32
> -           BUILT_IN_BSWAP64 BUILT_IN_BSWAP128)
> +  (for bswap (BSWAP BITREVERSE)
>      (simplify
>        (popcount (convert?@0 (bswap:s@1 @2)))
>        (if (INTEGRAL_TYPE_P (TREE_TYPE (@0))
> --- gcc/tree-ssa-phiopt.cc.jj 2026-06-04 08:24:37.641028175 +0200
> +++ gcc/tree-ssa-phiopt.cc    2026-06-04 08:31:41.599391815 +0200
> @@ -813,15 +813,8 @@ empty_bb_or_one_feeding_into_p (basic_bl
>       {
>       default:
>         return false;
> -     case CFN_BUILT_IN_BSWAP16:
> -     case CFN_BUILT_IN_BSWAP32:
> -     case CFN_BUILT_IN_BSWAP64:
> -     case CFN_BUILT_IN_BSWAP128:
> -     case CFN_BUILT_IN_BITREVERSE8:
> -     case CFN_BUILT_IN_BITREVERSE16:
> -     case CFN_BUILT_IN_BITREVERSE32:
> -     case CFN_BUILT_IN_BITREVERSE64:
> -     case CFN_BUILT_IN_BITREVERSE128:
> +     CASE_CFN_BSWAP:
> +     CASE_CFN_BITREVERSE:
>       CASE_CFN_FFS:
>       CASE_CFN_PARITY:
>       CASE_CFN_POPCOUNT:
> @@ -2577,15 +2570,8 @@ cond_removal_in_builtin_zero_pattern (ba
>    bool any_val = false;
>    switch (cfn)
>      {
> -    case CFN_BUILT_IN_BSWAP16:
> -    case CFN_BUILT_IN_BSWAP32:
> -    case CFN_BUILT_IN_BSWAP64:
> -    case CFN_BUILT_IN_BSWAP128:
> -    case CFN_BUILT_IN_BITREVERSE8:
> -    case CFN_BUILT_IN_BITREVERSE16:
> -    case CFN_BUILT_IN_BITREVERSE32:
> -    case CFN_BUILT_IN_BITREVERSE64:
> -    case CFN_BUILT_IN_BITREVERSE128:
> +    CASE_CFN_BSWAP:
> +    CASE_CFN_BITREVERSE:
>      CASE_CFN_FFS:
>      CASE_CFN_PARITY:
>      CASE_CFN_POPCOUNT:
> --- gcc/fold-const-call.cc.jj 2026-06-04 08:24:31.114114947 +0200
> +++ gcc/fold-const-call.cc    2026-06-04 08:31:41.600632646 +0200
> @@ -1094,19 +1094,12 @@ fold_const_call_ss (wide_int *result, co
>        *result = wi::shwi (wi::parity (arg), precision);
>        return true;
>  
> -    case CFN_BUILT_IN_BSWAP16:
> -    case CFN_BUILT_IN_BSWAP32:
> -    case CFN_BUILT_IN_BSWAP64:
> -    case CFN_BUILT_IN_BSWAP128:
> +    CASE_CFN_BSWAP:
>        *result = wi::bswap (wide_int::from (arg, precision,
>                                          TYPE_SIGN (arg_type)));
>        return true;
>  
> -    case CFN_BUILT_IN_BITREVERSE8:
> -    case CFN_BUILT_IN_BITREVERSE16:
> -    case CFN_BUILT_IN_BITREVERSE32:
> -    case CFN_BUILT_IN_BITREVERSE64:
> -    case CFN_BUILT_IN_BITREVERSE128:
> +    CASE_CFN_BITREVERSE:
>        *result = wi::bitreverse (wide_int::from (arg, precision,
>                                               TYPE_SIGN (arg_type)));
>        return true;
> --- gcc/fold-const.cc.jj      2026-06-04 08:24:31.117114908 +0200
> +++ gcc/fold-const.cc 2026-06-04 08:31:41.601387045 +0200
> @@ -14627,15 +14627,8 @@ tree_call_nonnegative_p (tree type, comb
>      CASE_CFN_PARITY:
>      CASE_CFN_POPCOUNT:
>      CASE_CFN_CLRSB:
> -    case CFN_BUILT_IN_BSWAP16:
> -    case CFN_BUILT_IN_BSWAP32:
> -    case CFN_BUILT_IN_BSWAP64:
> -    case CFN_BUILT_IN_BSWAP128:
> -    case CFN_BUILT_IN_BITREVERSE8:
> -    case CFN_BUILT_IN_BITREVERSE16:
> -    case CFN_BUILT_IN_BITREVERSE32:
> -    case CFN_BUILT_IN_BITREVERSE64:
> -    case CFN_BUILT_IN_BITREVERSE128:
> +    CASE_CFN_BSWAP:
> +    CASE_CFN_BITREVERSE:
>        /* Always true.  */
>        return true;
>  
> --- gcc/gimple-lower-bitint.cc.jj     2026-06-04 08:24:31.122114841 +0200
> +++ gcc/gimple-lower-bitint.cc        2026-06-04 08:31:41.602444764 +0200
> @@ -474,6 +474,7 @@ struct bitint_large_huge
>    void lower_cplxpart_stmt (tree, gimple *);
>    void lower_complexexpr_stmt (gimple *);
>    void lower_bit_query (gimple *);
> +  void lower_bswap_bitreverse (gimple *);
>    void lower_call (tree, gimple *);
>    void lower_asm (gimple *);
>    void lower_stmt (gimple *);
> @@ -6106,6 +6107,181 @@ bitint_large_huge::lower_bit_query (gimp
>      }
>  }
>  
> +/* Lower a .{BSWAP,BITREVERSE} call with one large/huge _BitInt argument.  */
> +
> +void
> +bitint_large_huge::lower_bswap_bitreverse (gimple *stmt)
> +{
> +  tree arg = gimple_call_arg (stmt, 0);
> +  tree lhs = gimple_call_lhs (stmt);
> +  gimple *g;
> +
> +  if (!lhs)
> +    {
> +      gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
> +      gsi_remove (&gsi, true);
> +      return;
> +    }
> +  tree type = TREE_TYPE (arg);
> +  gcc_assert (BITINT_TYPE_P (type));
> +  bitint_prec_kind kind = bitint_precision_kind (type);
> +  gcc_assert (kind >= bitint_prec_large);
> +  int part = var_to_partition (m_map, lhs);
> +  gcc_assert (m_vars[part] != NULL_TREE);
> +  tree obj = m_vars[part];
> +  enum internal_fn ifn = gimple_call_internal_fn (stmt);
> +  enum built_in_function bcode = END_BUILTINS;
> +  switch (limb_prec)
> +    {
> +    case 16:
> +      bcode = ifn == IFN_BSWAP ? BUILT_IN_BSWAP16 : BUILT_IN_BITREVERSE16;
> +      break;
> +    case 32:
> +      bcode = ifn == IFN_BSWAP ? BUILT_IN_BSWAP32 : BUILT_IN_BITREVERSE32;
> +      break;
> +    case 64:
> +      bcode = ifn == IFN_BSWAP ? BUILT_IN_BSWAP64 : BUILT_IN_BITREVERSE64;
> +      break;
> +    case 128:
> +      bcode = ifn == IFN_BSWAP ? BUILT_IN_BSWAP128 : BUILT_IN_BITREVERSE128;
> +      break;
> +    default:
> +      gcc_unreachable ();
> +    }
> +  tree fndecl = builtin_decl_explicit (bcode);
> +  unsigned prec = TYPE_PRECISION (type);
> +  tree p = build_int_cst (sizetype,
> +                       prec / limb_prec - (prec % limb_prec == 0));
> +  /* For IFN .BSWAP or .BITREVERSE and
> +     FN corresponding __builtin_bswapN or __builtin_bitreverseN where N
> +     is limb_prec, lower
> +       dst = IFN (src);
> +     as
> +       size_t p = prec / limb_prec - (prec % limb_prec == 0);
> +       if constexpr ((prec % limb_prec) == 0)
> +      {
> +        for (idx = 0; idx <= p; ++idx)
> +          dst[p - idx] = FN (src[idx]);
> +      }
> +       else
> +      {
> +        unsigned n1 = prec % limb_prec;
> +        unsigned n2 = limb_prec - n1;
> +        dst[p] = FN (src[0]) >> n2;
> +        for (idx = p - 1; (ssize_t) idx >= 0; --idx)
> +          dst[idx] = FN ((src[p - idx] << n2) | (src[p - idx - 1] >> n1));
> +      }  */
> +  if (prec % limb_prec == 0)
> +    {
> +      tree idx_next;
> +      tree idx = create_loop (size_zero_node, &idx_next);
> +      tree pmidx = make_ssa_name (sizetype);
> +      g = gimple_build_assign (pmidx, MINUS_EXPR, p, idx);
> +      insert_before (g);
> +      m_data_cnt = 0;
> +      tree t = handle_operand (arg, idx);
> +      m_first = false;
> +      g = gimple_build_call (fndecl, 1, t);
> +      t = make_ssa_name (m_limb_type);
> +      gimple_call_set_lhs (g, t);
> +      insert_before (g);
> +      tree l = limb_access (TREE_TYPE (lhs), obj, pmidx, true);
> +      g = gimple_build_assign (l, t);
> +      insert_before (g);
> +      g = gimple_build_assign (idx_next, PLUS_EXPR, idx, size_one_node);
> +      insert_before (g);
> +      g = gimple_build_cond (LE_EXPR, idx_next, p, NULL_TREE, NULL_TREE);
> +      insert_before (g);
> +    }
> +  else
> +    {
> +      tree n1 = build_int_cst (unsigned_type_node, prec % limb_prec);
> +      tree n2 = build_int_cst (unsigned_type_node,
> +                            limb_prec - (prec % limb_prec));
> +      m_data_cnt = 0;
> +      tree t = handle_operand (arg, bitint_big_endian ? p : size_zero_node);
> +      m_first = false;
> +      /* Nothing is needed to bswap 8 bits or bitreverse 1 bit, so just
> +      mask off higher bits in that case.  */
> +      if ((prec % limb_prec) != (ifn == IFN_BSWAP ? 8 : 1))
> +     {
> +       g = gimple_build_call (fndecl, 1, t);
> +       t = make_ssa_name (m_limb_type);
> +       gimple_call_set_lhs (g, t);
> +       insert_before (g);
> +       g = gimple_build_assign (make_ssa_name (m_limb_type), RSHIFT_EXPR,
> +                                t, n2);
> +     }
> +      else
> +     g = gimple_build_assign (make_ssa_name (m_limb_type), BIT_AND_EXPR,
> +                              t, build_int_cst (m_limb_type,
> +                                                ifn == IFN_BSWAP
> +                                                ? 0xff : 1));
> +      insert_before (g);
> +      t = gimple_assign_lhs (g);
> +      tree l = limb_access (TREE_TYPE (lhs), obj,
> +                         bitint_big_endian ? size_zero_node : p, true);
> +      g = gimple_build_assign (l, t);
> +      insert_before (g);
> +      tree pm1 = build_int_cst (sizetype, prec / limb_prec - 1);
> +      tree idx_next;
> +      tree idx = create_loop (pm1, &idx_next);
> +      tree pmidx = make_ssa_name (sizetype);
> +      g = gimple_build_assign (pmidx, MINUS_EXPR, p, idx);
> +      insert_before (g);
> +      m_data_cnt = 0;
> +      t = handle_operand (arg, bitint_big_endian ? idx : pmidx);
> +      m_data_cnt = 0;
> +      g = gimple_build_assign (make_ssa_name (m_limb_type), LSHIFT_EXPR,
> +                            t, n2);
> +      insert_before (g);
> +      t = gimple_assign_lhs (g);
> +      tree t2 = make_ssa_name (sizetype);
> +      if (bitint_big_endian)
> +     g = gimple_build_assign (t2, PLUS_EXPR, idx, size_one_node);
> +      else
> +     g = gimple_build_assign (t2, PLUS_EXPR, pmidx, size_int (-1));
> +      insert_before (g);
> +      t2 = handle_operand (arg, t2);
> +      g = gimple_build_assign (make_ssa_name (m_limb_type), RSHIFT_EXPR,
> +                            t2, n1);
> +      insert_before (g);
> +      t2 = gimple_assign_lhs (g);
> +      g = gimple_build_assign (make_ssa_name (m_limb_type), BIT_IOR_EXPR,
> +                            t, t2);
> +      insert_before (g);
> +      t = gimple_assign_lhs (g);
> +      g = gimple_build_call (fndecl, 1, t);
> +      t = make_ssa_name (m_limb_type);
> +      gimple_call_set_lhs (g, t);
> +      insert_before (g);
> +      l = limb_access (TREE_TYPE (lhs), obj,
> +                    bitint_big_endian ? pmidx : idx, true);
> +      g = gimple_build_assign (l, t);
> +      insert_before (g);
> +      g = gimple_build_assign (idx_next, PLUS_EXPR, idx, size_int (-1));
> +      insert_before (g);
> +      g = gimple_build_cond (NE_EXPR, idx, size_zero_node, NULL_TREE,
> +                          NULL_TREE);
> +      insert_before (g);
> +    }
> +  gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
> +  if (bitint_extended == bitint_ext_full
> +      && abi_limb_prec > limb_prec
> +      && (CEIL (prec, abi_limb_prec) * abi_limb_prec
> +       > CEIL (prec, limb_prec) * limb_prec))
> +    {
> +      m_gsi = gsi;
> +      tree p2 = build_int_cst (sizetype,
> +                            CEIL (prec, abi_limb_prec)
> +                            * abi_limb_prec / limb_prec - 1);
> +      tree l = limb_access (TREE_TYPE (lhs), obj, p2, true);
> +      g = gimple_build_assign (l, build_zero_cst (m_limb_type));
> +      insert_before (g);
> +    }
> +  gsi_remove (&gsi, true);
> +}
> +
>  /* Lower a call statement with one or more large/huge _BitInt
>     arguments or large/huge _BitInt return value.  */
>  
> @@ -6135,6 +6311,10 @@ bitint_large_huge::lower_call (tree obj,
>        case IFN_POPCOUNT:
>       lower_bit_query (stmt);
>       return;
> +      case IFN_BSWAP:
> +      case IFN_BITREVERSE:
> +     lower_bswap_bitreverse (stmt);
> +     return;
>        default:
>       break;
>        }
> @@ -6815,8 +6995,7 @@ build_bitint_stmt_ssa_conflicts (gimple
>           }
>       }
>      }
> -  else if (bitint_big_endian
> -        && is_gimple_call (stmt)
> +  else if (is_gimple_call (stmt)
>          && gimple_call_internal_p (stmt))
>      switch (gimple_call_internal_fn (stmt))
>        {
> @@ -6826,6 +7005,15 @@ build_bitint_stmt_ssa_conflicts (gimple
>        case IFN_UBSAN_CHECK_SUB:
>        case IFN_MUL_OVERFLOW:
>        case IFN_UBSAN_CHECK_MUL:
> +     if (bitint_big_endian)
> +       {
> +         lhs = gimple_call_lhs (stmt);
> +         if (lhs)
> +           muldiv_p = true;
> +       }
> +     break;
> +      case IFN_BSWAP:
> +      case IFN_BITREVERSE:
>       lhs = gimple_call_lhs (stmt);
>       if (lhs)
>         muldiv_p = true;
> --- gcc/c-family/c-common.h.jj        2026-06-04 08:24:31.070115532 +0200
> +++ gcc/c-family/c-common.h   2026-06-04 08:31:41.603068847 +0200
> @@ -111,7 +111,8 @@ enum rid
>    RID_TYPES_COMPATIBLE_P,      RID_BUILTIN_COMPLEX,     RID_BUILTIN_SHUFFLE,
>    RID_BUILTIN_SHUFFLEVECTOR,   RID_BUILTIN_CONVERTVECTOR,  
> RID_BUILTIN_TGMATH,
>    RID_BUILTIN_HAS_ATTRIBUTE,   RID_BUILTIN_ASSOC_BARRIER,  RID_BUILTIN_STDC,
> -  RID_BUILTIN_COUNTED_BY_REF,
> +  RID_BUILTIN_COUNTED_BY_REF,  RID_BUILTIN_BSWAPG,
> +  RID_BUILTIN_BITREVERSEG,
>    RID_DFLOAT32, RID_DFLOAT64, RID_DFLOAT128, RID_DFLOAT64X,
>  
>    /* TS 18661-3 keywords, in the same sequence as the TI_* values.  */
> --- gcc/c-family/c-common.cc.jj       2026-06-04 08:24:31.067115572 +0200
> +++ gcc/c-family/c-common.cc  2026-06-04 08:31:41.603541813 +0200
> @@ -433,7 +433,9 @@ const struct c_common_resword c_common_r
>    { "__auto_type",   RID_AUTO_TYPE,  D_CONLY },
>    { "__builtin_addressof", RID_ADDRESSOF, D_CXXONLY },
>    { "__builtin_assoc_barrier", RID_BUILTIN_ASSOC_BARRIER, 0 },
> +  { "__builtin_bitreverseg", RID_BUILTIN_BITREVERSEG, 0 },
>    { "__builtin_bit_cast", RID_BUILTIN_BIT_CAST, D_CXXONLY },
> +  { "__builtin_bswapg", RID_BUILTIN_BSWAPG, 0 },
>    { "__builtin_call_with_static_chain",
>      RID_BUILTIN_CALL_WITH_STATIC_CHAIN, D_CONLY },
>    { "__builtin_choose_expr", RID_CHOOSE_EXPR, D_CONLY },
> --- gcc/c/c-parser.cc.jj      2026-06-04 08:24:37.587028893 +0200
> +++ gcc/c/c-parser.cc 2026-06-04 08:53:43.390909824 +0200
> @@ -13534,6 +13534,76 @@ c_parser_postfix_expression (c_parser *p
>                                      expr.value);
>           break;
>         }
> +     case RID_BUILTIN_BSWAPG:
> +     case RID_BUILTIN_BITREVERSEG:
> +       {
> +         vec<c_expr_t, va_gc> *cexpr_list;
> +         location_t close_paren_loc;
> +         internal_fn ifn
> +           = (c_parser_peek_token (parser)->keyword == RID_BUILTIN_BSWAPG
> +              ? IFN_BSWAP : IFN_BITREVERSE);
> +         const char *name
> +           = (ifn == IFN_BSWAP ? "__builtin_bswapg"
> +              : "__builtin_bitreverseg");
> +
> +         c_parser_consume_token (parser);
> +         if (!c_parser_get_builtin_args (parser, name, &cexpr_list, false,
> +                                         &close_paren_loc))
> +           {
> +             expr.set_error ();
> +             break;
> +           }
> +
> +         if (vec_safe_length (cexpr_list) != 1)
> +           {
> +             error_at (loc, "wrong number of arguments to %qs", name);
> +             expr.set_error ();
> +             break;
> +           }
> +
> +         c_expr_t *arg_p = &(*cexpr_list)[0];
> +         *arg_p = convert_lvalue_to_rvalue (loc, *arg_p, true, true);
> +         tree arg = arg_p->value;
> +         tree type = TYPE_MAIN_VARIANT (TREE_TYPE (arg));
> +         if (!INTEGRAL_TYPE_P (type))
> +           {
> +             error_at (loc, "%qs operand not an integral type", name);
> +             expr.set_error ();
> +             break;
> +           }
> +         if (TREE_CODE (type) == ENUMERAL_TYPE)
> +           {
> +             error_at (loc, "argument %u in call to function "
> +                       "%qs has enumerated type", 1, name);
> +             expr.set_error ();
> +             break;
> +           }
> +         if (TREE_CODE (type) == BOOLEAN_TYPE)
> +           {
> +             error_at (loc, "argument %u in call to function "
> +                       "%qs has boolean type", 1, name);
> +             expr.set_error ();
> +             break;
> +           }
> +         if (!TYPE_UNSIGNED (type))
> +           {
> +             error_at (loc, "argument 1 in call to function "
> +                       "%qs has signed type", name);
> +             expr.set_error ();
> +             break;
> +           }
> +         if (ifn == IFN_BSWAP && (TYPE_PRECISION (type) % 8) != 0)
> +           {
> +             error_at (loc, "precision %d of argument 1 to function "
> +                       "%qs is not a multiple of 8",
> +                       TYPE_PRECISION (type), name);
> +             expr.set_error ();
> +             break;
> +           }
> +         expr.value = fold_build_builtin_bswapg_bitreverseg (loc, ifn, arg);
> +         set_c_expr_source_range (&expr, loc, close_paren_loc);
> +         break;
> +       }
>       case RID_AT_SELECTOR:
>         {
>           gcc_assert (c_dialect_objc ());
> --- gcc/cp/parser.cc.jj       2026-06-04 08:24:37.610028587 +0200
> +++ gcc/cp/parser.cc  2026-06-04 08:34:05.297481411 +0200
> @@ -8626,6 +8626,8 @@ cp_parser_postfix_expression (cp_parser
>      case RID_BUILTIN_ASSOC_BARRIER:
>      case RID_BUILTIN_OPERATOR_NEW:
>      case RID_BUILTIN_OPERATOR_DELETE:
> +    case RID_BUILTIN_BSWAPG:
> +    case RID_BUILTIN_BITREVERSEG:
>        {
>       vec<tree, va_gc> *vec;
>  
> @@ -8745,6 +8747,18 @@ cp_parser_postfix_expression (cp_parser
>             }
>           break;
>  
> +       case RID_BUILTIN_BSWAPG:
> +         postfix_expression
> +           = build_x_bswapg_bitreverseg (loc, IFN_BSWAP, vec,
> +                                         tf_warning_or_error);
> +         break;
> +
> +       case RID_BUILTIN_BITREVERSEG:
> +         postfix_expression
> +           = build_x_bswapg_bitreverseg (loc, IFN_BITREVERSE, vec,
> +                                         tf_warning_or_error);
> +         break;
> +
>         default:
>           gcc_unreachable ();
>         }
> --- gcc/cp/typeck.cc.jj       2026-06-04 08:24:31.102115107 +0200
> +++ gcc/cp/typeck.cc  2026-06-04 08:42:47.069566467 +0200
> @@ -7111,6 +7111,71 @@ build_x_shufflevector (location_t loc, v
>      }
>    return exp;
>  }
> +
> +/* Build __builtin_bswapg (ARG) or __builtin_bitreverseg (ARG).  */
> +tree
> +build_x_bswapg_bitreverseg (location_t loc, internal_fn ifn,
> +                         vec<tree, va_gc> *args, tsubst_flags_t complain)
> +{
> +  const char *name
> +    = ifn == IFN_BSWAP ? "__builtin_bswapg" : "__builtin_bitreverseg";
> +  if (args->length () != 1)
> +    {
> +      if (complain & tf_error)
> +     error_at (loc, "wrong number of arguments to %qs", name);
> +      return error_mark_node;
> +    }
> +  tree arg = (*args)[0];
> +  if (type_dependent_expression_p (arg))
> +    {
> +      tree exp = build_min_nt_call_vec (NULL, args);
> +      CALL_EXPR_IFN (exp) = ifn;
> +      return exp;
> +    }
> +  tree type = TYPE_MAIN_VARIANT (TREE_TYPE (arg));
> +  if (!INTEGRAL_TYPE_P (type))
> +    {
> +      if (complain & tf_error)
> +     error_at (loc, "%qs operand not an integral type", name);
> +      return error_mark_node;
> +    }
> +  if (TREE_CODE (type) == ENUMERAL_TYPE)
> +    {
> +      if (complain & tf_error)
> +     error_at (loc, "argument %u in call to function "
> +                    "%qs has enumerated type", 1, name);
> +      return error_mark_node;
> +    }
> +  if (TREE_CODE (type) == BOOLEAN_TYPE)
> +    {
> +      if (complain & tf_error)
> +     error_at (loc, "argument %u in call to function "
> +                    "%qs has boolean type", 1, name);
> +      return error_mark_node;
> +    }
> +  if (!TYPE_UNSIGNED (type))
> +    {
> +      if (complain & tf_error)
> +     error_at (loc, "argument 1 in call to function "
> +                    "%qs has signed type", name);
> +      return error_mark_node;
> +    }
> +  if (ifn == IFN_BSWAP && (TYPE_PRECISION (type) % 8) != 0)
> +    {
> +      if (complain & tf_error)
> +     error_at (loc, "precision %d of argument 1 to function "
> +                    "%qs is not a multiple of 8",
> +               TYPE_PRECISION (type), name);
> +      return error_mark_node;
> +    }
> +  tree exp = build_call_expr_internal_loc (loc, ifn, type, 1, arg);
> +  if (processing_template_decl)
> +    {
> +      exp = build_min_non_dep_call_vec (exp, NULL, args);
> +      CALL_EXPR_IFN (exp) = ifn;
> +    }
> +  return exp;
> +}
>  
>  /* Return a tree for the sum or difference (RESULTCODE says which)
>     of pointer PTROP and integer INTOP.  */
> --- gcc/cp/cp-tree.h.jj       2026-06-04 08:24:37.606028640 +0200
> +++ gcc/cp/cp-tree.h  2026-06-04 08:31:41.612343919 +0200
> @@ -9050,6 +9050,9 @@ extern tree build_x_vec_perm_expr
>  extern tree build_x_shufflevector               (location_t,
>                                                vec<tree, va_gc> *,
>                                                tsubst_flags_t);
> +extern tree build_x_bswapg_bitreverseg               (location_t, 
> internal_fn,
> +                                              vec<tree, va_gc> *,
> +                                              tsubst_flags_t);
>  #define cxx_sizeof(T)  cxx_sizeof_or_alignof_type (input_location, T, 
> SIZEOF_EXPR, false, true)
>  extern tree build_simple_component_ref               (tree, tree);
>  extern tree build_ptrmemfunc_access_expr     (tree, tree);
> --- gcc/cp/pt.cc.jj   2026-06-04 08:24:37.613028547 +0200
> +++ gcc/cp/pt.cc      2026-06-04 08:31:41.613787189 +0200
> @@ -22517,6 +22517,17 @@ tsubst_expr (tree t, tree args, tsubst_f
>               break;
>             }
>  
> +         case IFN_BSWAP:
> +         case IFN_BITREVERSE:
> +           {
> +             ret = build_x_bswapg_bitreverseg (input_location,
> +                                               CALL_EXPR_IFN (t), call_args,
> +                                               complain);
> +             if (ret != error_mark_node)
> +               RETURN (ret);
> +             break;
> +           }
> +
>           case IFN_ASSUME:
>             gcc_assert (nargs == 1);
>             if (vec_safe_length (call_args) != 1)
> --- gcc/cp/constexpr.cc.jj    2026-06-04 08:24:31.073115492 +0200
> +++ gcc/cp/constexpr.cc       2026-06-04 08:34:56.285803540 +0200
> @@ -3245,6 +3245,32 @@ cxx_eval_internal_function (const conste
>      case IFN_DEFERRED_INIT:
>        return build_clobber (TREE_TYPE (t), CLOBBER_OBJECT_BEGIN);
>  
> +    case IFN_BSWAP:
> +    case IFN_BITREVERSE:
> +      {
> +     tree arg = cxx_eval_constant_expression (ctx, CALL_EXPR_ARG (t, 0),
> +                                              vc_prvalue, non_constant_p,
> +                                              overflow_p, jump_target);
> +     if (*jump_target)
> +       return NULL_TREE;
> +     if (*non_constant_p)
> +       return t;
> +     location_t loc = cp_expr_loc_or_input_loc (t);
> +     if (TREE_CODE (arg) != INTEGER_CST
> +         || !INTEGRAL_TYPE_P (TREE_TYPE (arg))
> +         || !TYPE_UNSIGNED (TREE_TYPE (arg))
> +         || (CALL_EXPR_IFN (t) == IFN_BSWAP
> +             && (TYPE_PRECISION (TREE_TYPE (arg)) % 8) != 0))
> +       {
> +         if (!ctx->quiet)
> +           error_at (loc, "call to internal function %qE", t);
> +         *non_constant_p = true;
> +         return t;
> +       }
> +     return fold_build_builtin_bswapg_bitreverseg (loc, CALL_EXPR_IFN (t),
> +                                                   arg);
> +      }
> +
>      case IFN_VEC_CONVERT:
>        {
>       tree arg = cxx_eval_constant_expression (ctx, CALL_EXPR_ARG (t, 0),
> @@ -12026,6 +12052,8 @@ potential_constant_expression_1 (tree t,
>               case IFN_MUL_OVERFLOW:
>               case IFN_LAUNDER:
>               case IFN_VEC_CONVERT:
> +             case IFN_BSWAP:
> +             case IFN_BITREVERSE:
>                 bail = false;
>                 break;
>  
> --- gcc/cp/cp-gimplify.cc.jj  2026-06-04 08:24:31.085115333 +0200
> +++ gcc/cp/cp-gimplify.cc     2026-06-04 08:31:41.616308733 +0200
> @@ -44,6 +44,7 @@ along with GCC; see the file COPYING3.
>  #include "opts.h"
>  #include "gcc-urlifier.h"
>  #include "contracts.h" // build_contract_check ()
> +#include "builtins.h"
>  
>  /* Keep track of forward references to immediate-escalating functions in
>     case they become consteval.  This vector contains ADDR_EXPRs and
> @@ -880,7 +881,29 @@ cp_gimplify_expr (tree *expr_p, gimple_s
>             = build1 (NOP_EXPR, fnptrtype, CALL_EXPR_FN (*expr_p));
>       }
>        if (!CALL_EXPR_FN (*expr_p))
> -     /* Internal function call.  */;
> +     /* Internal function call.  */
> +     switch (CALL_EXPR_IFN (*expr_p))
> +       {
> +       case IFN_BSWAP:
> +       case IFN_BITREVERSE:
> +         if (ret == GS_OK)
> +           {
> +             location_t loc = EXPR_LOCATION (*expr_p);
> +             internal_fn ifn = CALL_EXPR_IFN (*expr_p);
> +             tree arg = CALL_EXPR_ARG (*expr_p, 0);
> +             tree r = fold_build_builtin_bswapg_bitreverseg (loc, ifn,
> +                                                             arg);
> +             if (TREE_CODE (r) == CALL_EXPR
> +                 && !CALL_EXPR_FN (r)
> +                 && CALL_EXPR_IFN (r) == ifn)
> +               break;
> +             *expr_p = r;
> +             return ret;
> +           }
> +         break;
> +       default:
> +         break;
> +       }
>        else if (CALL_EXPR_REVERSE_ARGS (*expr_p))
>       {
>         /* This is a call to a (compound) assignment operator that used
> --- gcc/testsuite/c-c++-common/builtin-bswapg-1.c.jj  2026-06-04 
> 08:31:41.616644255 +0200
> +++ gcc/testsuite/c-c++-common/builtin-bswapg-1.c     2026-06-04 
> 08:31:41.616644255 +0200
> @@ -0,0 +1,153 @@
> +/* Test __builtin_bswapg.  */
> +/* { dg-do run { target { c || c++11 } } } */
> +/* { dg-options "-O2" } */
> +
> +#if __CHAR_BIT__ == 8
> +#if __SIZEOF_INT__ == 4
> +static_assert (__builtin_bswapg (0x12345678U) == 0x78563412U, "");
> +#endif
> +#if __SIZEOF_LONG_LONG__ == 8
> +static_assert (__builtin_bswapg (0x123456789abcdef0ULL) == 
> 0xf0debc9a78563412ULL, "");
> +#endif
> +static_assert (__builtin_bswapg ((unsigned char) 0x23) == (unsigned char) 
> 0x23, "");
> +#if __SIZEOF_SHORT__ == 2
> +static_assert (__builtin_bswapg ((unsigned short) 0x2345) == (unsigned 
> short) 0x4523, "");
> +#endif
> +#if __SIZEOF_INT128__ == 16
> +static_assert (__builtin_bswapg ((((unsigned __int128) 
> 0x123456789abcdef0ULL) << 64)
> +                              | 0x23456789abcdef01ULL)
> +                              == ((((unsigned __int128) 
> 0x01efcdab89674523ULL) << 64)
> +                                  | 0xf0debc9a78563412ULL), "");
> +#endif
> +#endif
> +#if __BITINT_MAXWIDTH__ >= 856
> +static_assert (__builtin_bswapg (0xabcdefuwb) == 0xefcdabuwb, "");
> +static_assert (__builtin_bswapg (0xabcdef8081uwb) == 0x8180efcdabuwb, "");
> +static_assert (__builtin_bswapg ((unsigned _BitInt(136)) 
> 0x66b52574b5fd190b15a1b99858c27d0ac2uwb)
> +            == 0xc20a7dc25898b9a1150b19fdb57425b566uwb, "");
> +static_assert (__builtin_bswapg ((unsigned _BitInt(832)) 
> 0x021256fc7a59ee4dab277edcadfdbfd45c0690f99249cf9e31ad0b16f91a0efb2d64f8a7bde6f4680d7244ba70038ecc091fc59c68943a994146b03a60be368d222e34e0142948229b8ddc0b906bd79a8a9c36f230708b71b63bac17f9e2a41c10d9fc240244469duwb)
> +            == 
> 0x9d46440224fcd9101ca4e2f917ac3bb6718b7030f2369c8a9ad76b900bdc8d9b22482914e0342e228d36be603ab04641993a94689cc51f09cc8e0370ba44720d68f4e6bda7f8642dfb0e1af9160bad319ecf4992f990065cd4bffdaddc7e27ab4dee597afc561202uwb,
>  "");
> +static_assert (__builtin_bswapg ((unsigned _BitInt(840)) 
> 0x4c23edce0b5ffd538da2112c333d17f100a0db44f7c9cfb097538e995f3a5bab5d487969a776bc3518cd614b0a783d0b18184f10e11ec078714f11d0896c7be6b5f54f5c6b0c9184d9f3cfe46b0cef84243e94055d547dcea38f9f2cfb1a13b00f620d7b6e9eff4891uwb)
> +            == 
> 0x9148ff9e6e7b0d620fb0131afb2c9f8fa3ce7d545d05943e2484ef0c6be4cff3d984910c6b5c4ff5b5e67b6c89d0114f7178c01ee1104f18180b3d780a4b61cd1835bc76a76979485dab5b3a5f998e5397b0cfc9f744dba000f1173d332c11a28d53fd5f0bceed234cuwb,
>  "");
> +static_assert (__builtin_bswapg ((unsigned _BitInt(856)) 
> 0x41c39e2f987be9c81688ecc08a4ded319e4010952ecb6e4ac738a6924d81668f4404bedd7fa7a5952f9156bade43eb7d83fb12b2c780fc8eb9a22006238695678a53440afbe99f2a7af5e45938cfd6bccbe86e92696a20220c41282fc7be965211db5c0cc4fb373ff11b98uwb)
> +            == 
> 0x981bf13f37fbc40c5cdb115296bec72f28410c22206a69926ee8cbbcd6cf3859e4f57a2a9fe9fb0a44538a679586230620a2b98efc80c7b212fb837deb43deba56912f95a5a77fddbe04448f66814d92a638c74a6ecb2e9510409e31ed4d8ac0ec8816c8e97b982f9ec341uwb,
>  "");
> +#endif
> +
> +#if __CHAR_BIT__ == 8
> +#if __SIZEOF_INT__ == 4
> +[[gnu::noipa]] unsigned
> +bswap32 (unsigned x)
> +{
> +  return __builtin_bswapg (x);
> +}
> +#endif
> +#if __SIZEOF_LONG_LONG__ == 8
> +[[gnu::noipa]] unsigned long long
> +bswap64 (unsigned long long x)
> +{
> +  return __builtin_bswapg (x);
> +}
> +#endif
> +[[gnu::noipa]] unsigned char
> +bswap8 (unsigned char x)
> +{
> +  return __builtin_bswapg (x);
> +}
> +#if __SIZEOF_SHORT__ == 2
> +[[gnu::noipa]] unsigned short
> +bswap16 (unsigned short x)
> +{
> +  return __builtin_bswapg (x);
> +}
> +#endif
> +#if __SIZEOF_INT128__ == 16
> +[[gnu::noipa]] unsigned __int128
> +bswap128 (unsigned __int128 x)
> +{
> +  return __builtin_bswapg (x);
> +}
> +#endif
> +#endif
> +#if __BITINT_MAXWIDTH__ >= 856
> +[[gnu::noipa]] unsigned _BitInt(24)
> +bswap24 (unsigned _BitInt(24) x)
> +{
> +  return __builtin_bswapg (x);
> +}
> +
> +[[gnu::noipa]] unsigned _BitInt(40)
> +bswap40 (unsigned _BitInt(40) x)
> +{
> +  return __builtin_bswapg (x);
> +}
> +
> +[[gnu::noipa]] unsigned _BitInt(136)
> +bswap136 (unsigned _BitInt(136) x)
> +{
> +  return __builtin_bswapg (x);
> +}
> +
> +[[gnu::noipa]] unsigned _BitInt(832)
> +bswap832 (unsigned _BitInt(832) x)
> +{
> +  return __builtin_bswapg (x);
> +}
> +
> +[[gnu::noipa]] unsigned _BitInt(840)
> +bswap840 (unsigned _BitInt(840) x)
> +{
> +  return __builtin_bswapg (x);
> +}
> +
> +[[gnu::noipa]] unsigned _BitInt(856)
> +bswap856 (unsigned _BitInt(856) x)
> +{
> +  return __builtin_bswapg (x);
> +}
> +#endif
> +
> +int
> +main ()
> +{
> +#if __CHAR_BIT__ == 8
> +#if __SIZEOF_INT__ == 4
> +  if (bswap32 (0x12345678U) != 0x78563412U)
> +    __builtin_abort ();
> +#endif
> +#if __SIZEOF_LONG_LONG__ == 8
> +  if (bswap64 (0x123456789abcdef0ULL) != 0xf0debc9a78563412ULL)
> +    __builtin_abort ();
> +#endif
> +  if (bswap8 ((unsigned char) 0x23) != (unsigned char) 0x23)
> +    __builtin_abort ();
> +#if __SIZEOF_SHORT__ == 2
> +  if (bswap16 ((unsigned short) 0x2345) != (unsigned short) 0x4523)
> +    __builtin_abort ();
> +#endif
> +#if __SIZEOF_INT128__ == 16
> +  if (bswap128 ((((unsigned __int128) 0x123456789abcdef0ULL) << 64)
> +             | 0x23456789abcdef01ULL)
> +      != ((((unsigned __int128) 0x01efcdab89674523ULL) << 64)
> +       | 0xf0debc9a78563412ULL))
> +    __builtin_abort ();
> +#endif
> +#endif
> +#if __BITINT_MAXWIDTH__ >= 856
> +  if (bswap24 (0xabcdefuwb) != 0xefcdabuwb)
> +    __builtin_abort ();
> +  if (bswap40 (0xabcdef8081uwb) != 0x8180efcdabuwb)
> +    __builtin_abort ();
> +  if (bswap136 (0x66b52574b5fd190b15a1b99858c27d0ac2uwb)
> +      != 0xc20a7dc25898b9a1150b19fdb57425b566uwb)
> +    __builtin_abort ();
> +  if (bswap832 
> (0x021256fc7a59ee4dab277edcadfdbfd45c0690f99249cf9e31ad0b16f91a0efb2d64f8a7bde6f4680d7244ba70038ecc091fc59c68943a994146b03a60be368d222e34e0142948229b8ddc0b906bd79a8a9c36f230708b71b63bac17f9e2a41c10d9fc240244469duwb)
> +      != 
> 0x9d46440224fcd9101ca4e2f917ac3bb6718b7030f2369c8a9ad76b900bdc8d9b22482914e0342e228d36be603ab04641993a94689cc51f09cc8e0370ba44720d68f4e6bda7f8642dfb0e1af9160bad319ecf4992f990065cd4bffdaddc7e27ab4dee597afc561202uwb)
> +    __builtin_abort ();
> +  if (bswap840 
> (0x4c23edce0b5ffd538da2112c333d17f100a0db44f7c9cfb097538e995f3a5bab5d487969a776bc3518cd614b0a783d0b18184f10e11ec078714f11d0896c7be6b5f54f5c6b0c9184d9f3cfe46b0cef84243e94055d547dcea38f9f2cfb1a13b00f620d7b6e9eff4891uwb)
> +      != 
> 0x9148ff9e6e7b0d620fb0131afb2c9f8fa3ce7d545d05943e2484ef0c6be4cff3d984910c6b5c4ff5b5e67b6c89d0114f7178c01ee1104f18180b3d780a4b61cd1835bc76a76979485dab5b3a5f998e5397b0cfc9f744dba000f1173d332c11a28d53fd5f0bceed234cuwb)
> +    __builtin_abort ();
> +  if (bswap856 
> (0x41c39e2f987be9c81688ecc08a4ded319e4010952ecb6e4ac738a6924d81668f4404bedd7fa7a5952f9156bade43eb7d83fb12b2c780fc8eb9a22006238695678a53440afbe99f2a7af5e45938cfd6bccbe86e92696a20220c41282fc7be965211db5c0cc4fb373ff11b98uwb)
> +      != 
> 0x981bf13f37fbc40c5cdb115296bec72f28410c22206a69926ee8cbbcd6cf3859e4f57a2a9fe9fb0a44538a679586230620a2b98efc80c7b212fb837deb43deba56912f95a5a77fddbe04448f66814d92a638c74a6ecb2e9510409e31ed4d8ac0ec8816c8e97b982f9ec341uwb)
> +    __builtin_abort ();
> +#endif
> +}
> --- gcc/testsuite/c-c++-common/builtin-bswapg-2.c.jj  2026-06-04 
> 08:31:41.616760455 +0200
> +++ gcc/testsuite/c-c++-common/builtin-bswapg-2.c     2026-06-04 
> 08:36:22.357659251 +0200
> @@ -0,0 +1,21 @@
> +/* Test __builtin_bswapg.  */
> +/* { dg-do compile } */
> +/* { dg-options "" } */
> +
> +int
> +main ()
> +{
> +  __builtin_bswapg ();               /* { dg-error "wrong number of 
> arguments to '__builtin_bswapg'" } */
> +  __builtin_bswapg (1U, 1U); /* { dg-error "wrong number of arguments to 
> '__builtin_bswapg'" } */
> +  __builtin_bswapg (1.0);    /* { dg-error "'__builtin_bswapg' operand not 
> an integral type" } */
> +  __builtin_bswapg (1.0f);   /* { dg-error "'__builtin_bswapg' operand not 
> an integral type" } */
> +  __builtin_bswapg (1.0L);   /* { dg-error "'__builtin_bswapg' operand not 
> an integral type" } */
> +  struct S { int a; };
> +  __builtin_bswapg ((struct S) { 42 });      /* { dg-error 
> "'__builtin_bswapg' operand not an integral type" } */
> +  enum E { E0, E1 };
> +  __builtin_bswapg (E1);     /* { dg-error "argument 1 in call to function 
> '__builtin_bswapg' has signed type" "" { target c } } */
> +                             /* { dg-error "argument 1 in call to function 
> '__builtin_bswapg' has enumerated type" "" { target c++ } .-1 } */
> +  __builtin_bswapg (false);  /* { dg-error "argument 1 in call to function 
> '__builtin_bswapg' has boolean type" } */
> +  __builtin_bswapg (1);              /* { dg-error "argument 1 in call to 
> function '__builtin_bswapg' has signed type" } */
> +  __builtin_bswapg ((char) 1);       /* { dg-error "argument 1 in call to 
> function '__builtin_bswapg' has signed type" "" { target { ! unsigned_char } 
> } } */
> +}
> --- gcc/testsuite/c-c++-common/builtin-bswapg-3.c.jj  2026-06-04 
> 08:31:41.616895292 +0200
> +++ gcc/testsuite/c-c++-common/builtin-bswapg-3.c     2026-06-04 
> 08:31:41.616895292 +0200
> @@ -0,0 +1,15 @@
> +/* Test __builtin_bswapg.  */
> +/* { dg-do compile } */
> +/* { dg-options "" } */
> +
> +int
> +main ()
> +{
> +#if __BITINT_MAXWIDTH__ >= 575
> +  __builtin_bswapg (0x0uwb); /* { dg-error "precision 1 of argument 1 to 
> function '__builtin_bswapg' is not a multiple of 8" "" { target bitint575 } } 
> */
> +  __builtin_bswapg (0x3uwb); /* { dg-error "precision 2 of argument 1 to 
> function '__builtin_bswapg' is not a multiple of 8" "" { target bitint575 } } 
> */
> +  __builtin_bswapg (0x34938571398572uwb); /* { dg-error "precision 54 of 
> argument 1 to function '__builtin_bswapg' is not a multiple of 8" "" { target 
> bitint575 } } */
> +  __builtin_bswapg (0x34938571398572abcd9837298dabef9187983uwb); /* { 
> dg-error "precision 146 of argument 1 to function '__builtin_bswapg' is not a 
> multiple of 8" "" { target bitint575 } } */
> +  __builtin_bswapg 
> (0x34938571398572abcd9837298dabef918798329387987abef98792837549857983745983475329847uwb);
>  /* { dg-error "precision 322 of argument 1 to function '__builtin_bswapg' is 
> not a multiple of 8" "" { target bitint575 } } */
> +#endif
> +}
> --- gcc/testsuite/c-c++-common/builtin-bitreverseg-1.c.jj     2026-06-04 
> 08:31:41.616984054 +0200
> +++ gcc/testsuite/c-c++-common/builtin-bitreverseg-1.c        2026-06-04 
> 08:31:41.616984054 +0200
> @@ -0,0 +1,164 @@
> +/* Test __builtin_bitreverseg.  */
> +/* { dg-do run { target { c || c++11 } } } */
> +/* { dg-options "-O2" } */
> +
> +#if __CHAR_BIT__ == 8
> +#if __SIZEOF_INT__ == 4
> +static_assert (__builtin_bitreverseg (0x2fa889a7U) == 0xe59115f4U, "");
> +#endif
> +#if __SIZEOF_LONG_LONG__ == 8
> +static_assert (__builtin_bitreverseg (0xd7632f428bdccb94ULL) == 
> 0x29d33bd142f4c6ebULL, "");
> +#endif
> +static_assert (__builtin_bitreverseg ((unsigned char) 0xac) == (unsigned 
> char) 0x35, "");
> +#if __SIZEOF_SHORT__ == 2
> +static_assert (__builtin_bitreverseg ((unsigned short) 0xc4f0) == (unsigned 
> short) 0x0f23, "");
> +#endif
> +#if __SIZEOF_INT128__ == 16
> +static_assert (__builtin_bitreverseg ((((unsigned __int128) 
> 0x398773ddb9250c54ULL) << 64)
> +                              | 0x26933639cdf63ea6ULL)
> +                              == ((((unsigned __int128) 
> 0x657c6fb39c6cc964ULL) << 64)
> +                                  | 0x2a30a49dbbcee19cULL), "");
> +#endif
> +#endif
> +#if __BITINT_MAXWIDTH__ >= 856
> +static_assert (__builtin_bitreverseg (0xb75774uwb) == 0x2eeaeduwb, "");
> +static_assert (__builtin_bitreverseg (0xd55668c010uwb) == 0x0803166aabuwb, 
> "");
> +static_assert (__builtin_bitreverseg ((unsigned _BitInt(129)) 
> 0x01cc4426458663d6c35ad6f0c7117fc2b7uwb)
> +            == 0x01da87fd11c61ed6b586d78cc344c84467uwb, "");
> +static_assert (__builtin_bitreverseg ((unsigned _BitInt(136)) 
> 0xc73210faaad84376ebd396f82a166ac5f9uwb)
> +            == 0x9fa35668541f69cbd76ec21b555f084ce3uwb, "");
> +static_assert (__builtin_bitreverseg ((unsigned _BitInt(832)) 
> 0x09d2702b49ac2e9b1010df028451dceaf2cf9938035fa708921fb53a5d509d66220d916bb9bf07c9cfe6cc5437a83e2977d7617a360882c82838038588a0ecaaae7d16673d1d310c03fd603aa59f631c76c497adcc1975f451787ad9196684c7e39a2e20b75f2dbauwb)
> +            == 
> 0x5db4faed047459c7e32166989b5e1e8a2fae9833b5e9236e38c6f9a55c06bfc0308cb8bce668be7555370511a1c01c141341106c5e86ebee947c15ec2a3367f393e0fd9dd689b04466b90aba5cadf84910e5fac01c99f34f573b8a2140fb0808d9743592d40e4b90uwb,
>  "");
> +static_assert (__builtin_bitreverseg ((unsigned _BitInt(833)) 
> 0x0054078b08ef56720bb2a2cc52ddac983838de381c548c346e0b4274d51635f36b3c7e732bd4e536868702d864ae709ce74fd403a36037116c79854190bb34fbf7b26e238654590cdb5ce4400a54dcf1a3b1f546112c587da6ddbe3698f23190a49fb32af30c36cf68uwb)
> +            == 
> 0x002de6d8619ea99bf24a13189e32d8fb76cb7c346910c55f1b8b1e7654a0044e75b6613454c388ec9bdfbe59ba1305433c6d11d80d8b8057e5ce721cea4c3681c2c2d94e57a99cfc79ad9f58d1565c85a0ec5862547038f63838326b7694668a9ba09cd5ee21a3c054uwb,
>  "");
> +static_assert (__builtin_bitreverseg ((unsigned _BitInt(856)) 
> 0x6aa3d211688a1bc275204e2e83f7ecacfdc42aecdc1ae8093b901c207dc089e8645bf9cce6148e5b34dc89b7d47563d13a8ebd16a8a51fe3353b04b3fc8d9b60e9942ccfa8bb2adc97b4936b29f63c6384f9792c9f9810d4d41487d0a122308ab65c595e17843aaf38cd1auwb)
> +            == 
> 0x58b31cf55c21e87a9a3a6d510c44850be1282b2b0819f9349e9f21c63c6f94d6c92de93b54dd15f334299706d9b13fcd20dcacc7f8a51568bd715c8bc6ae2bed913b2cda712867339fda26179103be043809dc9017583b375423bf3537efc1747204ae43d85116884bc556uwb,
>  "");
> +#endif
> +
> +#if __CHAR_BIT__ == 8
> +#if __SIZEOF_INT__ == 4
> +[[gnu::noipa]] unsigned
> +bitreverse32 (unsigned x)
> +{
> +  return __builtin_bitreverseg (x);
> +}
> +#endif
> +#if __SIZEOF_LONG_LONG__ == 8
> +[[gnu::noipa]] unsigned long long
> +bitreverse64 (unsigned long long x)
> +{
> +  return __builtin_bitreverseg (x);
> +}
> +#endif
> +[[gnu::noipa]] unsigned char
> +bitreverse8 (unsigned char x)
> +{
> +  return __builtin_bitreverseg (x);
> +}
> +#if __SIZEOF_SHORT__ == 2
> +[[gnu::noipa]] unsigned short
> +bitreverse16 (unsigned short x)
> +{
> +  return __builtin_bitreverseg (x);
> +}
> +#endif
> +#if __SIZEOF_INT128__ == 16
> +[[gnu::noipa]] unsigned __int128
> +bitreverse128 (unsigned __int128 x)
> +{
> +  return __builtin_bitreverseg (x);
> +}
> +#endif
> +#endif
> +#if __BITINT_MAXWIDTH__ >= 856
> +[[gnu::noipa]] unsigned _BitInt(24)
> +bitreverse24 (unsigned _BitInt(24) x)
> +{
> +  return __builtin_bitreverseg (x);
> +}
> +
> +[[gnu::noipa]] unsigned _BitInt(40)
> +bitreverse40 (unsigned _BitInt(40) x)
> +{
> +  return __builtin_bitreverseg (x);
> +}
> +
> +[[gnu::noipa]] unsigned _BitInt(129)
> +bitreverse129 (unsigned _BitInt(129) x)
> +{
> +  return __builtin_bitreverseg (x);
> +}
> +
> +[[gnu::noipa]] unsigned _BitInt(136)
> +bitreverse136 (unsigned _BitInt(136) x)
> +{
> +  return __builtin_bitreverseg (x);
> +}
> +
> +[[gnu::noipa]] unsigned _BitInt(832)
> +bitreverse832 (unsigned _BitInt(832) x)
> +{
> +  return __builtin_bitreverseg (x);
> +}
> +
> +[[gnu::noipa]] unsigned _BitInt(833)
> +bitreverse833 (unsigned _BitInt(833) x)
> +{
> +  return __builtin_bitreverseg (x);
> +}
> +
> +[[gnu::noipa]] unsigned _BitInt(856)
> +bitreverse856 (unsigned _BitInt(856) x)
> +{
> +  return __builtin_bitreverseg (x);
> +}
> +#endif
> +
> +int
> +main ()
> +{
> +#if __CHAR_BIT__ == 8
> +#if __SIZEOF_INT__ == 4
> +  if (bitreverse32 (0x2fa889a7U) != 0xe59115f4U)
> +    __builtin_abort ();
> +#endif
> +#if __SIZEOF_LONG_LONG__ == 8
> +  if (bitreverse64 (0xd7632f428bdccb94ULL) != 0x29d33bd142f4c6ebULL)
> +    __builtin_abort ();
> +#endif
> +  if (bitreverse8 ((unsigned char) 0xac) != (unsigned char) 0x35)
> +    __builtin_abort ();
> +#if __SIZEOF_SHORT__ == 2
> +  if (bitreverse16 ((unsigned short) 0xc4f0) != (unsigned short) 0x0f23)
> +    __builtin_abort ();
> +#endif
> +#if __SIZEOF_INT128__ == 16
> +  if (bitreverse128 ((((unsigned __int128) 0x398773ddb9250c54ULL) << 64)
> +             | 0x26933639cdf63ea6ULL)
> +      != ((((unsigned __int128) 0x657c6fb39c6cc964ULL) << 64)
> +       | 0x2a30a49dbbcee19cULL))
> +    __builtin_abort ();
> +#endif
> +#endif
> +#if __BITINT_MAXWIDTH__ >= 856
> +  if (bitreverse24 (0xb75774uwb) != 0x2eeaed)
> +    __builtin_abort ();
> +  if (bitreverse40 (0xd55668c010uwb) != 0x0803166aabuwb)
> +    __builtin_abort ();
> +  if (bitreverse129 (0x01cc4426458663d6c35ad6f0c7117fc2b7uwb)
> +            != 0x01da87fd11c61ed6b586d78cc344c84467uwb)
> +    __builtin_abort ();
> +  if (bitreverse136 (0xc73210faaad84376ebd396f82a166ac5f9uwb)
> +      != 0x9fa35668541f69cbd76ec21b555f084ce3uwb)
> +    __builtin_abort ();
> +  if (bitreverse832 
> (0x09d2702b49ac2e9b1010df028451dceaf2cf9938035fa708921fb53a5d509d66220d916bb9bf07c9cfe6cc5437a83e2977d7617a360882c82838038588a0ecaaae7d16673d1d310c03fd603aa59f631c76c497adcc1975f451787ad9196684c7e39a2e20b75f2dbauwb)
> +      != 
> 0x5db4faed047459c7e32166989b5e1e8a2fae9833b5e9236e38c6f9a55c06bfc0308cb8bce668be7555370511a1c01c141341106c5e86ebee947c15ec2a3367f393e0fd9dd689b04466b90aba5cadf84910e5fac01c99f34f573b8a2140fb0808d9743592d40e4b90uwb)
> +    __builtin_abort ();
> +  if (bitreverse833 
> (0x0054078b08ef56720bb2a2cc52ddac983838de381c548c346e0b4274d51635f36b3c7e732bd4e536868702d864ae709ce74fd403a36037116c79854190bb34fbf7b26e238654590cdb5ce4400a54dcf1a3b1f546112c587da6ddbe3698f23190a49fb32af30c36cf68uwb)
> +      != 
> 0x002de6d8619ea99bf24a13189e32d8fb76cb7c346910c55f1b8b1e7654a0044e75b6613454c388ec9bdfbe59ba1305433c6d11d80d8b8057e5ce721cea4c3681c2c2d94e57a99cfc79ad9f58d1565c85a0ec5862547038f63838326b7694668a9ba09cd5ee21a3c054uwb)
> +    __builtin_abort ();
> +  if (bitreverse856 
> (0x6aa3d211688a1bc275204e2e83f7ecacfdc42aecdc1ae8093b901c207dc089e8645bf9cce6148e5b34dc89b7d47563d13a8ebd16a8a51fe3353b04b3fc8d9b60e9942ccfa8bb2adc97b4936b29f63c6384f9792c9f9810d4d41487d0a122308ab65c595e17843aaf38cd1auwb)
> +      != 
> 0x58b31cf55c21e87a9a3a6d510c44850be1282b2b0819f9349e9f21c63c6f94d6c92de93b54dd15f334299706d9b13fcd20dcacc7f8a51568bd715c8bc6ae2bed913b2cda712867339fda26179103be043809dc9017583b375423bf3537efc1747204ae43d85116884bc556uwb)
> +    __builtin_abort ();
> +#endif
> +}
> --- gcc/testsuite/c-c++-common/builtin-bitreverseg-2.c.jj     2026-06-04 
> 08:31:41.617122699 +0200
> +++ gcc/testsuite/c-c++-common/builtin-bitreverseg-2.c        2026-06-04 
> 08:35:54.425030605 +0200
> @@ -0,0 +1,21 @@
> +/* Test __builtin_bitreverseg.  */
> +/* { dg-do compile } */
> +/* { dg-options "" } */
> +
> +int
> +main ()
> +{
> +  __builtin_bitreverseg ();          /* { dg-error "wrong number of 
> arguments to '__builtin_bitreverseg'" } */
> +  __builtin_bitreverseg (1U, 1U);    /* { dg-error "wrong number of 
> arguments to '__builtin_bitreverseg'" } */
> +  __builtin_bitreverseg (1.0);               /* { dg-error 
> "'__builtin_bitreverseg' operand not an integral type" } */
> +  __builtin_bitreverseg (1.0f);              /* { dg-error 
> "'__builtin_bitreverseg' operand not an integral type" } */
> +  __builtin_bitreverseg (1.0L);              /* { dg-error 
> "'__builtin_bitreverseg' operand not an integral type" } */
> +  struct S { int a; };
> +  __builtin_bitreverseg ((struct S) { 42 }); /* { dg-error 
> "'__builtin_bitreverseg' operand not an integral type" } */
> +  enum E { E0, E1 };
> +  __builtin_bitreverseg (E1);                /* { dg-error "argument 1 in 
> call to function '__builtin_bitreverseg' has signed type" "" { target c } } */
> +                                     /* { dg-error "argument 1 in call to 
> function '__builtin_bitreverseg' has enumerated type" "" { target c++ } .-1 } 
> */
> +  __builtin_bitreverseg (false);     /* { dg-error "argument 1 in call to 
> function '__builtin_bitreverseg' has boolean type" } */
> +  __builtin_bitreverseg (1);         /* { dg-error "argument 1 in call to 
> function '__builtin_bitreverseg' has signed type" } */
> +  __builtin_bitreverseg ((char) 1);  /* { dg-error "argument 1 in call to 
> function '__builtin_bitreverseg' has signed type" "" { target { ! 
> unsigned_char } } } */
> +}
> 
> 
>       Jakub
> 
> 

-- 
Richard Biener <[email protected]>
SUSE Software Solutions Germany GmbH,
Frankenstrasse 146, 90461 Nuernberg, Germany;
GF: Jochen Jaser, Andrew McDonald, Werner Knoblich; (HRB 36809, AG Nuernberg)

Reply via email to