From 32160061ca6d0fc9588b3dea41ced503907f79ca Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Wed, 29 Apr 2026 11:12:47 +0200 Subject: [PATCH] bitintlower: Padding bit fixes, part 6 [PR123635] I've missed torture/bitint-{93,94}.c FAILs on s390x-linux (i.e. big endian). For __builtin_mul_overflow, the code to extend the partial most significant limb is done before memmoving it down, so that limb actually isn't on big endian at offset 0 but is nelts - obj_nelts. The following patch computes obj_nelts first, uses it on big-endian and so that the offset checking asserts don't trigger, on big-endian also uses NULL_TREE first argument to limb_access. 2026-04-29 Jakub Jelinek PR middle-end/123635 * gimple-lower-bitint.cc (bitint_large_huge::finish_arith_overflow): Move obj_nelts/atype computation before bitint_extended handling. For bitint_big_endian in the bitint_extended handling use size_zero_node only for limb_access_type calls, otherwise use size_int (nelts - obj_nelts) and pass NULL_TREE as first argument to limb_access calls. Reviewed-by: Richard Biener --- gcc/gimple-lower-bitint.cc | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/gcc/gimple-lower-bitint.cc b/gcc/gimple-lower-bitint.cc index 9c4600121d0..7d8ca05f88d 100644 --- a/gcc/gimple-lower-bitint.cc +++ b/gcc/gimple-lower-bitint.cc @@ -4478,6 +4478,13 @@ bitint_large_huge::finish_arith_overflow (tree var, tree obj, tree type, { unsigned HOST_WIDE_INT obj_nelts = 0; tree atype = NULL_TREE; + if (obj) + { + obj_nelts = tree_to_uhwi (TYPE_SIZE (TREE_TYPE (obj))) / limb_prec; + if (orig_obj == NULL_TREE) + obj_nelts >>= 1; + atype = build_array_type_nelts (m_limb_type, obj_nelts); + } if (bitint_extended && (var || obj)) { unsigned prec = TYPE_PRECISION (type); @@ -4492,9 +4499,13 @@ bitint_large_huge::finish_arith_overflow (tree var, tree obj, tree type, if ((code == MULT_EXPR && (prec % limb_prec) != 0) || (ext_ms_limb && !TYPE_UNSIGNED (type))) { - tree plm1idx = size_int (bitint_big_endian ? 0 : prec_limbs - 1); - tree plm1type = limb_access_type (type, plm1idx); - tree l = limb_access (type, var ? var : obj, plm1idx, true); + tree plm1idx = size_int (bitint_big_endian + ? nelts - obj_nelts : prec_limbs - 1); + tree plm1type + = limb_access_type (type, bitint_big_endian + ? size_zero_node : plm1idx); + tree l = limb_access (bitint_big_endian ? NULL_TREE : type, + var ? var : obj, plm1idx, true); tree rhs = make_ssa_name (TREE_TYPE (l)); g = gimple_build_assign (rhs, l); insert_before (g); @@ -4505,7 +4516,8 @@ bitint_large_huge::finish_arith_overflow (tree var, tree obj, tree type, if (!useless_type_conversion_p (TREE_TYPE (l), TREE_TYPE (rhs))) rhs = add_cast (TREE_TYPE (l), rhs); - l = limb_access (type, var ? var : obj, plm1idx, true); + l = limb_access (bitint_big_endian ? NULL_TREE : type, + var ? var : obj, plm1idx, true); g = gimple_build_assign (l, rhs); insert_before (g); } @@ -4537,13 +4549,6 @@ bitint_large_huge::finish_arith_overflow (tree var, tree obj, tree type, insert_before (g); } } - if (obj) - { - obj_nelts = tree_to_uhwi (TYPE_SIZE (TREE_TYPE (obj))) / limb_prec; - if (orig_obj == NULL_TREE) - obj_nelts >>= 1; - atype = build_array_type_nelts (m_limb_type, obj_nelts); - } if (var && obj) { tree v1, v2;