From: Jakub Jelinek Date: Fri, 12 Jan 2024 10:16:41 +0000 (+0100) Subject: lower-bitint: Fix handling of casts on arches with abi_limb_mode != limb_mode X-Git-Tag: basepoints/gcc-15~2961 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4ff5e7cec91013f2b2e5c680d13bfd20e2a19763;p=thirdparty%2Fgcc.git lower-bitint: Fix handling of casts on arches with abi_limb_mode != limb_mode > > This patch is still work in progress, but posting to show failure with > > bitint-7 test where handle_stmt called from lower_mergeable_stmt ICE's > > because the idx (3) is out of range for the __BitInt(135) with a limb_prec > > of 64. > > I can reproduce it, will debug it momentarily. So, the problem was that in 2 spots I was comparing TYPE_SIZE of large/huge BITINT_TYPEs to determine if it can be handled cheaply. On x86_64 with limb_mode == abi_limb_mode (both DImode) that works fine, if TYPE_SIZE is equal, it means it has the same number of limbs. But on aarch64 TYPE_SIZE of say _BitInt(135) and _BitInt(193) is the same, both are 256-bit storage, but because DImode is used as limb_mode, the former actually needs just 3 limbs, while the latter needs 4 limbs. And limb_access_type was asserting that we don't try to access 4th limb on types which actually have a precision which needs just 3 limbs. The following patch should fix that. Note, for the info.extended targets (currently none, but I think arm 32-bit in the ABI is meant like that), we'll need to do something different, because the upper bits aren't just padding and should be zero/sign extended, so if we say have limb_mode SImode, abi_limb_mode DImode, we'll need to treat _BitInt(135) not as 5 SImode limbs, but 6. For !info.extended targets I think treating _BitInt(135) as 3 DImode limbs rather than 4 is fine. 2024-01-12 Jakub Jelinek * gimple-lower-bitint.cc (mergeable_op): Instead of comparing TYPE_SIZE (t) of large/huge BITINT_TYPEs, compare CEIL (TYPE_PRECISION (t), limb_prec). (bitint_large_huge::handle_cast): Likewise. --- diff --git a/gcc/gimple-lower-bitint.cc b/gcc/gimple-lower-bitint.cc index 8993a6136e7d..68e01897ba4e 100644 --- a/gcc/gimple-lower-bitint.cc +++ b/gcc/gimple-lower-bitint.cc @@ -231,7 +231,8 @@ mergeable_op (gimple *stmt) && TREE_CODE (rhs_type) == BITINT_TYPE && bitint_precision_kind (lhs_type) >= bitint_prec_large && bitint_precision_kind (rhs_type) >= bitint_prec_large - && tree_int_cst_equal (TYPE_SIZE (lhs_type), TYPE_SIZE (rhs_type))) + && (CEIL (TYPE_PRECISION (lhs_type), limb_prec) + == CEIL (TYPE_PRECISION (rhs_type), limb_prec))) { if (TYPE_PRECISION (rhs_type) >= TYPE_PRECISION (lhs_type)) return true; @@ -1263,8 +1264,8 @@ bitint_large_huge::handle_cast (tree lhs_type, tree rhs1, tree idx) if m_upwards_2limb * limb_prec is equal to lhs precision that is not the case. */ || (!m_var_msb - && tree_int_cst_equal (TYPE_SIZE (rhs_type), - TYPE_SIZE (lhs_type)) + && (CEIL (TYPE_PRECISION (lhs_type), limb_prec) + == CEIL (TYPE_PRECISION (rhs_type), limb_prec)) && (!m_upwards_2limb || (m_upwards_2limb * limb_prec < TYPE_PRECISION (lhs_type)))))