On 6/4/26 3:33 AM, 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 C++ changes are OK now.

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


Reply via email to