On Fri, Jul 25, 2025 at 10:53:37AM +0800, Yang Yujie wrote: > This patch also make casts of ABI-extended large/huge _BitInts > behave the same as the small/middle case, i.e. no-op for casts > to a higher precision _BitInt with the same number of limbs / > extension for casts that turns a full top limb into a partial limb. > This conveniently helps keep some code with implementation-specific > extension semantics (e.g. BEXTC from gcc.dg/bitintext.h) the same > for _BitInts of any precision. > > gcc/ChangeLog: > > * gimple-lower-bitint.cc (bitint_large_huge::limb_access): > Add a parameter abi_load_p. If set, load a limb directly > in its actual precision without casting from m_limb_type. > (struct bitint_large_huge): Same. > (bitint_large_huge::handle_load): Use. > --- > gcc/gimple-lower-bitint.cc | 27 +++++++++++++++++++-------- > 1 file changed, 19 insertions(+), 8 deletions(-) > > diff --git a/gcc/gimple-lower-bitint.cc b/gcc/gimple-lower-bitint.cc > index 8fb7a604591..631a7844790 100644 > --- a/gcc/gimple-lower-bitint.cc > +++ b/gcc/gimple-lower-bitint.cc > @@ -429,7 +429,7 @@ struct bitint_large_huge > > void insert_before (gimple *); > tree limb_access_type (tree, tree); > - tree limb_access (tree, tree, tree, bool); > + tree limb_access (tree, tree, tree, bool, bool = false); > tree build_bit_field_ref (tree, tree, unsigned HOST_WIDE_INT, > unsigned HOST_WIDE_INT); > void if_then (gimple *, profile_probability, edge &, edge &); > @@ -610,11 +610,15 @@ bitint_large_huge::limb_access_type (tree type, tree > idx) > TYPE. If WRITE_P is true, it will be a store, otherwise a read. */ > > tree > -bitint_large_huge::limb_access (tree type, tree var, tree idx, bool write_p) > +bitint_large_huge::limb_access (tree type, tree var, tree idx, bool write_p, > + bool abi_load_p) > { > tree atype = (tree_fits_uhwi_p (idx) > ? limb_access_type (type, idx) : m_limb_type); > - tree ltype = m_limb_type; > + > + tree ltype = (tree_fits_uhwi_p (idx) && bitint_extended && abi_load_p > + ? limb_access_type (type, idx) : m_limb_type);
Why do you call limb_access_type again? atype in that case should be the result of limb_access_type. > + > addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (var)); > if (as != TYPE_ADDR_SPACE (ltype)) > ltype = build_qualified_type (ltype, TYPE_QUALS (ltype) > @@ -651,12 +655,12 @@ bitint_large_huge::limb_access (tree type, tree var, > tree idx, bool write_p) > { > unsigned HOST_WIDE_INT nelts > = CEIL (tree_to_uhwi (TYPE_SIZE (TREE_TYPE (var))), limb_prec); > - tree atype = build_array_type_nelts (ltype, nelts); > + tree atype = build_array_type_nelts (m_limb_type, nelts); This looks wrong. It needs to be from the right address space, see above if (as != TYPE_ADDR_SPACE (ltype)) ltype = build_qualified_type ... > var = build1 (VIEW_CONVERT_EXPR, atype, var); > } > ret = build4 (ARRAY_REF, ltype, var, idx, NULL_TREE, NULL_TREE); > } > - if (!write_p && !useless_type_conversion_p (atype, m_limb_type)) > + if (!write_p && !useless_type_conversion_p (atype, ltype)) Again, this looks wrong for non-standard address spaces. Jakub