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

Reply via email to