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. */
