aboutsummaryrefslogtreecommitdiff
path: root/gcc/expr.cc
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2023-09-06 17:25:49 +0200
committerJakub Jelinek <jakub@redhat.com>2023-09-06 17:28:24 +0200
commit4f4fa2501186e43d115238ae938b3df322c9e02a (patch)
tree175594012bb25f03f599aba0078c082fb98fae81 /gcc/expr.cc
parent6b96de22d6bcadb45530c1898b264e4738afa4fd (diff)
downloadgcc-4f4fa2501186e43d115238ae938b3df322c9e02a.zip
gcc-4f4fa2501186e43d115238ae938b3df322c9e02a.tar.gz
gcc-4f4fa2501186e43d115238ae938b3df322c9e02a.tar.bz2
Middle-end _BitInt support [PR102989]
The following patch introduces the middle-end part of the _BitInt support, a new BITINT_TYPE, handling it where needed, except the lowering pass and sanitizer support. 2023-09-06 Jakub Jelinek <jakub@redhat.com> PR c/102989 * tree.def (BITINT_TYPE): New type. * tree.h (TREE_CHECK6, TREE_NOT_CHECK6): Define. (NUMERICAL_TYPE_CHECK, INTEGRAL_TYPE_P): Include BITINT_TYPE. (BITINT_TYPE_P): Define. (CONSTRUCTOR_BITFIELD_P): Return true even for BLKmode bit-fields if they have BITINT_TYPE type. (tree_check6, tree_not_check6): New inline functions. (any_integral_type_check): Include BITINT_TYPE. (build_bitint_type): Declare. * tree.cc (tree_code_size, wide_int_to_tree_1, cache_integer_cst, build_zero_cst, type_hash_canon_hash, type_cache_hasher::equal, type_hash_canon): Handle BITINT_TYPE. (bitint_type_cache): New variable. (build_bitint_type): New function. (signed_or_unsigned_type_for, verify_type_variant, verify_type): Handle BITINT_TYPE. (tree_cc_finalize): Free bitint_type_cache. * builtins.cc (type_to_class): Handle BITINT_TYPE. (fold_builtin_unordered_cmp): Handle BITINT_TYPE like INTEGER_TYPE. * cfgexpand.cc (expand_debug_expr): Punt on BLKmode BITINT_TYPE INTEGER_CSTs. * convert.cc (convert_to_pointer_1, convert_to_real_1, convert_to_complex_1): Handle BITINT_TYPE like INTEGER_TYPE. (convert_to_integer_1): Likewise. For BITINT_TYPE don't check GET_MODE_PRECISION (TYPE_MODE (type)). * doc/generic.texi (BITINT_TYPE): Document. * doc/tm.texi.in (TARGET_C_BITINT_TYPE_INFO): New. * doc/tm.texi: Regenerated. * dwarf2out.cc (base_type_die, is_base_type, modified_type_die, gen_type_die_with_usage): Handle BITINT_TYPE. (rtl_for_decl_init): Punt on BLKmode BITINT_TYPE INTEGER_CSTs or handle those which fit into shwi. * expr.cc (expand_expr_real_1): Define EXTEND_BITINT macro, reduce to bitfield precision reads from BITINT_TYPE vars, parameters or memory locations. Expand large/huge BITINT_TYPE INTEGER_CSTs into memory. * fold-const.cc (fold_convert_loc, make_range_step): Handle BITINT_TYPE. (extract_muldiv_1): For BITINT_TYPE use TYPE_PRECISION rather than GET_MODE_SIZE (SCALAR_INT_TYPE_MODE). (native_encode_int, native_interpret_int, native_interpret_expr): Handle BITINT_TYPE. * gimple-expr.cc (useless_type_conversion_p): Make BITINT_TYPE to some other integral type or vice versa conversions non-useless. * gimple-fold.cc (gimple_fold_builtin_memset): Punt for BITINT_TYPE. (clear_padding_unit): Mention in comment that _BitInt types don't need to fit either. (clear_padding_bitint_needs_padding_p): New function. (clear_padding_type_may_have_padding_p): Handle BITINT_TYPE. (clear_padding_type): Likewise. * internal-fn.cc (expand_mul_overflow): For unsigned non-mode precision operands force pos_neg? to 1. (expand_MULBITINT, expand_DIVMODBITINT, expand_FLOATTOBITINT, expand_BITINTTOFLOAT): New functions. * internal-fn.def (MULBITINT, DIVMODBITINT, FLOATTOBITINT, BITINTTOFLOAT): New internal functions. * internal-fn.h (expand_MULBITINT, expand_DIVMODBITINT, expand_FLOATTOBITINT, expand_BITINTTOFLOAT): Declare. * match.pd (non-equality compare simplifications from fold_binary): Punt if TYPE_MODE (arg1_type) is BLKmode. * pretty-print.h (pp_wide_int): Handle printing of large precision wide_ints which would buffer overflow digit_buffer. * stor-layout.cc (finish_bitfield_representative): For bit-fields with BITINT_TYPE, prefer representatives with precisions in multiple of limb precision. (layout_type): Handle BITINT_TYPE. Handle COMPLEX_TYPE with BLKmode element type and assert it is BITINT_TYPE. * target.def (bitint_type_info): New C target hook. * target.h (struct bitint_info): New type. * targhooks.cc (default_bitint_type_info): New function. * targhooks.h (default_bitint_type_info): Declare. * tree-pretty-print.cc (dump_generic_node): Handle BITINT_TYPE. Handle printing large wide_ints which would buffer overflow digit_buffer. * tree-ssa-sccvn.cc: Include target.h. (eliminate_dom_walker::eliminate_stmt): Punt for large/huge BITINT_TYPE. * tree-switch-conversion.cc (jump_table_cluster::emit): For more than 64-bit BITINT_TYPE subtract low bound from expression and cast to 64-bit integer type both the controlling expression and case labels. * typeclass.h (enum type_class): Add bitint_type_class enumerator. * varasm.cc (output_constant): Handle BITINT_TYPE INTEGER_CSTs. * vr-values.cc (check_for_binary_op_overflow): Use widest2_int rather than widest_int. (simplify_using_ranges::simplify_internal_call_using_ranges): Use unsigned_type_for rather than build_nonstandard_integer_type.
Diffstat (limited to 'gcc/expr.cc')
-rw-r--r--gcc/expr.cc61
1 files changed, 56 insertions, 5 deletions
diff --git a/gcc/expr.cc b/gcc/expr.cc
index 9a37bff..d6b5bd0 100644
--- a/gcc/expr.cc
+++ b/gcc/expr.cc
@@ -10650,6 +10650,25 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode,
tree ssa_name = NULL_TREE;
gimple *g;
+ /* Some ABIs define padding bits in _BitInt uninitialized. Normally, RTL
+ expansion sign/zero extends integral types with less than mode precision
+ when reading from bit-fields and after arithmetic operations (see
+ REDUCE_BIT_FIELD in expand_expr_real_2) and on subsequent loads relies
+ on those extensions to have been already performed, but because of the
+ above for _BitInt they need to be sign/zero extended when reading from
+ locations that could be exposed to ABI boundaries (when loading from
+ objects in memory, or function arguments, return value). Because we
+ 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 \
+ && reduce_bit_field \
+ && mode != BLKmode \
+ && modifier != EXPAND_MEMORY \
+ && modifier != EXPAND_WRITE \
+ && modifier != EXPAND_CONST_ADDRESS) \
+ ? reduce_to_bit_field_precision ((expr), NULL_RTX, type) : (expr))
+
type = TREE_TYPE (exp);
mode = TYPE_MODE (type);
unsignedp = TYPE_UNSIGNED (type);
@@ -10823,6 +10842,13 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode,
ssa_name = exp;
decl_rtl = get_rtx_for_ssa_name (ssa_name);
exp = SSA_NAME_VAR (ssa_name);
+ /* Optimize and avoid to EXTEND_BITINIT doing anything if it is an
+ SSA_NAME computed within the current function. In such case the
+ value have been already extended before. While if it is a function
+ parameter, result or some memory location, we need to be prepared
+ for some other compiler leaving the bits uninitialized. */
+ if (!exp || VAR_P (exp))
+ reduce_bit_field = false;
goto expand_decl_rtl;
case VAR_DECL:
@@ -10956,7 +10982,7 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode,
temp = expand_misaligned_mem_ref (temp, mode, unsignedp,
MEM_ALIGN (temp), NULL_RTX, NULL);
- return temp;
+ return EXTEND_BITINT (temp);
}
if (exp)
@@ -11002,13 +11028,35 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode,
temp = gen_lowpart_SUBREG (mode, decl_rtl);
SUBREG_PROMOTED_VAR_P (temp) = 1;
SUBREG_PROMOTED_SET (temp, unsignedp);
- return temp;
+ return EXTEND_BITINT (temp);
}
- return decl_rtl;
+ return EXTEND_BITINT (decl_rtl);
case INTEGER_CST:
{
+ if (TREE_CODE (type) == BITINT_TYPE)
+ {
+ unsigned int prec = TYPE_PRECISION (type);
+ struct bitint_info info;
+ gcc_assert (targetm.c.bitint_type_info (prec, &info));
+ scalar_int_mode limb_mode
+ = as_a <scalar_int_mode> (info.limb_mode);
+ unsigned int limb_prec = GET_MODE_PRECISION (limb_mode);
+ if (prec > limb_prec)
+ {
+ scalar_int_mode arith_mode
+ = (targetm.scalar_mode_supported_p (TImode)
+ ? TImode : DImode);
+ if (prec > GET_MODE_PRECISION (arith_mode))
+ {
+ /* Emit large/huge _BitInt INTEGER_CSTs into memory. */
+ exp = tree_output_constant_def (exp);
+ return expand_expr (exp, target, VOIDmode, modifier);
+ }
+ }
+ }
+
/* Given that TYPE_PRECISION (type) is not always equal to
GET_MODE_PRECISION (TYPE_MODE (type)), we need to extend from
the former to the latter according to the signedness of the
@@ -11187,7 +11235,7 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode,
&& align < GET_MODE_ALIGNMENT (mode))
temp = expand_misaligned_mem_ref (temp, mode, unsignedp,
align, NULL_RTX, NULL);
- return temp;
+ return EXTEND_BITINT (temp);
}
case MEM_REF:
@@ -11258,7 +11306,7 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode,
? NULL_RTX : target, alt_rtl);
if (reverse)
temp = flip_storage_order (mode, temp);
- return temp;
+ return EXTEND_BITINT (temp);
}
case ARRAY_REF:
@@ -11810,6 +11858,8 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode,
&& modifier != EXPAND_WRITE)
op0 = flip_storage_order (mode1, op0);
+ op0 = EXTEND_BITINT (op0);
+
if (mode == mode1 || mode1 == BLKmode || mode1 == tmode
|| modifier == EXPAND_CONST_ADDRESS
|| modifier == EXPAND_INITIALIZER)
@@ -12155,6 +12205,7 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode,
return expand_expr_real_2 (&ops, target, tmode, modifier);
}
}
+#undef EXTEND_BITINT
/* Subroutine of above: reduce EXP to the precision of TYPE (in the
signedness of TYPE), possibly returning the result in TARGET.