https://gcc.gnu.org/g:b554e3e64368c734e6e47c708fa7dde4096775c6

commit r17-997-gb554e3e64368c734e6e47c708fa7dde4096775c6
Author: Jakub Jelinek <[email protected]>
Date:   Sat May 30 09:46:29 2026 +0200

    c, middle-end: Implement C2Y N3705: bit-precise enum
    
    The following patch implements the C2Y
    https://www.open-std.org/jtc1/sc22/WG14/www/docs/n3705.htm - bit-precise 
enum
    paper.
    In c_parser_enum_specifier it allows {,signed,unsigned} _BitInt(N) types as
    fixed underlying type of enums for -std=c2y/-std=gnu2y and the rest of the
    patch deals with that, mostly by adjusting the preexisting BITINT_TYPE_P 
macro
    (which was just used in one spot though) to not just include BITINT_TYPE
    types, but ENUMERAL_TYPE with BITINT_TYPE as underlying type, and changing
    lots of places that use TREE_CODE (type) == BITINT_TYPE to
    BITINT_TYPE_P (type).
    Like normal ENUMERAL_TYPEs are uselessly convertible in GIMPLE with same
    precision/sign INTEGER_TYPEs, ENUMERAL_TYPEs with BITINT_TYPE as underlying 
type
    are uselessly convertible with same precision/sign BITINT_TYPE and vice
    versa, so that extends the number of spots that need to use BITINT_TYPE_P
    macros.
    For bit-fields with enumeral types with underlying fixed bit-precise type,
    WG14 issue 1021 wording is used, in that those bit-fields promote to the
    underlying bit-precise type.
    
    2026-05-30  Jakub Jelinek  <[email protected]>
    
    gcc/
            * tree.h (BITINT_TYPE_P): Return true also for ENUMERAL_TYPE with
            BITINT_TYPE as underlying type.
            * stor-layout.cc (finish_bitfield_representative): Use BITINT_TYPE_P
            macro.
            (layout_type): Likewise.  Lay out ENUMERAL_TYPEs with BITINT_TYPE as
            underlying type the same as BITINT_TYPEs.
            * gimple-lower-bitint.cc (maybe_cast_middle_bitint): Use 
BITINT_TYPE_P
            macro.
            (mergeable_op, optimizable_arith_overflow, comparison_op,
            bitint_large_huge::handle_cast, bitint_large_huge::lower_shift_stmt,
            bitint_large_huge::lower_muldiv_stmt,
            bitint_large_huge::lower_mul_overflow,
            bitint_large_huge::lower_bit_query,
            bitint_large_huge::lower_call, bitint_large_huge::lower_asm,
            bitint_large_huge::lower_stmt, build_bitint_stmt_ssa_conflicts,
            arith_overflow_arg_kind, gimple_lower_bitint): Likewise.
            * gimple-expr.cc (useless_type_conversion_p): Likewise.
            * fold-const.cc (make_range_step): Likewise.
            (range_check_type): For ENUMERAL_TYPEs with BITINT_TYPE as 
underlying
            type use the underlying type.
            (extract_muldiv_1): Use BITINT_TYPE_P macro.
            (native_encode_wide_int): Likewise.
            (native_interpret_int): Likewise.
            * vr-values.cc
            (simplify_using_ranges::simplify_float_conversion_using_ranges):
            Likewise.
            * cfgexpand.cc (expand_debug_expr): Likewise.
            * convert.cc (convert_to_integer_1): Add special case for 
ENUMERAL_TYPE
            with underlying BITINT_TYPE.
            * tree-ssa-sccvn.cc (vn_walk_cb_data::push_partial_def): Use
            BITINT_TYPE_P macro.
            (vn_reference_lookup_3): Likewise.
            (eliminate_dom_walker::eliminate_stmt): Likewise.
            * match.pd (ctz(ext(X)) == ctz(X), popcount(zext(X)) == popcount(X),
            parity(zext(X)) == parity(X), a != 0 ? CLZ(a) : CST -> .CLZ(a),
            a != 0 ? CTZ(a) : CST -> .CTZ(a), ffs(ext(X)) == ffs(X)): Likewise.
            * builtins.cc (fold_builtin_bit_query): Likewise.
            * explow.cc (promote_function_mode): Handle ENUMERAL_TYPE with
            BITINT_TYPE as underlying type like BITINT_TYPE.
            (promote_mode): Likewise.
            * expr.cc (EXTEND_BITINT): Use BITINT_TYPE_P macro.
            (expand_expr_real_1): Likewise.
            * fold-const-call.cc (fold_const_call_ss): Likewise.
            * gimple-fold.cc (gimple_fold_builtin_memset): Likewise.
            (clear_padding_type_may_have_padding_p): Handle ENUMERAL_TYPE
            with BITINT_TYPE as underlying type like BITINT_TYPE.
            (type_has_padding_at_level_p): Likewise.
            (clear_padding_type): Likewise.
            * gimple-match-exports.cc (build_call_internal): Use BITINT_TYPE_P
            macro.
            * internal-fn.cc (expand_ubsan_result_store): Likewise.
            * tree-sra.cc (create_access): Likewise.
            (analyze_access_subtree): Likewise.
            * tree-ssa-phiopt.cc (cond_removal_in_builtin_zero_pattern): 
Likewise.
            * tree-ssa.cc (maybe_optimize_var): Likewise.
            * tree-switch-conversion.cc (switch_conversion::array_value_type):
            Likewise.
            (switch_conversion::build_arrays): Likewise.
            (jump_table_cluster::emit): Likewise.
            * ubsan.cc (ubsan_encode_value): Likewise.
            (ubsan_type_descriptor): Handle ENUMERAL_TYPE with BITINT_TYPE as
            underlying type like BITINT_TYPE.
            (instrument_si_overflow): Use BITINT_TYPE_P macro.
            * varasm.cc (output_constant): Handle ENUMERAL_TYPE with BITINT_TYPE
            as underlying type like BITINT_TYPE.
            * config/aarch64/aarch64.cc (aarch64_return_in_memory_1): Use
            BITINT_TYPE_P macro.
            (bitint_or_aggr_of_bitint_p): Likewise.
            (aarch64_composite_type_p): Likewise.
            * config/arm/arm.cc (arm_return_in_memory): Likewise.
            (arm_needs_doubleword_align): Likewise.
            * config/i386/i386.cc (classify_argument): Handle ENUMERAL_TYPE with
            BITINT_TYPE as underlying type like BITINT_TYPE.
            * config/loongarch/loongarch.h: Use BITINT_TYPE_P macro.
    gcc/c-family/
            * c-attribs.cc (type_valid_for_vector_size): Use BITINT_TYPE_P 
macro.
            * c-common.cc (c_common_get_narrower): For ENUMERAL_TYPE with
            BITINT_TYPE as underlying type convert to the underlying type.
            (c_common_signed_or_unsigned_type): Use BITINT_TYPE_P macro.
            (sync_resolve_size): Likewise.
            (atomic_bitint_fetch_using_cas_loop): Likewise.
            (resolve_overloaded_builtin): Likewise.
    gcc/c/
            * c-parser.cc (c_parser_enum_specifier): Implement
            C2Y N3705: bit-precise enum.  Allow for flag_isoc2y enumerated
            types with BITINT_TYPE as underlying type.
            * c-lang.cc (LANG_HOOKS_ENUM_UNDERLYING_BASE_TYPE): Redefine.
            * c-tree.h (c_enum_underlying_base_type): Declare.
            * c-objc-common.cc (c_enum_underlying_base_type): New function.
            * c-decl.cc (finish_struct): Use BITINT_TYPE_P macro.
            * c-typeck.cc (perform_integral_promotions): Promote bit-fields with
            enum type with underlying fixed _BitInt type to that _BitInt type.
    gcc/testsuite/
            * gcc.dg/bitint-133.c: New test.
            * gcc.dg/bitint-134.c: New test.
            * gcc.dg/bitint-135.c: New test.
            * gcc.dg/bitint-136.c: New test.
            * gcc.dg/torture/bitint-99.c: New test.
    
    Reviewed-by: Joseph Myers <[email protected]>

Diff:
---
 gcc/builtins.cc                          |   2 +-
 gcc/c-family/c-attribs.cc                |   2 +-
 gcc/c-family/c-common.cc                 |  13 +--
 gcc/c/c-decl.cc                          |   4 +-
 gcc/c/c-lang.cc                          |   2 +
 gcc/c/c-objc-common.cc                   |  15 ++++
 gcc/c/c-parser.cc                        |   3 +-
 gcc/c/c-tree.h                           |   1 +
 gcc/c/c-typeck.cc                        |  11 ++-
 gcc/cfgexpand.cc                         |   2 +-
 gcc/config/aarch64/aarch64.cc            |   6 +-
 gcc/config/arm/arm.cc                    |   6 +-
 gcc/config/i386/i386.cc                  |   3 +-
 gcc/config/loongarch/loongarch.h         |   2 +-
 gcc/convert.cc                           |   6 ++
 gcc/explow.cc                            |  17 ++--
 gcc/expr.cc                              |   6 +-
 gcc/fold-const-call.cc                   |   4 +-
 gcc/fold-const.cc                        |  13 +--
 gcc/gimple-expr.cc                       |   3 +-
 gcc/gimple-fold.cc                       |  15 +++-
 gcc/gimple-lower-bitint.cc               | 134 +++++++++++++++----------------
 gcc/gimple-match-exports.cc              |   2 +-
 gcc/internal-fn.cc                       |   2 +-
 gcc/match.pd                             |  16 ++--
 gcc/stor-layout.cc                       |  26 +++---
 gcc/testsuite/gcc.dg/bitint-133.c        |  45 +++++++++++
 gcc/testsuite/gcc.dg/bitint-134.c        |  42 ++++++++++
 gcc/testsuite/gcc.dg/bitint-135.c        |  47 +++++++++++
 gcc/testsuite/gcc.dg/bitint-136.c        |  36 +++++++++
 gcc/testsuite/gcc.dg/torture/bitint-99.c |  58 +++++++++++++
 gcc/tree-sra.cc                          |   5 +-
 gcc/tree-ssa-phiopt.cc                   |   4 +-
 gcc/tree-ssa-sccvn.cc                    |   6 +-
 gcc/tree-ssa.cc                          |   2 +-
 gcc/tree-switch-conversion.cc            |   6 +-
 gcc/tree.h                               |  11 ++-
 gcc/ubsan.cc                             |  17 ++--
 gcc/varasm.cc                            |   6 +-
 gcc/vr-values.cc                         |   2 +-
 40 files changed, 449 insertions(+), 154 deletions(-)

diff --git a/gcc/builtins.cc b/gcc/builtins.cc
index 05d5fb13bfce..3772a352dfad 100644
--- a/gcc/builtins.cc
+++ b/gcc/builtins.cc
@@ -10483,7 +10483,7 @@ fold_builtin_bit_query (location_t loc, enum 
built_in_function fcode,
       /* Only keep second argument to IFN_CLZ/IFN_CTZ if it is the
         value defined at zero during GIMPLE, or for large/huge _BitInt
         (which are then lowered during bitint lowering).  */
-      if (arg2 && TREE_CODE (TREE_TYPE (arg0)) != BITINT_TYPE)
+      if (arg2 && !BITINT_TYPE_P (TREE_TYPE (arg0)))
        {
          int val;
          if (fcode == BUILT_IN_CLZG)
diff --git a/gcc/c-family/c-attribs.cc b/gcc/c-family/c-attribs.cc
index d437c55285e3..626aebef0ffc 100644
--- a/gcc/c-family/c-attribs.cc
+++ b/gcc/c-family/c-attribs.cc
@@ -4885,7 +4885,7 @@ type_valid_for_vector_size (tree type, tree atname, tree 
args,
       || !tree_fits_uhwi_p (TYPE_SIZE_UNIT (type))
       || TREE_CODE (type) == BOOLEAN_TYPE
       || hardbool_p
-      || TREE_CODE (type) == BITINT_TYPE)
+      || BITINT_TYPE_P (type))
     {
       if (error_p)
        error ("invalid vector type for attribute %qE", atname);
diff --git a/gcc/c-family/c-common.cc b/gcc/c-family/c-common.cc
index 874530f065d3..961b3fc93d7b 100644
--- a/gcc/c-family/c-common.cc
+++ b/gcc/c-family/c-common.cc
@@ -1380,6 +1380,9 @@ c_common_get_narrower (tree op, int *unsignedp_ptr)
   if (TREE_CODE (TREE_TYPE (op)) == ENUMERAL_TYPE
       && ENUM_IS_SCOPED (TREE_TYPE (op)))
     {
+      if (BITINT_TYPE_P (TREE_TYPE (op)))
+       return fold_convert (ENUM_UNDERLYING_TYPE (TREE_TYPE (op)), op);
+
       /* C++0x scoped enumerations don't implicitly convert to integral
         type; if we stripped an explicit conversion to a larger type we
         need to replace it so common_type will still work.  */
@@ -2818,7 +2821,7 @@ c_common_signed_or_unsigned_type (int unsignedp, tree 
type)
       || TYPE_UNSIGNED (type) == unsignedp)
     return type;
 
-  if (TREE_CODE (type) == BITINT_TYPE
+  if (BITINT_TYPE_P (type)
       /* signed _BitInt(1) is invalid before C2Y, avoid creating that.  */
       && (unsignedp || flag_isoc2y || TYPE_PRECISION (type) > 1))
     return build_bitint_type (TYPE_PRECISION (type), unsignedp);
@@ -7747,7 +7750,7 @@ sync_resolve_size (tree function, vec<tree, va_gc> 
*params, bool fetch,
 
   size = tree_to_uhwi (TYPE_SIZE_UNIT (type));
   if (size == 16
-      && TREE_CODE (type) == BITINT_TYPE
+      && BITINT_TYPE_P (type)
       && !targetm.scalar_mode_supported_p (TImode))
     {
       if (fetch && !orig_format)
@@ -7758,7 +7761,7 @@ sync_resolve_size (tree function, vec<tree, va_gc> 
*params, bool fetch,
   if (size == 1 || size == 2 || size == 4 || size == 8 || size == 16)
     return size;
 
-  if (fetch && !orig_format && TREE_CODE (type) == BITINT_TYPE)
+  if (fetch && !orig_format && BITINT_TYPE_P (type))
     return -1;
 
  incompatible:
@@ -8486,7 +8489,7 @@ atomic_bitint_fetch_using_cas_loop (location_t loc,
 
   tree nonatomic_lhs_type = TREE_TYPE (TREE_TYPE ((*orig_params)[0]));
   nonatomic_lhs_type = TYPE_MAIN_VARIANT (nonatomic_lhs_type);
-  gcc_assert (TREE_CODE (nonatomic_lhs_type) == BITINT_TYPE);
+  gcc_assert (BITINT_TYPE_P (nonatomic_lhs_type));
 
   tree lhs_addr = (*orig_params)[0];
   tree val = convert (nonatomic_lhs_type, (*orig_params)[1]);
@@ -8879,7 +8882,7 @@ resolve_overloaded_builtin (location_t loc, tree function,
        if (new_return)
          {
            /* Cast function result from I{1,2,4,8,16} to the required type.  */
-           if (TREE_CODE (TREE_TYPE (new_return)) == BITINT_TYPE)
+           if (BITINT_TYPE_P (TREE_TYPE (new_return)))
              {
                struct bitint_info info;
                unsigned prec = TYPE_PRECISION (TREE_TYPE (new_return));
diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc
index 683780ab6543..ab2a0d27dbf6 100644
--- a/gcc/c/c-decl.cc
+++ b/gcc/c/c-decl.cc
@@ -9847,8 +9847,8 @@ finish_struct (location_t loc, tree t, tree fieldlist, 
tree attributes,
            }
          if (width != TYPE_PRECISION (type))
            {
-             if (TREE_CODE (type) == BITINT_TYPE
-                 && width >= (TYPE_UNSIGNED (type) ? 1 : 2))
+             if (BITINT_TYPE_P (type)
+                 && width >= ((TYPE_UNSIGNED (type) || flag_isoc2y) ? 1 : 2))
                TREE_TYPE (field)
                  = build_bitint_type (width, TYPE_UNSIGNED (type));
              else
diff --git a/gcc/c/c-lang.cc b/gcc/c/c-lang.cc
index 0d1b1c66ad0e..1c939561c72f 100644
--- a/gcc/c/c-lang.cc
+++ b/gcc/c/c-lang.cc
@@ -39,6 +39,8 @@ enum c_language_kind c_language = clk_c;
 #define LANG_HOOKS_INIT c_objc_common_init
 #undef LANG_HOOKS_INIT_TS
 #define LANG_HOOKS_INIT_TS c_common_init_ts
+#undef LANG_HOOKS_ENUM_UNDERLYING_BASE_TYPE
+#define LANG_HOOKS_ENUM_UNDERLYING_BASE_TYPE c_enum_underlying_base_type
 
 #if CHECKING_P
 #undef LANG_HOOKS_RUN_LANG_SELFTESTS
diff --git a/gcc/c/c-objc-common.cc b/gcc/c/c-objc-common.cc
index e56e936316f7..15f981bfc525 100644
--- a/gcc/c/c-objc-common.cc
+++ b/gcc/c/c-objc-common.cc
@@ -487,3 +487,18 @@ c_type_dwarf_attribute (const_tree type, int attr)
 
   return -1;
 }
+
+/* The C version of the enum_underlying_base_type langhook.  */
+
+tree
+c_enum_underlying_base_type (const_tree type)
+{
+  tree underlying_type = ENUM_UNDERLYING_TYPE (type);
+
+  if (! ENUM_FIXED_UNDERLYING_TYPE_P (type))
+    underlying_type
+      = c_common_type_for_mode (TYPE_MODE (underlying_type),
+                               TYPE_UNSIGNED (underlying_type));
+
+  return underlying_type;
+}
diff --git a/gcc/c/c-parser.cc b/gcc/c/c-parser.cc
index 4ded9661f589..408417d15706 100644
--- a/gcc/c/c-parser.cc
+++ b/gcc/c/c-parser.cc
@@ -4182,7 +4182,8 @@ c_parser_enum_specifier (c_parser *parser)
       if (specs->default_int_p)
        error_at (enum_loc, "no %<enum%> underlying type specified");
       else if (TREE_CODE (specs->type) != INTEGER_TYPE
-              && TREE_CODE (specs->type) != BOOLEAN_TYPE)
+              && TREE_CODE (specs->type) != BOOLEAN_TYPE
+              && (!flag_isoc2y || TREE_CODE (specs->type) != BITINT_TYPE))
        {
          error_at (enum_loc, "invalid %<enum%> underlying type");
          specs->type = integer_type_node;
diff --git a/gcc/c/c-tree.h b/gcc/c/c-tree.h
index 6dce4d3b4ba1..2271dbc5ca16 100644
--- a/gcc/c/c-tree.h
+++ b/gcc/c/c-tree.h
@@ -786,6 +786,7 @@ extern void c_initialize_diagnostics (diagnostics::context 
*);
 extern bool c_var_mod_p (tree x, tree fn);
 extern alias_set_type c_get_alias_set (tree);
 extern int c_type_dwarf_attribute (const_tree, int);
+extern tree c_enum_underlying_base_type (const_tree);
 
 /* in c-typeck.cc */
 extern int in_alignof;
diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc
index 6bf404ac9857..9d2c991d91e9 100644
--- a/gcc/c/c-typeck.cc
+++ b/gcc/c/c-typeck.cc
@@ -2826,9 +2826,14 @@ perform_integral_promotions (tree exp)
   if (TREE_CODE (exp) == COMPONENT_REF
       && DECL_C_BIT_FIELD (TREE_OPERAND (exp, 1)))
     {
-      if (TREE_CODE (DECL_BIT_FIELD_TYPE (TREE_OPERAND (exp, 1)))
-         == BITINT_TYPE)
-       return convert (DECL_BIT_FIELD_TYPE (TREE_OPERAND (exp, 1)), exp);
+      if (BITINT_TYPE_P (DECL_BIT_FIELD_TYPE (TREE_OPERAND (exp, 1))))
+       {
+         tree btype = DECL_BIT_FIELD_TYPE (TREE_OPERAND (exp, 1));
+         if (TREE_CODE (btype) == BITINT_TYPE)
+           return convert (btype, exp);
+         else
+           return convert (ENUM_UNDERLYING_TYPE (btype), exp);
+       }
       /* If it's thinner than an int, promote it like a
         c_promoting_integer_type_p, otherwise leave it alone.  */
       if (compare_tree_int (DECL_SIZE (TREE_OPERAND (exp, 1)),
diff --git a/gcc/cfgexpand.cc b/gcc/cfgexpand.cc
index 7517e8d57889..9f6e66e1c759 100644
--- a/gcc/cfgexpand.cc
+++ b/gcc/cfgexpand.cc
@@ -4924,7 +4924,7 @@ expand_debug_expr (tree exp)
       /* Fall through.  */
 
     case INTEGER_CST:
-      if (TREE_CODE (TREE_TYPE (exp)) == BITINT_TYPE
+      if (BITINT_TYPE_P (TREE_TYPE (exp))
          && TYPE_MODE (TREE_TYPE (exp)) == BLKmode)
        return NULL;
       /* FALLTHRU */
diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
index 8465303649f6..0aa48f456a76 100644
--- a/gcc/config/aarch64/aarch64.cc
+++ b/gcc/config/aarch64/aarch64.cc
@@ -7397,7 +7397,7 @@ aarch64_return_in_memory_1 (const_tree type)
   int count;
 
   if (!AGGREGATE_TYPE_P (type)
-      && TREE_CODE (type) != BITINT_TYPE
+      && !BITINT_TYPE_P (type)
       && TREE_CODE (type) != COMPLEX_TYPE
       && TREE_CODE (type) != VECTOR_TYPE)
     /* Simple scalar types always returned in registers.  */
@@ -7571,7 +7571,7 @@ bitint_or_aggr_of_bitint_p (tree type)
   if (!type)
     return false;
 
-  if (TREE_CODE (type) == BITINT_TYPE)
+  if (BITINT_TYPE_P (type))
     return true;
 
   /* If ARRAY_TYPE, check it's element type.  */
@@ -23478,7 +23478,7 @@ aarch64_composite_type_p (const_tree type,
     return true;
 
   if (type
-      && TREE_CODE (type) == BITINT_TYPE
+      && BITINT_TYPE_P (type)
       && int_size_in_bytes (type) > 16)
     return true;
 
diff --git a/gcc/config/arm/arm.cc b/gcc/config/arm/arm.cc
index 41808e42ab15..6f65c06c13ca 100644
--- a/gcc/config/arm/arm.cc
+++ b/gcc/config/arm/arm.cc
@@ -6134,7 +6134,7 @@ arm_return_in_memory (const_tree type, const_tree fntype)
         some of the detail.  */
       if (!AGGREGATE_TYPE_P (type)
          /* A _BitInt(N) for N <= 64 is a simple, non-aggregate type.  */
-         && !(TREE_CODE (type) == BITINT_TYPE && size > 8)
+         && !(BITINT_TYPE_P (type) && size > 8)
          && TREE_CODE (type) != VECTOR_TYPE
          && TREE_CODE (type) != COMPLEX_TYPE)
        return false;
@@ -6166,7 +6166,7 @@ arm_return_in_memory (const_tree type, const_tree fntype)
 
   if (!AGGREGATE_TYPE_P (type)
       /* A _BitInt(N) for N <= 64 is a simple, non-aggregate type.  */
-      && !(TREE_CODE (type) == BITINT_TYPE && size > 8)
+      && !(BITINT_TYPE_P (type) && size > 8)
       && (TREE_CODE (type) != VECTOR_TYPE))
     /* All simple types are returned in registers.  */
     return false;
@@ -7227,7 +7227,7 @@ arm_needs_doubleword_align (machine_mode mode, const_tree 
type)
     return GET_MODE_ALIGNMENT (mode) > PARM_BOUNDARY;
 
   /* For any _BitInt(N) where N > 32 the ABI demands double word alignment.  */
-  if (TREE_CODE (type) == BITINT_TYPE)
+  if (BITINT_TYPE_P (type))
     {
       if (int_size_in_bytes (type) > 4)
        return 1;
diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc
index ac8982964161..9148ac1e0571 100644
--- a/gcc/config/i386/i386.cc
+++ b/gcc/config/i386/i386.cc
@@ -2281,7 +2281,7 @@ classify_argument (machine_mode mode, const_tree type,
     }
 
   if (type && (AGGREGATE_TYPE_P (type)
-              || (TREE_CODE (type) == BITINT_TYPE && words > 1)))
+              || (BITINT_TYPE_P (type) && words > 1)))
     {
       int i;
       tree field;
@@ -2431,6 +2431,7 @@ classify_argument (machine_mode mode, const_tree type,
          break;
 
        case BITINT_TYPE:
+       case ENUMERAL_TYPE:
          /* _BitInt(N) for N > 64 is passed as structure containing
             (N + 63) / 64 64-bit elements.  */
          if (words > 2)
diff --git a/gcc/config/loongarch/loongarch.h b/gcc/config/loongarch/loongarch.h
index 1059eee37ca3..4d9acd8ca7c5 100644
--- a/gcc/config/loongarch/loongarch.h
+++ b/gcc/config/loongarch/loongarch.h
@@ -271,7 +271,7 @@ along with GCC; see the file COPYING3.  If not see
       && GET_MODE_SIZE (MODE) < UNITS_PER_WORD) \
     { \
       if ((MODE) == SImode \
-         && !(TYPE && TREE_CODE (TYPE) == BITINT_TYPE \
+         && !(TYPE && BITINT_TYPE_P (TYPE) \
               && TYPE_PRECISION (TYPE) < 32)) \
        (UNSIGNEDP) = 0; \
       (MODE) = Pmode; \
diff --git a/gcc/convert.cc b/gcc/convert.cc
index 881797194f8c..2d2cdfbc8662 100644
--- a/gcc/convert.cc
+++ b/gcc/convert.cc
@@ -704,6 +704,12 @@ convert_to_integer_1 (tree type, tree expr, bool dofold)
          return maybe_fold_build1_loc (dofold, loc, code, type, expr);
        }
 
+      else if (TREE_CODE (type) == ENUMERAL_TYPE && BITINT_TYPE_P (type))
+       {
+         expr = convert_to_integer_1 (TREE_TYPE (type), expr, dofold);
+         return maybe_fold_build1_loc (dofold, loc, NOP_EXPR, type, expr);
+       }
+
       /* If TYPE is an enumeral type or a type with a precision less
         than the number of bits in its mode, do the conversion to the
         type corresponding to its mode, then do a nop conversion
diff --git a/gcc/explow.cc b/gcc/explow.cc
index 755c1d2e6dc4..e9dc755ee629 100644
--- a/gcc/explow.cc
+++ b/gcc/explow.cc
@@ -852,9 +852,8 @@ promote_function_mode (const_tree type, machine_mode mode, 
int *punsignedp,
        return mode;
     }
 
-  switch (TREE_CODE (type))
+  if (BITINT_TYPE_P (type))
     {
-    case BITINT_TYPE:
       if (TYPE_MODE (type) == BLKmode)
        return mode;
 
@@ -865,10 +864,12 @@ promote_function_mode (const_tree type, machine_mode 
mode, int *punsignedp,
 
       if (!info.extended)
        return mode;
-      /* FALLTHRU */
+    }
+  switch (TREE_CODE (type))
+    {
     case INTEGER_TYPE:   case ENUMERAL_TYPE:   case BOOLEAN_TYPE:
     case REAL_TYPE:      case OFFSET_TYPE:     case FIXED_POINT_TYPE:
-    case POINTER_TYPE:   case REFERENCE_TYPE:
+    case POINTER_TYPE:   case REFERENCE_TYPE:  case BITINT_TYPE:
       return targetm.calls.promote_function_mode (type, mode, punsignedp, 
funtype,
                                                  for_return);
 
@@ -903,9 +904,8 @@ promote_mode (const_tree type ATTRIBUTE_UNUSED, 
machine_mode mode,
   code = TREE_CODE (type);
   unsignedp = *punsignedp;
 
-  switch (code)
+  if (BITINT_TYPE_P (type))
     {
-    case BITINT_TYPE:
       if (TYPE_MODE (type) == BLKmode)
        return mode;
 
@@ -916,9 +916,12 @@ promote_mode (const_tree type ATTRIBUTE_UNUSED, 
machine_mode mode,
 
       if (!info.extended)
        return mode;
-      /* FALLTHRU */
+    }
+  switch (code)
+    {
     case INTEGER_TYPE:   case ENUMERAL_TYPE:   case BOOLEAN_TYPE:
     case REAL_TYPE:      case OFFSET_TYPE:     case FIXED_POINT_TYPE:
+    case BITINT_TYPE:
       /* Values of these types always have scalar mode.  */
       smode = as_a <scalar_mode> (mode);
       PROMOTE_MODE (smode, unsignedp, type);
diff --git a/gcc/expr.cc b/gcc/expr.cc
index 1c68055d45f8..aa79b41d2e16 100644
--- a/gcc/expr.cc
+++ b/gcc/expr.cc
@@ -11397,7 +11397,7 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode 
tmode,
      internally extend after arithmetic operations, we can avoid doing that
      when reading from SSA_NAMEs of vars.  */
 #define EXTEND_BITINT(expr) \
-  ((TREE_CODE (type) == BITINT_TYPE                                    \
+  ((BITINT_TYPE_P (type)                                               \
     && !bitint_extended                                                        
\
     && reduce_bit_field                                                        
\
     && mode != BLKmode                                                 \
@@ -11410,7 +11410,7 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode 
tmode,
   type = TREE_TYPE (exp);
   mode = TYPE_MODE (type);
   unsignedp = TYPE_UNSIGNED (type);
-  if (TREE_CODE (type) == BITINT_TYPE && bitint_extended == -1)
+  if (BITINT_TYPE_P (type) && bitint_extended == -1)
     {
       struct bitint_info info;
       bool ok = targetm.c.bitint_type_info (TYPE_PRECISION (type), &info);
@@ -11755,7 +11755,7 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode 
tmode,
 
     case INTEGER_CST:
       {
-       if (TREE_CODE (type) == BITINT_TYPE)
+       if (BITINT_TYPE_P (type))
          {
            unsigned int prec = TYPE_PRECISION (type);
            struct bitint_info info;
diff --git a/gcc/fold-const-call.cc b/gcc/fold-const-call.cc
index f982983dba6a..6e3487b34a75 100644
--- a/gcc/fold-const-call.cc
+++ b/gcc/fold-const-call.cc
@@ -1055,7 +1055,7 @@ fold_const_call_ss (wide_int *result, combined_fn fn, 
const wide_int_ref &arg,
        int tmp;
        if (wi::ne_p (arg, 0))
          tmp = wi::clz (arg);
-       else if (TREE_CODE (arg_type) == BITINT_TYPE)
+       else if (BITINT_TYPE_P (arg_type))
          tmp = TYPE_PRECISION (arg_type);
        else if (!CLZ_DEFINED_VALUE_AT_ZERO (SCALAR_INT_TYPE_MODE (arg_type),
                                             tmp))
@@ -1070,7 +1070,7 @@ fold_const_call_ss (wide_int *result, combined_fn fn, 
const wide_int_ref &arg,
        int tmp;
        if (wi::ne_p (arg, 0))
          tmp = wi::ctz (arg);
-       else if (TREE_CODE (arg_type) == BITINT_TYPE)
+       else if (BITINT_TYPE_P (arg_type))
          tmp = TYPE_PRECISION (arg_type);
        else if (!CTZ_DEFINED_VALUE_AT_ZERO (SCALAR_INT_TYPE_MODE (arg_type),
                                             tmp))
diff --git a/gcc/fold-const.cc b/gcc/fold-const.cc
index 352083e146b4..2eba50368dde 100644
--- a/gcc/fold-const.cc
+++ b/gcc/fold-const.cc
@@ -5426,7 +5426,7 @@ make_range_step (location_t loc, enum tree_code code, 
tree arg0, tree arg1,
            equiv_type
              = lang_hooks.types.type_for_mode (TYPE_MODE (arg0_type),
                                                TYPE_SATURATING (arg0_type));
-         else if (TREE_CODE (arg0_type) == BITINT_TYPE)
+         else if (BITINT_TYPE_P (arg0_type))
            equiv_type = arg0_type;
          else
            equiv_type
@@ -5616,7 +5616,9 @@ range_check_type (tree etype)
 {
   /* First make sure that arithmetics in this type is valid, then make sure
      that it wraps around.  */
-  if (TREE_CODE (etype) == ENUMERAL_TYPE || TREE_CODE (etype) == BOOLEAN_TYPE)
+  if (TREE_CODE (etype) == ENUMERAL_TYPE && BITINT_TYPE_P (etype))
+    etype = TREE_TYPE (etype);
+  else if (TREE_CODE (etype) == ENUMERAL_TYPE || TREE_CODE (etype) == 
BOOLEAN_TYPE)
     etype = lang_hooks.types.type_for_size (TYPE_PRECISION (etype), 1);
 
   if (TREE_CODE (etype) == INTEGER_TYPE && !TYPE_UNSIGNED (etype))
@@ -6572,8 +6574,7 @@ extract_muldiv_1 (tree t, tree c, enum tree_code code, 
tree wide_type)
   tree ctype = type;
   if (wide_type)
     {
-      if (TREE_CODE (type) == BITINT_TYPE
-         || TREE_CODE (wide_type) == BITINT_TYPE)
+      if (BITINT_TYPE_P (type) || BITINT_TYPE_P (wide_type))
        {
          if (TYPE_PRECISION (wide_type) > TYPE_PRECISION (type))
            ctype = wide_type;
@@ -7455,7 +7456,7 @@ native_encode_wide_int (tree type, const wide_int_ref 
&val,
                        unsigned char *ptr, int len, int off)
 {
   int total_bytes;
-  if (TREE_CODE (type) == BITINT_TYPE)
+  if (BITINT_TYPE_P (type))
     {
       struct bitint_info info;
       bool ok = targetm.c.bitint_type_info (TYPE_PRECISION (type), &info);
@@ -8479,7 +8480,7 @@ static tree
 native_interpret_int (tree type, const unsigned char *ptr, int len)
 {
   int total_bytes;
-  if (TREE_CODE (type) == BITINT_TYPE)
+  if (BITINT_TYPE_P (type))
     {
       struct bitint_info info;
       bool ok = targetm.c.bitint_type_info (TYPE_PRECISION (type), &info);
diff --git a/gcc/gimple-expr.cc b/gcc/gimple-expr.cc
index 96f9fc720afb..3b8726ded4d3 100644
--- a/gcc/gimple-expr.cc
+++ b/gcc/gimple-expr.cc
@@ -116,8 +116,7 @@ useless_type_conversion_p (tree outer_type, tree inner_type)
         body, we need to prevent changing BITINT_TYPE to INTEGER_TYPE
         of the same precision or vice versa when passed to functions,
         especially for varargs.  */
-      if ((TREE_CODE (inner_type) == BITINT_TYPE)
-         != (TREE_CODE (outer_type) == BITINT_TYPE))
+      if (BITINT_TYPE_P (inner_type) != BITINT_TYPE_P (outer_type))
        return false;
 
       /* We don't need to preserve changes in the types minimum or
diff --git a/gcc/gimple-fold.cc b/gcc/gimple-fold.cc
index a2f9de53855e..9048155e01e5 100644
--- a/gcc/gimple-fold.cc
+++ b/gcc/gimple-fold.cc
@@ -1485,7 +1485,7 @@ gimple_fold_builtin_memset (gimple_stmt_iterator *gsi, 
tree c, tree len)
 
   if ((!INTEGRAL_TYPE_P (etype)
        && !POINTER_TYPE_P (etype))
-      || TREE_CODE (etype) == BITINT_TYPE)
+      || BITINT_TYPE_P (etype))
     return false;
 
   if (! var_decl_component_p (var))
@@ -4749,6 +4749,10 @@ clear_padding_type_may_have_padding_p (tree type)
       return clear_padding_type_may_have_padding_p (TREE_TYPE (type));
     case REAL_TYPE:
       return clear_padding_real_needs_padding_p (type);
+    case ENUMERAL_TYPE:
+      if (BITINT_TYPE_P (type))
+       return clear_padding_bitint_needs_padding_p (type);
+      return false;
     case BITINT_TYPE:
       return clear_padding_bitint_needs_padding_p (type);
     default:
@@ -4809,6 +4813,10 @@ type_has_padding_at_level_p (tree type)
       return false;
     case REAL_TYPE:
       return clear_padding_real_needs_padding_p (type);
+    case ENUMERAL_TYPE:
+      if (BITINT_TYPE_P (type))
+       return clear_padding_bitint_needs_padding_p (type);
+      return false;
     case BITINT_TYPE:
       return clear_padding_bitint_needs_padding_p (type);
     default:
@@ -5057,6 +5065,7 @@ clear_padding_type (clear_padding_struct *buf, tree type,
       buf->size += sz;
       break;
     case BITINT_TYPE:
+    do_bitint:
       {
        struct bitint_info info;
        bool ok = targetm.c.bitint_type_info (TYPE_PRECISION (type), &info);
@@ -5109,6 +5118,10 @@ clear_padding_type (clear_padding_struct *buf, tree type,
          }
        break;
       }
+    case ENUMERAL_TYPE:
+      if (BITINT_TYPE_P (type))
+       goto do_bitint;
+      /* FALLTHRU */
     default:
       gcc_assert ((size_t) sz <= clear_padding_unit);
       if ((unsigned HOST_WIDE_INT) sz + buf->size > clear_padding_buf_size)
diff --git a/gcc/gimple-lower-bitint.cc b/gcc/gimple-lower-bitint.cc
index 7d8ca05f88d0..a33269b3ec2c 100644
--- a/gcc/gimple-lower-bitint.cc
+++ b/gcc/gimple-lower-bitint.cc
@@ -185,7 +185,7 @@ tree
 maybe_cast_middle_bitint (gimple_stmt_iterator *gsi, tree op, tree &type)
 {
   if (op == NULL_TREE
-      || TREE_CODE (TREE_TYPE (op)) != BITINT_TYPE
+      || !BITINT_TYPE_P (TREE_TYPE (op))
       || bitint_precision_kind (TREE_TYPE (op)) != bitint_prec_middle)
     return op;
 
@@ -244,8 +244,8 @@ mergeable_op (gimple *stmt)
        tree lhs_type = TREE_TYPE (gimple_assign_lhs (stmt));
        tree rhs_type = TREE_TYPE (gimple_assign_rhs1 (stmt));
        if (TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME
-           && TREE_CODE (lhs_type) == BITINT_TYPE
-           && TREE_CODE (rhs_type) == BITINT_TYPE
+           && BITINT_TYPE_P (lhs_type)
+           && BITINT_TYPE_P (rhs_type)
            && bitint_precision_kind (lhs_type) >= bitint_prec_large
            && bitint_precision_kind (rhs_type) >= bitint_prec_large
            && (CEIL (TYPE_PRECISION (lhs_type), limb_prec)
@@ -302,7 +302,7 @@ optimizable_arith_overflow (gimple *stmt)
   if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs))
     return 0;
   tree type = is_ubsan ? TREE_TYPE (lhs) : TREE_TYPE (TREE_TYPE (lhs));
-  if (TREE_CODE (type) != BITINT_TYPE
+  if (!BITINT_TYPE_P (type)
       || bitint_precision_kind (type) < bitint_prec_large)
     return 0;
 
@@ -356,7 +356,7 @@ optimizable_arith_overflow (gimple *stmt)
 
          lhs2 = gimple_assign_lhs (use_stmt);
          if (!INTEGRAL_TYPE_P (TREE_TYPE (lhs2))
-             || TREE_CODE (TREE_TYPE (lhs2)) == BITINT_TYPE)
+             || BITINT_TYPE_P (TREE_TYPE (lhs2)))
            return 0;
          cast = use_stmt;
        }
@@ -415,7 +415,7 @@ comparison_op (gimple *stmt, tree *pop1, tree *pop2)
   if (TREE_CODE_CLASS (code) != tcc_comparison)
     return ERROR_MARK;
   tree type = TREE_TYPE (op1);
-  if (TREE_CODE (type) != BITINT_TYPE
+  if (!BITINT_TYPE_P (type)
       || bitint_precision_kind (type) < bitint_prec_large)
     return ERROR_MARK;
   if (pop1)
@@ -1369,8 +1369,8 @@ bitint_large_huge::handle_cast (tree lhs_type, tree rhs1, 
tree idx)
   tree rhs_type = TREE_TYPE (rhs1);
   gimple *g;
   if ((TREE_CODE (rhs1) == SSA_NAME || TREE_CODE (rhs1) == INTEGER_CST)
-      && TREE_CODE (lhs_type) == BITINT_TYPE
-      && TREE_CODE (rhs_type) == BITINT_TYPE
+      && BITINT_TYPE_P (lhs_type)
+      && BITINT_TYPE_P (rhs_type)
       && bitint_precision_kind (lhs_type) >= bitint_prec_large
       && bitint_precision_kind (rhs_type) >= bitint_prec_large)
     {
@@ -1737,7 +1737,7 @@ bitint_large_huge::handle_cast (tree lhs_type, tree rhs1, 
tree idx)
          return t;
        }
     }
-  else if (TREE_CODE (lhs_type) == BITINT_TYPE
+  else if (BITINT_TYPE_P (lhs_type)
           && bitint_precision_kind (lhs_type) >= bitint_prec_large
           && INTEGRAL_TYPE_P (rhs_type))
     {
@@ -1755,7 +1755,7 @@ bitint_large_huge::handle_cast (tree lhs_type, tree rhs1, 
tree idx)
            m_gsi = gsi_after_labels (gsi_bb (m_gsi));
          else
            gsi_next (&m_gsi);
-         if (TREE_CODE (rhs_type) == BITINT_TYPE
+         if (BITINT_TYPE_P (rhs_type)
              && bitint_precision_kind (rhs_type) == bitint_prec_middle)
            {
              tree type = NULL_TREE;
@@ -2424,7 +2424,7 @@ bitint_large_huge::handle_operand_addr (tree op, gimple 
*stmt,
   location_t loc_save = m_loc;
   tree ret = NULL_TREE;
   int precs = 0;
-  if ((TREE_CODE (TREE_TYPE (op)) != BITINT_TYPE
+  if ((!BITINT_TYPE_P (TREE_TYPE (op))
        || bitint_precision_kind (TREE_TYPE (op)) < bitint_prec_large)
       && TREE_CODE (op) != INTEGER_CST)
     {
@@ -2432,7 +2432,7 @@ bitint_large_huge::handle_operand_addr (tree op, gimple 
*stmt,
       *prec = range_to_prec (op, stmt);
       bitint_prec_kind kind = bitint_prec_small;
       gcc_assert (INTEGRAL_TYPE_P (TREE_TYPE (op)));
-      if (TREE_CODE (TREE_TYPE (op)) == BITINT_TYPE)
+      if (BITINT_TYPE_P (TREE_TYPE (op)))
        kind = bitint_precision_kind (TREE_TYPE (op));
       if (kind == bitint_prec_middle)
        {
@@ -2542,7 +2542,7 @@ bitint_large_huge::handle_operand_addr (tree op, gimple 
*stmt,
              if (TREE_CODE (rhs1) == VIEW_CONVERT_EXPR)
                rhs1 = TREE_OPERAND (rhs1, 0);
              gcc_assert (INTEGRAL_TYPE_P (TREE_TYPE (rhs1)));
-             if (TREE_CODE (TREE_TYPE (rhs1)) == BITINT_TYPE)
+             if (BITINT_TYPE_P (TREE_TYPE (rhs1)))
                kind = bitint_precision_kind (TREE_TYPE (rhs1));
              if (kind >= bitint_prec_large)
                {
@@ -2625,12 +2625,12 @@ bitint_large_huge::handle_operand_addr (tree op, gimple 
*stmt,
       if (mp == 0)
        mp = 1;
       if (mp >= (unsigned) TYPE_PRECISION (TREE_TYPE (op))
-         && (TREE_CODE (TREE_TYPE (op)) == BITINT_TYPE
+         && (BITINT_TYPE_P (TREE_TYPE (op))
              || TYPE_PRECISION (TREE_TYPE (op)) <= limb_prec))
        type = TREE_TYPE (op);
       else
        type = build_bitint_type (mp, 1);
-      if (TREE_CODE (type) != BITINT_TYPE
+      if (!BITINT_TYPE_P (type)
          || bitint_precision_kind (type) == bitint_prec_small)
        {
          if (TYPE_PRECISION (type) <= limb_prec)
@@ -2730,7 +2730,7 @@ bitint_large_huge::lower_mergeable_stmt (gimple *stmt, 
tree_code &cmp_code,
     type = TREE_TYPE (cmp_op1);
   else
     type = TREE_TYPE (gimple_assign_lhs (stmt));
-  gcc_assert (TREE_CODE (type) == BITINT_TYPE);
+  gcc_assert (BITINT_TYPE_P (type));
   bitint_prec_kind kind = bitint_precision_kind (type);
   gcc_assert (kind >= bitint_prec_large);
   gimple *g;
@@ -2738,7 +2738,7 @@ bitint_large_huge::lower_mergeable_stmt (gimple *stmt, 
tree_code &cmp_code,
   tree rhs1, lhs_type = lhs ? TREE_TYPE (lhs) : NULL_TREE;
   if (lhs
       && TREE_CODE (lhs) == SSA_NAME
-      && TREE_CODE (TREE_TYPE (lhs)) == BITINT_TYPE
+      && BITINT_TYPE_P (TREE_TYPE (lhs))
       && bitint_precision_kind (TREE_TYPE (lhs)) >= bitint_prec_large)
     {
       int p = var_to_partition (m_map, lhs);
@@ -2836,7 +2836,7 @@ bitint_large_huge::lower_mergeable_stmt (gimple *stmt, 
tree_code &cmp_code,
       if (TREE_CODE (rhs1) == SSA_NAME
          && (m_names == NULL
              || !bitmap_bit_p (m_names, SSA_NAME_VERSION (rhs1)))
-         && TREE_CODE (TREE_TYPE (rhs1)) == BITINT_TYPE
+         && BITINT_TYPE_P (TREE_TYPE (rhs1))
          && bitint_precision_kind (TREE_TYPE (rhs1)) >= bitint_prec_large
          && (CEIL ((unsigned) TYPE_PRECISION (TREE_TYPE (rhs1)),
                    limb_prec) < CEIL (prec, limb_prec)
@@ -3372,7 +3372,7 @@ bitint_large_huge::lower_comparison_stmt (gimple *stmt, 
tree_code &cmp_code,
                                          tree cmp_op1, tree cmp_op2)
 {
   tree type = TREE_TYPE (cmp_op1);
-  gcc_assert (TREE_CODE (type) == BITINT_TYPE);
+  gcc_assert (BITINT_TYPE_P (type));
   bitint_prec_kind kind = bitint_precision_kind (type);
   gcc_assert (kind >= bitint_prec_large);
   gimple *g;
@@ -3506,7 +3506,7 @@ bitint_large_huge::lower_shift_stmt (tree obj, gimple 
*stmt)
   tree_code rhs_code = gimple_assign_rhs_code (stmt);
   tree type = TREE_TYPE (rhs1);
   gimple *final_stmt = gsi_stmt (m_gsi);
-  gcc_assert (TREE_CODE (type) == BITINT_TYPE
+  gcc_assert (BITINT_TYPE_P (type)
              && bitint_precision_kind (type) >= bitint_prec_large);
   int prec = TYPE_PRECISION (type);
   tree n = gimple_assign_rhs2 (stmt), n1, n2, n3, n4;
@@ -4082,7 +4082,7 @@ bitint_large_huge::lower_muldiv_stmt (tree obj, gimple 
*stmt)
   tree lhs = gimple_assign_lhs (stmt);
   tree_code rhs_code = gimple_assign_rhs_code (stmt);
   tree type = TREE_TYPE (rhs1);
-  gcc_assert (TREE_CODE (type) == BITINT_TYPE
+  gcc_assert (BITINT_TYPE_P (type)
              && bitint_precision_kind (type) >= bitint_prec_large);
   int prec = TYPE_PRECISION (type), prec1, prec2;
   bool ext_ms_limb = false;
@@ -4426,7 +4426,7 @@ bitint_large_huge::finish_arith_overflow (tree var, tree 
obj, tree type,
   gimple *g;
 
   if (obj == NULL_TREE
-      && (TREE_CODE (type) != BITINT_TYPE
+      && (!BITINT_TYPE_P (type)
          || bitint_precision_kind (type) < bitint_prec_large))
     {
       /* Add support for 3 or more limbs filled in from normal integral
@@ -4435,7 +4435,7 @@ bitint_large_huge::finish_arith_overflow (tree var, tree 
obj, tree type,
         be needed.  */
       gcc_assert (TYPE_PRECISION (type) <= 2 * limb_prec);
       tree lhs_type = type;
-      if (TREE_CODE (type) == BITINT_TYPE
+      if (BITINT_TYPE_P (type)
          && bitint_precision_kind (type) == bitint_prec_middle)
        lhs_type = build_nonstandard_integer_type (TYPE_PRECISION (type),
                                                   TYPE_UNSIGNED (type));
@@ -4781,7 +4781,7 @@ bitint_large_huge::lower_addsub_overflow (tree obj, 
gimple *stmt)
   tree var = NULL_TREE;
   tree orig_obj = obj;
   if (obj == NULL_TREE
-      && TREE_CODE (type) == BITINT_TYPE
+      && BITINT_TYPE_P (type)
       && bitint_precision_kind (type) >= bitint_prec_large
       && m_names
       && bitmap_bit_p (m_names, SSA_NAME_VERSION (lhs)))
@@ -4792,7 +4792,7 @@ bitint_large_huge::lower_addsub_overflow (tree obj, 
gimple *stmt)
       if (TREE_TYPE (lhs) == type)
        orig_obj = obj;
     }
-  if (TREE_CODE (type) != BITINT_TYPE
+  if (!BITINT_TYPE_P (type)
       || bitint_precision_kind (type) < bitint_prec_large)
     {
       unsigned HOST_WIDE_INT nelts = CEIL (prec, limb_prec);
@@ -5289,7 +5289,7 @@ bitint_large_huge::lower_mul_overflow (tree obj, gimple 
*stmt)
   tree orig_obj = obj;
   bool force_var = false;
   if (obj == NULL_TREE
-      && TREE_CODE (type) == BITINT_TYPE
+      && BITINT_TYPE_P (type)
       && bitint_precision_kind (type) >= bitint_prec_large
       && m_names
       && bitmap_bit_p (m_names, SSA_NAME_VERSION (lhs)))
@@ -5316,7 +5316,7 @@ bitint_large_huge::lower_mul_overflow (tree obj, gimple 
*stmt)
     }
   if (obj == NULL_TREE
       || force_var
-      || TREE_CODE (type) != BITINT_TYPE
+      || !BITINT_TYPE_P (type)
       || bitint_precision_kind (type) < bitint_prec_large
       || prec2 > (CEIL (prec, limb_prec) * limb_prec * (orig_obj ? 1 : 2)))
     {
@@ -5592,7 +5592,7 @@ bitint_large_huge::lower_bit_query (gimple *stmt)
       return;
     }
   tree type = TREE_TYPE (arg0);
-  gcc_assert (TREE_CODE (type) == BITINT_TYPE);
+  gcc_assert (BITINT_TYPE_P (type));
   bitint_prec_kind kind = bitint_precision_kind (type);
   gcc_assert (kind >= bitint_prec_large);
   enum internal_fn ifn = gimple_call_internal_fn (stmt);
@@ -6143,7 +6143,7 @@ bitint_large_huge::lower_call (tree obj, gimple *stmt)
     {
       tree arg = gimple_call_arg (stmt, i);
       if (TREE_CODE (arg) != SSA_NAME
-         || TREE_CODE (TREE_TYPE (arg)) != BITINT_TYPE
+         || !BITINT_TYPE_P (TREE_TYPE (arg))
          || bitint_precision_kind (TREE_TYPE (arg)) <= bitint_prec_middle)
        continue;
       if (SSA_NAME_IS_DEFAULT_DEF (arg)
@@ -6176,7 +6176,7 @@ bitint_large_huge::lower_call (tree obj, gimple *stmt)
   tree lhs = gimple_call_lhs (stmt);
   if (lhs
       && TREE_CODE (lhs) == SSA_NAME
-      && TREE_CODE (TREE_TYPE (lhs)) == BITINT_TYPE
+      && BITINT_TYPE_P (TREE_TYPE (lhs))
       && bitint_precision_kind (TREE_TYPE (lhs)) >= bitint_prec_large)
     {
       int p = var_to_partition (m_map, lhs);
@@ -6204,7 +6204,7 @@ bitint_large_huge::lower_asm (gimple *stmt)
       tree t = gimple_asm_output_op (g, i);
       tree s = TREE_VALUE (t);
       if (TREE_CODE (s) == SSA_NAME
-         && TREE_CODE (TREE_TYPE (s)) == BITINT_TYPE
+         && BITINT_TYPE_P (TREE_TYPE (s))
          && bitint_precision_kind (TREE_TYPE (s)) >= bitint_prec_large)
        {
          int part = var_to_partition (m_map, s);
@@ -6217,7 +6217,7 @@ bitint_large_huge::lower_asm (gimple *stmt)
       tree t = gimple_asm_input_op (g, i);
       tree s = TREE_VALUE (t);
       if (TREE_CODE (s) == SSA_NAME
-         && TREE_CODE (TREE_TYPE (s)) == BITINT_TYPE
+         && BITINT_TYPE_P (TREE_TYPE (s))
          && bitint_precision_kind (TREE_TYPE (s)) >= bitint_prec_large)
        {
          if (SSA_NAME_IS_DEFAULT_DEF (s)
@@ -6280,11 +6280,11 @@ bitint_large_huge::lower_stmt (gimple *stmt)
       tree rhs1 = gimple_assign_rhs1 (stmt);
       if (TREE_CODE (rhs1) == VIEW_CONVERT_EXPR)
        rhs1 = TREE_OPERAND (rhs1, 0);
-      if (TREE_CODE (TREE_TYPE (lhs)) == BITINT_TYPE
+      if (BITINT_TYPE_P (TREE_TYPE (lhs))
          && bitint_precision_kind (TREE_TYPE (lhs)) >= bitint_prec_large
          && INTEGRAL_TYPE_P (TREE_TYPE (rhs1)))
        mergeable_cast_p = true;
-      else if (TREE_CODE (TREE_TYPE (rhs1)) == BITINT_TYPE
+      else if (BITINT_TYPE_P (TREE_TYPE (rhs1))
               && bitint_precision_kind (TREE_TYPE (rhs1)) >= bitint_prec_large
               && (INTEGRAL_TYPE_P (TREE_TYPE (lhs))
                   || POINTER_TYPE_P (TREE_TYPE (lhs))
@@ -6368,7 +6368,7 @@ bitint_large_huge::lower_stmt (gimple *stmt)
                }
            }
        }
-      else if (TREE_CODE (TREE_TYPE (lhs)) == BITINT_TYPE
+      else if (BITINT_TYPE_P (TREE_TYPE (lhs))
               && bitint_precision_kind (TREE_TYPE (lhs)) >= bitint_prec_large
               && !INTEGRAL_TYPE_P (TREE_TYPE (rhs1))
               && !POINTER_TYPE_P (TREE_TYPE (rhs1))
@@ -6480,7 +6480,7 @@ bitint_large_huge::lower_stmt (gimple *stmt)
                              boolean_false_node);
          gimple_assign_set_rhs1 (stmt, cond);
          lhs = gimple_assign_lhs (stmt);
-         gcc_assert (TREE_CODE (TREE_TYPE (lhs)) != BITINT_TYPE
+         gcc_assert (!BITINT_TYPE_P (TREE_TYPE (lhs))
                      || (bitint_precision_kind (TREE_TYPE (lhs))
                          <= bitint_prec_middle));
          update_stmt (stmt);
@@ -6501,7 +6501,7 @@ bitint_large_huge::lower_stmt (gimple *stmt)
         be needed.  */
       gcc_assert (TYPE_PRECISION (lhs_type) <= 2 * limb_prec);
       gimple *g;
-      if ((TREE_CODE (lhs_type) == BITINT_TYPE
+      if ((BITINT_TYPE_P (lhs_type)
           && bitint_precision_kind (lhs_type) == bitint_prec_middle)
          || POINTER_TYPE_P (lhs_type))
        lhs_type = build_nonstandard_integer_type (TYPE_PRECISION (lhs_type),
@@ -6651,7 +6651,7 @@ bitint_dom_walker::before_dom_children (basic_block bb)
       tree lhs = gimple_get_lhs (stmt);
       if (lhs
          && TREE_CODE (lhs) == SSA_NAME
-         && TREE_CODE (TREE_TYPE (lhs)) == BITINT_TYPE
+         && BITINT_TYPE_P (TREE_TYPE (lhs))
          && bitint_precision_kind (TREE_TYPE (lhs)) >= bitint_prec_large
          && !bitmap_bit_p (m_names, SSA_NAME_VERSION (lhs)))
        /* If lhs of stmt is large/huge _BitInt SSA_NAME not in m_names,
@@ -6666,7 +6666,7 @@ bitint_dom_walker::before_dom_children (basic_block bb)
       FOR_EACH_SSA_USE_OPERAND (use_p, stmt, oi, SSA_OP_USE)
        {
          tree s = USE_FROM_PTR (use_p);
-         if (TREE_CODE (TREE_TYPE (s)) == BITINT_TYPE
+         if (BITINT_TYPE_P (TREE_TYPE (s))
              && bitint_precision_kind (TREE_TYPE (s)) >= bitint_prec_large)
            worklist.safe_push (s);
        }
@@ -6683,7 +6683,7 @@ bitint_dom_walker::before_dom_children (basic_block bb)
              FOR_EACH_SSA_USE_OPERAND (use_p, g, oi, SSA_OP_USE)
                {
                  tree s2 = USE_FROM_PTR (use_p);
-                 if (TREE_CODE (TREE_TYPE (s2)) == BITINT_TYPE
+                 if (BITINT_TYPE_P (TREE_TYPE (s2))
                      && (bitint_precision_kind (TREE_TYPE (s2))
                          >= bitint_prec_large))
                    worklist.safe_push (s2);
@@ -6778,7 +6778,7 @@ build_bitint_stmt_ssa_conflicts (gimple *stmt, live_track 
*live,
          tree type = TREE_TYPE (lhs);
          if (TREE_CODE (type) == COMPLEX_TYPE)
            type = TREE_TYPE (type);
-         if (TREE_CODE (type) == BITINT_TYPE
+         if (BITINT_TYPE_P (type)
              && bitint_precision_kind (type) >= bitint_prec_large)
            {
              if (!bitmap_bit_p (names, SSA_NAME_VERSION (lhs)))
@@ -6856,7 +6856,7 @@ build_bitint_stmt_ssa_conflicts (gimple *stmt, live_track 
*live,
       if (TREE_CODE (ltype) == COMPLEX_TYPE)
        muldiv_p = true;
       else if (TREE_CODE (lhs) == SSA_NAME
-              && TREE_CODE (ltype) == BITINT_TYPE
+              && BITINT_TYPE_P (ltype)
               && bitint_precision_kind (ltype) >= bitint_prec_large)
        {
          unsigned lnelts = CEIL (TYPE_PRECISION (ltype), limb_prec);
@@ -6865,7 +6865,7 @@ build_bitint_stmt_ssa_conflicts (gimple *stmt, live_track 
*live,
              tree type = TREE_TYPE (var);
              if (TREE_CODE (type) == COMPLEX_TYPE)
                type = TREE_TYPE (type);
-             if (TREE_CODE (type) == BITINT_TYPE
+             if (BITINT_TYPE_P (type)
                  && bitint_precision_kind (type) >= bitint_prec_large)
                {
                  if (bitmap_bit_p (names, SSA_NAME_VERSION (var)))
@@ -6892,7 +6892,7 @@ build_bitint_stmt_ssa_conflicts (gimple *stmt, live_track 
*live,
                  tree type = TREE_TYPE (var);
                  if (TREE_CODE (type) == COMPLEX_TYPE)
                    type = TREE_TYPE (type);
-                 if (TREE_CODE (type) == BITINT_TYPE
+                 if (BITINT_TYPE_P (type)
                      && bitint_precision_kind (type) >= bitint_prec_large)
                    {
                      if (bitmap_bit_p (names, SSA_NAME_VERSION (var)))
@@ -6943,7 +6943,7 @@ build_bitint_stmt_ssa_conflicts (gimple *stmt, live_track 
*live,
       tree type = TREE_TYPE (var);
       if (TREE_CODE (type) == COMPLEX_TYPE)
        type = TREE_TYPE (type);
-      if (TREE_CODE (type) == BITINT_TYPE
+      if (BITINT_TYPE_P (type)
          && bitint_precision_kind (type) >= bitint_prec_large)
        {
          if (bitmap_bit_p (names, SSA_NAME_VERSION (var)))
@@ -6961,7 +6961,7 @@ build_bitint_stmt_ssa_conflicts (gimple *stmt, live_track 
*live,
          tree type = TREE_TYPE (var);
          if (TREE_CODE (type) == COMPLEX_TYPE)
            type = TREE_TYPE (type);
-         if (TREE_CODE (type) == BITINT_TYPE
+         if (BITINT_TYPE_P (type)
              && bitint_precision_kind (type) >= bitint_prec_large)
            {
              if (bitmap_bit_p (names, SSA_NAME_VERSION (var)))
@@ -6994,7 +6994,7 @@ arith_overflow_arg_kind (gimple *stmt)
          {
            tree a = gimple_call_arg (stmt, i);
            if (TREE_CODE (a) == INTEGER_CST
-               && TREE_CODE (TREE_TYPE (a)) == BITINT_TYPE)
+               && BITINT_TYPE_P (TREE_TYPE (a)))
              {
                bitint_prec_kind kind = bitint_precision_kind (TREE_TYPE (a));
                ret = MAX (ret, kind);
@@ -7030,7 +7030,7 @@ gimple_lower_bitint (void)
            break;
          type = TREE_TYPE (type);
        }
-      if (TREE_CODE (type) == BITINT_TYPE
+      if (BITINT_TYPE_P (type)
          && bitint_precision_kind (type) != bitint_prec_small)
        break;
       /* We need to also rewrite stores of large/huge _BitInt INTEGER_CSTs
@@ -7041,7 +7041,7 @@ gimple_lower_bitint (void)
          if (is_gimple_assign (g) && gimple_store_p (g))
            {
              tree t = gimple_assign_rhs1 (g);
-             if (TREE_CODE (TREE_TYPE (t)) == BITINT_TYPE
+             if (BITINT_TYPE_P (TREE_TYPE (t))
                  && (bitint_precision_kind (TREE_TYPE (t))
                      >= bitint_prec_large))
                break;
@@ -7056,7 +7056,7 @@ gimple_lower_bitint (void)
            {
              tree t = gimple_assign_rhs1 (g);
              if (TREE_CODE (t) == INTEGER_CST
-                 && TREE_CODE (TREE_TYPE (t)) == BITINT_TYPE
+                 && BITINT_TYPE_P (TREE_TYPE (t))
                  && (bitint_precision_kind (TREE_TYPE (t))
                      != bitint_prec_small))
                break;
@@ -7073,7 +7073,7 @@ gimple_lower_bitint (void)
       if (gswitch *swtch = safe_dyn_cast <gswitch *> (*gsi_last_bb (bb)))
        {
          tree idx = gimple_switch_index (swtch);
-         if (TREE_CODE (TREE_TYPE (idx)) != BITINT_TYPE
+         if (!BITINT_TYPE_P (TREE_TYPE (idx))
              || bitint_precision_kind (TREE_TYPE (idx)) < bitint_prec_large)
            continue;
 
@@ -7130,7 +7130,7 @@ gimple_lower_bitint (void)
            has_large_huge = true;
          type = TREE_TYPE (type);
        }
-      if (TREE_CODE (type) == BITINT_TYPE
+      if (BITINT_TYPE_P (type)
          && bitint_precision_kind (type) >= bitint_prec_large)
        {
          if (first_large_huge == ~0U)
@@ -7339,7 +7339,7 @@ gimple_lower_bitint (void)
          if (is_gimple_assign (g) && gimple_store_p (g))
            {
              tree t = gimple_assign_rhs1 (g);
-             if (TREE_CODE (TREE_TYPE (t)) == BITINT_TYPE
+             if (BITINT_TYPE_P (TREE_TYPE (t))
                  && (bitint_precision_kind (TREE_TYPE (t))
                      >= bitint_prec_large))
                has_large_huge = true;
@@ -7354,7 +7354,7 @@ gimple_lower_bitint (void)
            {
              tree t = gimple_assign_rhs1 (g);
              if (TREE_CODE (t) == INTEGER_CST
-                 && TREE_CODE (TREE_TYPE (t)) == BITINT_TYPE
+                 && BITINT_TYPE_P (TREE_TYPE (t))
                  && (bitint_precision_kind (TREE_TYPE (t))
                      >= bitint_prec_large))
                has_large_huge = true;
@@ -7369,7 +7369,7 @@ gimple_lower_bitint (void)
       tree type = TREE_TYPE (s);
       if (TREE_CODE (type) == COMPLEX_TYPE)
        type = TREE_TYPE (type);
-      if (TREE_CODE (type) == BITINT_TYPE
+      if (BITINT_TYPE_P (type)
          && bitint_precision_kind (type) >= bitint_prec_large)
        {
          use_operand_p use_p;
@@ -7452,7 +7452,7 @@ gimple_lower_bitint (void)
                              goto force_name;
                            /* FALLTHRU */
                          case MULT_EXPR:
-                           if (TREE_CODE (TREE_TYPE (rhs1)) != BITINT_TYPE
+                           if (!BITINT_TYPE_P (TREE_TYPE (rhs1))
                                || (bitint_precision_kind (TREE_TYPE (rhs1))
                                    < bitint_prec_large))
                              continue;
@@ -7485,7 +7485,7 @@ gimple_lower_bitint (void)
                          default:
                            break;
                        }
-                     if (TREE_CODE (TREE_TYPE (rhs1)) != BITINT_TYPE
+                     if (!BITINT_TYPE_P (TREE_TYPE (rhs1))
                          || (bitint_precision_kind (TREE_TYPE (rhs1))
                              < bitint_prec_large))
                        continue;
@@ -7519,7 +7519,7 @@ gimple_lower_bitint (void)
                             not mergeable.  */
                          tree rhs2
                            = gimple_assign_rhs1 (SSA_NAME_DEF_STMT (rhs1));
-                         if (TREE_CODE (TREE_TYPE (rhs2)) == BITINT_TYPE
+                         if (BITINT_TYPE_P (TREE_TYPE (rhs2))
                              && (TYPE_PRECISION (TREE_TYPE (rhs1))
                                  == TYPE_PRECISION (TREE_TYPE (rhs2))))
                            {
@@ -7718,7 +7718,7 @@ gimple_lower_bitint (void)
          if (is_gimple_assign (g) && gimple_store_p (g))
            {
              tree t = gimple_assign_rhs1 (g);
-             if (TREE_CODE (TREE_TYPE (t)) == BITINT_TYPE
+             if (BITINT_TYPE_P (TREE_TYPE (t))
                  && bitint_precision_kind (TREE_TYPE (t)) >= bitint_prec_large)
                has_large_huge = true;
            }
@@ -7822,7 +7822,7 @@ gimple_lower_bitint (void)
          bitint_prec_kind kind = bitint_prec_small;
          tree t;
          FOR_EACH_SSA_TREE_OPERAND (t, stmt, iter, SSA_OP_ALL_OPERANDS)
-           if (TREE_CODE (TREE_TYPE (t)) == BITINT_TYPE)
+           if (BITINT_TYPE_P (TREE_TYPE (t)))
              {
                bitint_prec_kind this_kind
                  = bitint_precision_kind (TREE_TYPE (t));
@@ -7831,7 +7831,7 @@ gimple_lower_bitint (void)
          if (is_gimple_assign (stmt) && gimple_store_p (stmt))
            {
              t = gimple_assign_rhs1 (stmt);
-             if (TREE_CODE (TREE_TYPE (t)) == BITINT_TYPE)
+             if (BITINT_TYPE_P (TREE_TYPE (t)))
                {
                  bitint_prec_kind this_kind
                    = bitint_precision_kind (TREE_TYPE (t));
@@ -7842,7 +7842,7 @@ gimple_lower_bitint (void)
              && gimple_assign_rhs_code (stmt) == FLOAT_EXPR)
            {
              t = gimple_assign_rhs1 (stmt);
-             if (TREE_CODE (TREE_TYPE (t)) == BITINT_TYPE
+             if (BITINT_TYPE_P (TREE_TYPE (t))
                  && TREE_CODE (t) == INTEGER_CST)
                {
                  bitint_prec_kind this_kind
@@ -7857,7 +7857,7 @@ gimple_lower_bitint (void)
                {
                  bitint_prec_kind this_kind = arith_overflow_arg_kind (stmt);
                  kind = MAX (kind, this_kind);
-                 if (TREE_CODE (TREE_TYPE (TREE_TYPE (t))) == BITINT_TYPE)
+                 if (BITINT_TYPE_P (TREE_TYPE (TREE_TYPE (t))))
                    {
                      this_kind
                        = bitint_precision_kind (TREE_TYPE (TREE_TYPE (t)));
@@ -7940,7 +7940,7 @@ gimple_lower_bitint (void)
                      }
                  }
              if (tree lhs = gimple_get_lhs (stmt))
-               if (TREE_CODE (TREE_TYPE (lhs)) == BITINT_TYPE
+               if (BITINT_TYPE_P (TREE_TYPE (lhs))
                    && (bitint_precision_kind (TREE_TYPE (lhs))
                        == bitint_prec_middle))
                  {
@@ -7969,7 +7969,7 @@ gimple_lower_bitint (void)
                tree type = TREE_TYPE (lhs);
                if (TREE_CODE (type) == COMPLEX_TYPE)
                  type = TREE_TYPE (type);
-               if (TREE_CODE (type) == BITINT_TYPE
+               if (BITINT_TYPE_P (type)
                    && bitint_precision_kind (type) >= bitint_prec_large
                    && (large_huge.m_names == NULL
                        || !bitmap_bit_p (large_huge.m_names,
@@ -7986,7 +7986,7 @@ gimple_lower_bitint (void)
        {
          gphi *phi = gsi.phi ();
          tree lhs = gimple_phi_result (phi);
-         if (TREE_CODE (TREE_TYPE (lhs)) != BITINT_TYPE
+         if (!BITINT_TYPE_P (TREE_TYPE (lhs))
              || bitint_precision_kind (TREE_TYPE (lhs)) < bitint_prec_large)
            continue;
          int p1 = var_to_partition (large_huge.m_map, lhs);
@@ -8216,7 +8216,7 @@ gimple_lower_bitint (void)
          tree type = TREE_TYPE (s);
          if (TREE_CODE (type) == COMPLEX_TYPE)
            type = TREE_TYPE (type);
-         if (TREE_CODE (type) == BITINT_TYPE
+         if (BITINT_TYPE_P (type)
              && bitint_precision_kind (type) >= bitint_prec_large)
            {
              if (large_huge.m_preserved
diff --git a/gcc/gimple-match-exports.cc b/gcc/gimple-match-exports.cc
index 5fd1baba7a41..3e409adbc2db 100644
--- a/gcc/gimple-match-exports.cc
+++ b/gcc/gimple-match-exports.cc
@@ -269,7 +269,7 @@ build_call_internal (internal_fn fn, gimple_match_op 
*res_op)
              /* For these 6 builtins large/huge _BitInt operand is ok
                 before bitint lowering pass.  */
              if (res_op->num_ops >= 1
-                 && TREE_CODE (TREE_TYPE (res_op->ops[0])) == BITINT_TYPE
+                 && BITINT_TYPE_P (TREE_TYPE (res_op->ops[0]))
                  && (TYPE_PRECISION (TREE_TYPE (res_op->ops[0]))
                      > MAX_FIXED_MODE_SIZE)
                  && cfun
diff --git a/gcc/internal-fn.cc b/gcc/internal-fn.cc
index cad5c50d83d7..2aaf98f29380 100644
--- a/gcc/internal-fn.cc
+++ b/gcc/internal-fn.cc
@@ -1131,7 +1131,7 @@ static void
 expand_ubsan_result_store (tree lhs, rtx target, scalar_int_mode mode,
                           rtx res, rtx_code_label *do_error)
 {
-  if (TREE_CODE (TREE_TYPE (lhs)) == BITINT_TYPE
+  if (BITINT_TYPE_P (TREE_TYPE (lhs))
       && TYPE_PRECISION (TREE_TYPE (lhs)) < GET_MODE_PRECISION (mode))
     {
       int uns = TYPE_UNSIGNED (TREE_TYPE (lhs));
diff --git a/gcc/match.pd b/gcc/match.pd
index 8a2de136e7f1..45ffe39604eb 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -10253,7 +10253,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
        && TYPE_PRECISION (TREE_TYPE (@1)) > TYPE_PRECISION (TREE_TYPE (@0)))
    (with { combined_fn cfn = CFN_LAST;
           tree type0 = TREE_TYPE (@0);
-          if (TREE_CODE (type0) == BITINT_TYPE)
+          if (BITINT_TYPE_P (type0))
             {
               if (TYPE_PRECISION (type0) > MAX_FIXED_MODE_SIZE)
                 cfn = CFN_CTZ;
@@ -10393,7 +10393,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
        && TYPE_PRECISION (TREE_TYPE (@1)) > TYPE_PRECISION (TREE_TYPE (@0)))
    (with { combined_fn cfn = CFN_LAST;
           tree type0 = TREE_TYPE (@0);
-          if (TREE_CODE (type0) == BITINT_TYPE)
+          if (BITINT_TYPE_P (type0))
             {
               if (TYPE_PRECISION (type0) > MAX_FIXED_MODE_SIZE)
                 cfn = CFN_POPCOUNT;
@@ -10495,7 +10495,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
                - TYPE_PRECISION (TREE_TYPE (@0))) & 1) == 0))
    (with { combined_fn cfn = CFN_LAST;
           tree type0 = TREE_TYPE (@0);
-          if (TREE_CODE (type0) == BITINT_TYPE)
+          if (BITINT_TYPE_P (type0))
             {
               if (TYPE_PRECISION (type0) > MAX_FIXED_MODE_SIZE)
                 cfn = CFN_PARITY;
@@ -10551,7 +10551,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
   (cond (ne @0 integer_zerop@1) (func (convert?@3 @0)) INTEGER_CST@2)
   (with { int val;
          internal_fn ifn = IFN_LAST;
-         if (TREE_CODE (TREE_TYPE (@3)) == BITINT_TYPE)
+         if (BITINT_TYPE_P (TREE_TYPE (@3)))
            {
              if (tree_fits_shwi_p (@2))
                {
@@ -10575,7 +10575,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
  (cond (ne @0 integer_zerop@1) (IFN_CLZ (convert?@3 @0) INTEGER_CST@2) @2)
   (with { int val;
          internal_fn ifn = IFN_LAST;
-         if (TREE_CODE (TREE_TYPE (@3)) == BITINT_TYPE)
+         if (BITINT_TYPE_P (TREE_TYPE (@3)))
            ifn = IFN_CLZ;
          else if (direct_internal_fn_supported_p (IFN_CLZ, TREE_TYPE (@3),
                                                   OPTIMIZE_FOR_BOTH))
@@ -10590,7 +10590,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
   (cond (ne @0 integer_zerop@1) (func (convert?@3 @0)) INTEGER_CST@2)
   (with { int val;
          internal_fn ifn = IFN_LAST;
-         if (TREE_CODE (TREE_TYPE (@3)) == BITINT_TYPE)
+         if (BITINT_TYPE_P (TREE_TYPE (@3)))
            {
              if (tree_fits_shwi_p (@2))
                {
@@ -10614,7 +10614,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
  (cond (ne @0 integer_zerop@1) (IFN_CTZ (convert?@3 @0) INTEGER_CST@2) @2)
   (with { int val;
          internal_fn ifn = IFN_LAST;
-         if (TREE_CODE (TREE_TYPE (@3)) == BITINT_TYPE)
+         if (BITINT_TYPE_P (TREE_TYPE (@3)))
            ifn = IFN_CTZ;
          else if (direct_internal_fn_supported_p (IFN_CTZ, TREE_TYPE (@3),
                                                   OPTIMIZE_FOR_BOTH))
@@ -10952,7 +10952,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
        && TYPE_PRECISION (TREE_TYPE (@1)) > TYPE_PRECISION (TREE_TYPE (@0)))
    (with { combined_fn cfn = CFN_LAST;
           tree type0 = TREE_TYPE (@0);
-          if (TREE_CODE (type0) == BITINT_TYPE)
+          if (BITINT_TYPE_P (type0))
             {
               if (TYPE_PRECISION (type0) > MAX_FIXED_MODE_SIZE)
                 cfn = CFN_FFS;
diff --git a/gcc/stor-layout.cc b/gcc/stor-layout.cc
index 796fc8199213..8f6b68e4a41a 100644
--- a/gcc/stor-layout.cc
+++ b/gcc/stor-layout.cc
@@ -2180,7 +2180,7 @@ finish_bitfield_representative (tree repr, tree field)
       || GET_MODE_BITSIZE (mode) > maxbitsize
       || GET_MODE_BITSIZE (mode) > MAX_FIXED_MODE_SIZE)
     {
-      if (TREE_CODE (TREE_TYPE (field)) == BITINT_TYPE)
+      if (BITINT_TYPE_P (TREE_TYPE (field)))
        {
          struct bitint_info info;
          unsigned prec = TYPE_PRECISION (TREE_TYPE (field));
@@ -2459,15 +2459,19 @@ layout_type (tree type)
     case BOOLEAN_TYPE:
     case INTEGER_TYPE:
     case ENUMERAL_TYPE:
-      {
-       scalar_int_mode mode
-         = smallest_int_mode_for_size (TYPE_PRECISION (type)).require ();
-       SET_TYPE_MODE (type, mode);
-       TYPE_SIZE (type) = bitsize_int (GET_MODE_BITSIZE (mode));
-       /* Don't set TYPE_PRECISION here, as it may be set by a bitfield.  */
-       TYPE_SIZE_UNIT (type) = size_int (GET_MODE_SIZE (mode));
-       break;
-      }
+      if (TREE_CODE (type) != ENUMERAL_TYPE
+         || TREE_TYPE (type) == NULL_TREE
+         || TREE_CODE (TREE_TYPE (type)) != BITINT_TYPE)
+       {
+         scalar_int_mode mode
+           = smallest_int_mode_for_size (TYPE_PRECISION (type)).require ();
+         SET_TYPE_MODE (type, mode);
+         TYPE_SIZE (type) = bitsize_int (GET_MODE_BITSIZE (mode));
+         /* Don't set TYPE_PRECISION here, as it may be set by a bitfield.  */
+         TYPE_SIZE_UNIT (type) = size_int (GET_MODE_SIZE (mode));
+         break;
+       }
+      /* FALLTHRU */
 
     case BITINT_TYPE:
       {
@@ -2558,7 +2562,7 @@ layout_type (tree type)
       TYPE_UNSIGNED (type) = TYPE_UNSIGNED (TREE_TYPE (type));
       if (TYPE_MODE (TREE_TYPE (type)) == BLKmode)
        {
-         gcc_checking_assert (TREE_CODE (TREE_TYPE (type)) == BITINT_TYPE);
+         gcc_checking_assert (BITINT_TYPE_P (TREE_TYPE (type)));
          SET_TYPE_MODE (type, BLKmode);
          TYPE_SIZE (type)
            = int_const_binop (MULT_EXPR, TYPE_SIZE (TREE_TYPE (type)),
diff --git a/gcc/testsuite/gcc.dg/bitint-133.c 
b/gcc/testsuite/gcc.dg/bitint-133.c
new file mode 100644
index 000000000000..6c4316ab3ee1
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/bitint-133.c
@@ -0,0 +1,45 @@
+/* C2Y N3705: bit-precise enum.  */
+/* { dg-do compile { target bitint } } */
+/* { dg-options "-std=c2y" } */
+
+#define expr_has_type(e, t) _Generic (e, default : 0, t : 1)
+
+#if __BITINT_MAXWIDTH__ >= 129
+enum A : unsigned _BitInt(3) { A0 = 0, A1 = 7 };
+enum B : unsigned _BitInt(67) { B0 = 0, B1 = 255 };
+enum C : _BitInt(4) { C0 = -8, C1 = 7 };
+enum D : signed _BitInt(129) { D0 = -61822874253726891040447382843909510144wb, 
D1 = 333265406300494622897688995893630121068wb };
+enum E : _BitInt(__BITINT_MAXWIDTH__) { E0 = -1, E1 = 1 };
+#endif
+
+int
+main ()
+{
+#if __BITINT_MAXWIDTH__ >= 129
+  enum A a = A0;
+  static_assert (expr_has_type (a, enum A));
+  static_assert (expr_has_type (+a, unsigned _BitInt(3)));
+  static_assert (expr_has_type (a + 0wb, unsigned _BitInt(3)));
+  static_assert (expr_has_type (a + a, unsigned _BitInt(3)));
+  enum B b = B0;
+  static_assert (expr_has_type (b, enum B));
+  static_assert (expr_has_type (+b, unsigned _BitInt(67)));
+  static_assert (expr_has_type (b + 0wb, unsigned _BitInt(67)));
+  static_assert (expr_has_type (b + b, unsigned _BitInt(67)));
+  enum C c = C0;
+  static_assert (expr_has_type (c, enum C));
+  static_assert (expr_has_type (+c, _BitInt(4)));
+  static_assert (expr_has_type (c + 0wb, _BitInt(4)));
+  static_assert (expr_has_type (c + c, _BitInt(4)));
+  enum D d = D0;
+  static_assert (expr_has_type (d, enum D));
+  static_assert (expr_has_type (+d, signed _BitInt(129)));
+  static_assert (expr_has_type (d + 0wb, signed _BitInt(129)));
+  static_assert (expr_has_type (d + d, signed _BitInt(129)));
+  enum E e = E0;
+  static_assert (expr_has_type (e, enum E));
+  static_assert (expr_has_type (+e, signed _BitInt(__BITINT_MAXWIDTH__)));
+  static_assert (expr_has_type (e + 0wb, signed _BitInt(__BITINT_MAXWIDTH__)));
+  static_assert (expr_has_type (e + e, signed _BitInt(__BITINT_MAXWIDTH__)));
+#endif
+}
diff --git a/gcc/testsuite/gcc.dg/bitint-134.c 
b/gcc/testsuite/gcc.dg/bitint-134.c
new file mode 100644
index 000000000000..2fe8223b487b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/bitint-134.c
@@ -0,0 +1,42 @@
+/* C2Y N3705: bit-precise enum.  */
+/* { dg-do compile { target bitint } } */
+/* { dg-options "-std=c2y -Wall" } */
+
+enum E : unsigned _BitInt(1) { E1 = 0, E2 = 1 };
+#if __BITINT_MAXWITH__ >= 977
+enum F : _BitInt(976) { F1 = 1wb, F2 = 
300670311812537087458442068171242480163042891902139164259644606340061247186864125993521170465570759574674133007538491713720385607199458367860097993945704706551423706008678936855195978990583102392208311054636025123775462104768336555710742464822135886690195218326330916446029087852132145116425130wb,
 F3 = ~(unsigned _BitInt(975)) 0 };
+#endif
+
+int
+foo (enum E x)
+{
+  switch (x)
+    {
+    case E1:
+      return 1;
+    case E2:
+      return 2;
+    }
+}
+
+#if __BITINT_MAXWITH__ >= 977
+_BitInt(977)
+bar (enum F x)
+{
+  return x + 1;
+}
+
+enum F
+baz (enum F x)
+{
+  switch (x)
+    {
+    case F1:
+      return F2;
+    case F2:
+      return F3;
+    default:
+      return F1;
+    }
+}
+#endif
diff --git a/gcc/testsuite/gcc.dg/bitint-135.c 
b/gcc/testsuite/gcc.dg/bitint-135.c
new file mode 100644
index 000000000000..f31936f46f56
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/bitint-135.c
@@ -0,0 +1,47 @@
+/* C2Y N3705: bit-precise enum.  */
+/* { dg-do run { target bitint } } */
+/* { dg-options "-std=c2y" } */
+
+#if __BITINT_MAXWIDTH__ >= 257
+enum A : unsigned _BitInt(7) { A0 = 0, A1 = 7 };
+enum B : unsigned _BitInt(79) { B0 = 0, B1 = 255 };
+enum C : _BitInt(25) { C0 = -8, C1 = 7 };
+enum D : signed _BitInt(182) { D0 = -61822874253726891040447382843909510144wb, 
D1 = 333265406300494622897688995893630121068wb };
+enum E : _BitInt(__BITINT_MAXWIDTH__) { E0 = -1, E1 = 1 };
+struct F { enum A a : 3; enum B b : 67; enum C c : 4; enum D d : 129; enum E e 
: 257; } f;
+#endif
+
+[[gnu::noipa]] void
+foo ()
+{
+  if (f.a != A1
+      || f.b != B1
+      || f.c != C1
+      || f.d != D1
+      || f.e != E1)
+    __builtin_abort ();
+  f.a = A0;
+  f.b = B0;
+  f.c = C0;
+  f.d = D0;
+  f.e = E0;
+}
+
+int
+main ()
+{
+#if __BITINT_MAXWIDTH__ >= 257
+  f.a = A1;
+  f.b = B1;
+  f.c = C1;
+  f.d = D1;
+  f.e = E1;
+  foo ();
+  if (f.a != A0
+      || f.b != B0
+      || f.c != C0
+      || f.d != D0
+      || f.e != E0)
+    __builtin_abort ();
+#endif
+}
diff --git a/gcc/testsuite/gcc.dg/bitint-136.c 
b/gcc/testsuite/gcc.dg/bitint-136.c
new file mode 100644
index 000000000000..42be73b46fcf
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/bitint-136.c
@@ -0,0 +1,36 @@
+/* C2Y N3705: bit-precise enum.  */
+/* { dg-do compile { target bitint } } */
+/* { dg-options "-std=c2y" } */
+
+#define expr_has_type(e, t) _Generic (e, default : 0, t : 1)
+
+#if __BITINT_MAXWIDTH__ >= 257
+enum A : unsigned _BitInt(7) { A0 = 0, A1 = 7 };
+enum B : unsigned _BitInt(79) { B0 = 0, B1 = 255 };
+enum C : _BitInt(25) { C0 = -8, C1 = 7 };
+enum D : signed _BitInt(182) { D0 = -61822874253726891040447382843909510144wb, 
D1 = 333265406300494622897688995893630121068wb };
+enum E : _BitInt(__BITINT_MAXWIDTH__) { E0 = -1, E1 = 1 };
+struct F { enum A a : 3; enum B b : 67; enum C c : 4; enum D d : 129; enum E e 
: 257; } f;
+#endif
+
+int
+main ()
+{
+#if __BITINT_MAXWIDTH__ >= 257
+  static_assert (expr_has_type (+f.a, unsigned _BitInt(7)));
+  static_assert (expr_has_type (f.a + 0wb, unsigned _BitInt(7)));
+  static_assert (expr_has_type (f.a + f.a, unsigned _BitInt(7)));
+  static_assert (expr_has_type (+f.b, unsigned _BitInt(79)));
+  static_assert (expr_has_type (f.b + 0wb, unsigned _BitInt(79)));
+  static_assert (expr_has_type (f.b + f.b, unsigned _BitInt(79)));
+  static_assert (expr_has_type (+f.c, _BitInt(25)));
+  static_assert (expr_has_type (f.c + 0wb, _BitInt(25)));
+  static_assert (expr_has_type (f.c + f.c, _BitInt(25)));
+  static_assert (expr_has_type (+f.d, signed _BitInt(182)));
+  static_assert (expr_has_type (f.d + 0wb, signed _BitInt(182)));
+  static_assert (expr_has_type (f.d + f.d, signed _BitInt(182)));
+  static_assert (expr_has_type (+f.e, signed _BitInt(__BITINT_MAXWIDTH__)));
+  static_assert (expr_has_type (f.e + 0wb, signed 
_BitInt(__BITINT_MAXWIDTH__)));
+  static_assert (expr_has_type (f.e + f.e, signed 
_BitInt(__BITINT_MAXWIDTH__)));
+#endif
+}
diff --git a/gcc/testsuite/gcc.dg/torture/bitint-99.c 
b/gcc/testsuite/gcc.dg/torture/bitint-99.c
new file mode 100644
index 000000000000..1de275c066bd
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/bitint-99.c
@@ -0,0 +1,58 @@
+/* C2Y N3705: bit-precise enum.  */
+/* { dg-do compile { target bitint } } */
+/* { dg-options "-std=c2y -pedantic-errors" } */
+/* { dg-skip-if "" { ! run_expensive_tests }  { "*" } { "-O0" "-O2" } } */
+/* { dg-skip-if "" { ! run_expensive_tests } { "-flto" } { "" } } */
+
+#if __BITINT_MAXWIDTH__ >= 931
+enum A : unsigned _BitInt(931) { A0 = 0, A1 = ~(unsigned _BitInt(931)) 0 };
+
+[[gnu::noipa]] enum A
+foo (enum A x, enum A y)
+{
+  return x + y;
+}
+
+[[gnu::noipa]] enum A
+bar (enum A x, enum A y)
+{
+  return x * y;
+}
+
+[[gnu::noipa]] enum A
+baz (enum A x, int y)
+{
+  return x << y;
+}
+
+[[gnu::noipa]] long double
+qux (enum A x)
+{
+  return x;
+}
+#endif
+
+int
+main ()
+{
+  if (foo 
(6311375123928035423950285815103134911823756068469611777446526212940235067784850613353497329740063593697085797242982576864482320954041469603405692898785705968909387515267461870959824498259469495351851027191417268686507795153960941899524534819776605247652440362840005231043955863251uwb,
+          
14387261967519759057764126008098292183127782109485750598911399497161011642298676488973745200653245797159693794534840726810049655774169609382090435748786710789342570033603954826553305901144008614628394445814741866666472834301004639140374682209505172315237277433772283979289285215192uwb)
+      != ((unsigned _BitInt(931)) 
6311375123928035423950285815103134911823756068469611777446526212940235067784850613353497329740063593697085797242982576864482320954041469603405692898785705968909387515267461870959824498259469495351851027191417268686507795153960941899524534819776605247652440362840005231043955863251uwb
+         + 
14387261967519759057764126008098292183127782109485750598911399497161011642298676488973745200653245797159693794534840726810049655774169609382090435748786710789342570033603954826553305901144008614628394445814741866666472834301004639140374682209505172315237277433772283979289285215192uwb)
+      || foo (42, 43) != 85
+      || bar 
(11450886075967129033052256159825006993789547814645317054307262295553183531582194402180689046449356587523973694466833975060817054401287265586817097051188432556072249366122506436985624261677676836219438960612585780057976181675859636764878183805546490277128899407974903051218414039906uwb,
+             
17319821836005877733927644950742811128616796074756636477991226488210814096671627534609545922744022960185648230703380956243036682725031141936390527207521613841001950058662947028886894999944938393683770058909115780447269611178311112868417694704349733151327800871414934360178286516220uwb)
+        != ((unsigned _BitInt(931)) 
11450886075967129033052256159825006993789547814645317054307262295553183531582194402180689046449356587523973694466833975060817054401287265586817097051188432556072249366122506436985624261677676836219438960612585780057976181675859636764878183805546490277128899407974903051218414039906uwb
+             * 
17319821836005877733927644950742811128616796074756636477991226488210814096671627534609545922744022960185648230703380956243036682725031141936390527207521613841001950058662947028886894999944938393683770058909115780447269611178311112868417694704349733151327800871414934360178286516220uwb)
+      || bar (42, 43) != (42 * 43)
+      || baz 
(1741243423058845609493717319573689670252835849747079409452709857940702982389080261485458577486556787796580475119344401810353389865747399915963686220476226766063058821552766983213692892185191052405922570241479839142610515539669844621168541758908874036250322040751021964408140728317uwb,
+             278)
+        != ((unsigned _BitInt(931)) 
1741243423058845609493717319573689670252835849747079409452709857940702982389080261485458577486556787796580475119344401810353389865747399915963686220476226766063058821552766983213692892185191052405922570241479839142610515539669844621168541758908874036250322040751021964408140728317uwb
+            << 278)
+#if __LDBL_MAX_19_EXP__ >= 240
+      || qux 
(1072109040180989940290225035254632830964130184664319348440549688998788uwb)
+        != (long double) 
1072109040180989940290225035254632830964130184664319348440549688998788uwb
+#endif
+      || false)
+    __builtin_abort ();
+}
diff --git a/gcc/tree-sra.cc b/gcc/tree-sra.cc
index fde4d558f0eb..fd82070e0147 100644
--- a/gcc/tree-sra.cc
+++ b/gcc/tree-sra.cc
@@ -968,8 +968,7 @@ create_access (tree expr, gimple *stmt, bool write)
       disqualify_candidate (base, "Encountered an access beyond the base.");
       return NULL;
     }
-  if (TREE_CODE (TREE_TYPE (expr)) == BITINT_TYPE
-      && size > WIDE_INT_MAX_PRECISION - 1)
+  if (BITINT_TYPE_P (TREE_TYPE (expr)) && size > WIDE_INT_MAX_PRECISION - 1)
     {
       disqualify_candidate (base, "Encountered too large _BitInt access.");
       return NULL;
@@ -2951,7 +2950,7 @@ analyze_access_subtree (struct access *root, struct 
access *parent,
          tree rt = root->type;
          gcc_assert ((root->offset % BITS_PER_UNIT) == 0
                      && (root->size % BITS_PER_UNIT) == 0);
-         if (TREE_CODE (root->type) == BITINT_TYPE)
+         if (BITINT_TYPE_P (root->type))
            root->type = build_bitint_type (root->size, TYPE_UNSIGNED (rt));
          else
            root->type = build_nonstandard_integer_type (root->size,
diff --git a/gcc/tree-ssa-phiopt.cc b/gcc/tree-ssa-phiopt.cc
index 1c04a9b0f7c3..f5b295d1da32 100644
--- a/gcc/tree-ssa-phiopt.cc
+++ b/gcc/tree-ssa-phiopt.cc
@@ -2594,7 +2594,7 @@ cond_removal_in_builtin_zero_pattern (basic_block cond_bb,
       if (INTEGRAL_TYPE_P (TREE_TYPE (arg)))
        {
          tree type = TREE_TYPE (arg);
-         if (TREE_CODE (type) == BITINT_TYPE)
+         if (BITINT_TYPE_P (type))
            {
              if (gimple_call_num_args (call) == 1)
                {
@@ -2624,7 +2624,7 @@ cond_removal_in_builtin_zero_pattern (basic_block cond_bb,
       if (INTEGRAL_TYPE_P (TREE_TYPE (arg)))
        {
          tree type = TREE_TYPE (arg);
-         if (TREE_CODE (type) == BITINT_TYPE)
+         if (BITINT_TYPE_P (type))
            {
              if (gimple_call_num_args (call) == 1)
                {
diff --git a/gcc/tree-ssa-sccvn.cc b/gcc/tree-ssa-sccvn.cc
index 79b6b4652946..9bf29f40a2ae 100644
--- a/gcc/tree-ssa-sccvn.cc
+++ b/gcc/tree-ssa-sccvn.cc
@@ -2349,7 +2349,7 @@ vn_walk_cb_data::push_partial_def (pd_data pd,
      access size.  */
   if (INTEGRAL_TYPE_P (vr->type) && maxsizei != TYPE_PRECISION (vr->type))
     {
-      if (TREE_CODE (vr->type) == BITINT_TYPE
+      if (BITINT_TYPE_P (vr->type)
          && maxsizei > MAX_FIXED_MODE_SIZE)
        type = build_bitint_type (maxsizei, TYPE_UNSIGNED (type));
       else
@@ -3285,7 +3285,7 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void 
*data_,
                      && maxsizei != TYPE_PRECISION (vr->type))
                    {
                      bool uns = TYPE_UNSIGNED (type);
-                     if (TREE_CODE (vr->type) == BITINT_TYPE
+                     if (BITINT_TYPE_P (vr->type)
                          && maxsizei > MAX_FIXED_MODE_SIZE)
                        type = build_bitint_type (maxsizei, uns);
                      else
@@ -7393,7 +7393,7 @@ eliminate_dom_walker::eliminate_stmt (basic_block b, 
gimple_stmt_iterator *gsi)
              || !DECL_BIT_FIELD_TYPE (TREE_OPERAND (lhs, 1)))
          && !type_has_mode_precision_p (TREE_TYPE (lhs)))
        {
-         if (TREE_CODE (TREE_TYPE (lhs)) == BITINT_TYPE
+         if (BITINT_TYPE_P (TREE_TYPE (lhs))
              && TYPE_PRECISION (TREE_TYPE (lhs)) > MAX_FIXED_MODE_SIZE)
            lookup_lhs = NULL_TREE;
          else if (TREE_CODE (lhs) == COMPONENT_REF
diff --git a/gcc/tree-ssa.cc b/gcc/tree-ssa.cc
index e110e4acf2b0..5248c0903d45 100644
--- a/gcc/tree-ssa.cc
+++ b/gcc/tree-ssa.cc
@@ -1811,7 +1811,7 @@ maybe_optimize_var (tree var, bitmap addresses_taken, 
bitmap not_reg_needs,
              fprintf (dump_file, "\n");
            }
        }
-      else if (TREE_CODE (TREE_TYPE (var)) == BITINT_TYPE
+      else if (BITINT_TYPE_P (TREE_TYPE (var))
               && (cfun->curr_properties & PROP_gimple_lbitint) != 0
               && TYPE_PRECISION (TREE_TYPE (var)) > MAX_FIXED_MODE_SIZE)
        {
diff --git a/gcc/tree-switch-conversion.cc b/gcc/tree-switch-conversion.cc
index e2b7e5ce6254..b22daf2c659e 100644
--- a/gcc/tree-switch-conversion.cc
+++ b/gcc/tree-switch-conversion.cc
@@ -894,7 +894,7 @@ switch_conversion::array_value_type (tree type, int num)
   type = TYPE_MAIN_VARIANT (type);
 
   if (!INTEGRAL_TYPE_P (type)
-      || (TREE_CODE (type) == BITINT_TYPE
+      || (BITINT_TYPE_P (type)
          && (TYPE_PRECISION (type) > MAX_FIXED_MODE_SIZE
              || TYPE_MODE (type) == BLKmode)))
     return type;
@@ -1086,7 +1086,7 @@ switch_conversion::build_arrays ()
   utype = TREE_TYPE (m_index_expr);
   if (TREE_TYPE (utype))
     utype = lang_hooks.types.type_for_mode (TYPE_MODE (TREE_TYPE (utype)), 1);
-  else if (TREE_CODE (utype) == BITINT_TYPE
+  else if (BITINT_TYPE_P (utype)
           && (TYPE_PRECISION (utype) > MAX_FIXED_MODE_SIZE
               || TYPE_MODE (utype) == BLKmode))
     utype = unsigned_type_for (utype);
@@ -1548,7 +1548,7 @@ jump_table_cluster::emit (tree index_expr, tree,
   /* For large/huge _BitInt, subtract low from index_expr, cast to unsigned
      DImode type (get_range doesn't support ranges larger than 64-bits)
      and subtract low from all case values as well.  */
-  if (TREE_CODE (TREE_TYPE (index_expr)) == BITINT_TYPE
+  if (BITINT_TYPE_P (TREE_TYPE (index_expr))
       && TYPE_PRECISION (TREE_TYPE (index_expr)) > GET_MODE_PRECISION (DImode))
     {
       bitint = true;
diff --git a/gcc/tree.h b/gcc/tree.h
index 05400ada20ba..5ef8b464bbb8 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -633,9 +633,14 @@ extern void omp_clause_range_check_failed (const_tree, 
const char *, int,
         || VECTOR_TYPE_P (TYPE))               \
        && INTEGRAL_TYPE_P (TREE_TYPE (TYPE))))
 
-/* Nonzero if TYPE is bit-precise integer type.  */
-
-#define BITINT_TYPE_P(TYPE) (TREE_CODE (TYPE) == BITINT_TYPE)
+/* Nonzero if TYPE is bit-precise integer type or enumeral type
+   with bit-precise integer type as underlying type.  */
+
+#define BITINT_TYPE_P(TYPE) \
+  (TREE_CODE (TYPE) == BITINT_TYPE                     \
+   || (TREE_CODE (TYPE) == ENUMERAL_TYPE               \
+       && TREE_TYPE (TYPE)                             \
+       && TREE_CODE (TREE_TYPE (TYPE)) == BITINT_TYPE))
 
 /* Nonzero if TYPE represents a non-saturating fixed-point type.  */
 
diff --git a/gcc/ubsan.cc b/gcc/ubsan.cc
index 6525d320fd44..b87adf90900e 100644
--- a/gcc/ubsan.cc
+++ b/gcc/ubsan.cc
@@ -127,7 +127,7 @@ tree
 ubsan_encode_value (tree t, enum ubsan_encode_value_phase phase)
 {
   tree type = TREE_TYPE (t);
-  if (TREE_CODE (type) == BITINT_TYPE)
+  if (BITINT_TYPE_P (type))
     {
       if (TYPE_PRECISION (type) <= POINTER_SIZE)
        {
@@ -374,8 +374,7 @@ ubsan_type_descriptor (tree type, enum ubsan_print_style 
pstyle)
     {
       /* Temporary hack for -fsanitize=shift with _BitInt(129) and more.
         libubsan crashes if it is not TK_Integer type.  */
-      if (TREE_CODE (type) == BITINT_TYPE
-         && TYPE_PRECISION (type) > MAX_FIXED_MODE_SIZE)
+      if (BITINT_TYPE_P (type) && TYPE_PRECISION (type) > MAX_FIXED_MODE_SIZE)
        type3 = build_qualified_type (type, TYPE_QUAL_CONST);
       if (type3 == type)
        pstyle = UBSAN_PRINT_NORMAL;
@@ -432,7 +431,7 @@ ubsan_type_descriptor (tree type, enum ubsan_print_style 
pstyle)
 
   if (tname == NULL)
     {
-      if (TREE_CODE (type2) == BITINT_TYPE)
+      if (BITINT_TYPE_P (type2))
        {
          snprintf (tname_bitint, sizeof (tname_bitint),
                    "%s_BitInt(%d)", TYPE_UNSIGNED (type2) ? "unsigned " : "",
@@ -506,10 +505,16 @@ ubsan_type_descriptor (tree type, enum ubsan_print_style 
pstyle)
   switch (TREE_CODE (eltype))
     {
     case BOOLEAN_TYPE:
-    case ENUMERAL_TYPE:
     case INTEGER_TYPE:
       tkind = 0x0000;
       break;
+    case ENUMERAL_TYPE:
+      if (!BITINT_TYPE_P (eltype))
+       {
+         tkind = 0x0000;
+         break;
+       }
+      /* FALLTHRU */
     case BITINT_TYPE:
       if (TYPE_PRECISION (eltype) <= MAX_FIXED_MODE_SIZE)
        tkind = 0x0000;
@@ -1667,7 +1672,7 @@ instrument_si_overflow (gimple_stmt_iterator gsi)
      Also punt on bit-fields.  */
   if (!INTEGRAL_TYPE_P (lhsinner)
       || TYPE_OVERFLOW_WRAPS (lhsinner)
-      || (TREE_CODE (lhsinner) != BITINT_TYPE
+      || (!BITINT_TYPE_P (lhsinner)
          && maybe_ne (GET_MODE_BITSIZE (TYPE_MODE (lhsinner)),
                       TYPE_PRECISION (lhsinner))))
     return;
diff --git a/gcc/varasm.cc b/gcc/varasm.cc
index 5999f1e5420c..b3948dead4a4 100644
--- a/gcc/varasm.cc
+++ b/gcc/varasm.cc
@@ -5530,9 +5530,12 @@ output_constant (tree exp, unsigned HOST_WIDE_INT size, 
unsigned int align,
      Otherwise, break and ensure SIZE is the size written.  */
   switch (code)
     {
+    case ENUMERAL_TYPE:
+      if (BITINT_TYPE_P (TREE_TYPE (exp)))
+       goto do_bitint;
+      /* FALLTHRU */
     case BOOLEAN_TYPE:
     case INTEGER_TYPE:
-    case ENUMERAL_TYPE:
     case POINTER_TYPE:
     case REFERENCE_TYPE:
     case OFFSET_TYPE:
@@ -5564,6 +5567,7 @@ output_constant (tree exp, unsigned HOST_WIDE_INT size, 
unsigned int align,
       break;
 
     case BITINT_TYPE:
+    do_bitint:
       if (TREE_CODE (exp) != INTEGER_CST)
        error ("initializer for %<_BitInt(%d)%> value is not an integer "
               "constant", TYPE_PRECISION (TREE_TYPE (exp)));
diff --git a/gcc/vr-values.cc b/gcc/vr-values.cc
index 7d486c3a3061..672b637b9181 100644
--- a/gcc/vr-values.cc
+++ b/gcc/vr-values.cc
@@ -1561,7 +1561,7 @@ 
simplify_using_ranges::simplify_float_conversion_using_ranges
 
   /* The code below doesn't work for large/huge _BitInt, nor is really
      needed for those, bitint lowering does use ranges already.  */
-  if (TREE_CODE (TREE_TYPE (rhs1)) == BITINT_TYPE
+  if (BITINT_TYPE_P (TREE_TYPE (rhs1))
       && TYPE_MODE (TREE_TYPE (rhs1)) == BLKmode)
     return false;
   /* First check if we can use a signed type in place of an unsigned.  */

Reply via email to