For targets that set the "extended" flag in TARGET_C_BITINT_TYPE_INFO, we assume small _BitInts to be internally extended after arithmetic operations. In this case, an extra extension during RTL expansion can be avoided.
gcc/ChangeLog: * expr.cc (expand_expr_real_1): Do not call reduce_to_bit_field_precision if the target assume the _BitInt results to be already extended. (EXTEND_BITINT): Same. --- gcc/expr.cc | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/gcc/expr.cc b/gcc/expr.cc index ac4fdfaa218..a3d73edffd5 100644 --- a/gcc/expr.cc +++ b/gcc/expr.cc @@ -11268,6 +11268,10 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode, tree ssa_name = NULL_TREE; gimple *g; + type = TREE_TYPE (exp); + mode = TYPE_MODE (type); + unsignedp = TYPE_UNSIGNED (type); + /* 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 @@ -11278,8 +11282,10 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode, 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 \ + && !bitint_type_info.extended \ && reduce_bit_field \ && mode != BLKmode \ && modifier != EXPAND_MEMORY \ @@ -11288,9 +11294,13 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode, && 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); + struct bitint_info bitint_type_info; + if (TREE_CODE (type) == BITINT_TYPE) + { + bool ok = targetm.c.bitint_type_info (TYPE_PRECISION (type), + &bitint_type_info); + gcc_assert (ok); + } treeop0 = treeop1 = treeop2 = NULL_TREE; if (!VL_EXP_CLASS_P (exp)) @@ -11631,12 +11641,9 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode, { if (TREE_CODE (type) == BITINT_TYPE) { - unsigned int prec = TYPE_PRECISION (type); - struct bitint_info info; - bool ok = targetm.c.bitint_type_info (prec, &info); - gcc_assert (ok); scalar_int_mode limb_mode - = as_a <scalar_int_mode> (info.limb_mode); + = as_a <scalar_int_mode> (bitint_type_info.limb_mode); + unsigned int prec = TYPE_PRECISION (type); unsigned int limb_prec = GET_MODE_PRECISION (limb_mode); if (prec > limb_prec && prec > MAX_FIXED_MODE_SIZE) { -- 2.46.0