On Fri, 12 Jan 2024, Jakub Jelinek wrote:

> On Thu, Jan 11, 2024 at 12:12:59PM +0100, Jakub Jelinek wrote:
> > 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 (so far tested on x86_64 with all the bitint tests plus
> > on the bitint-7.c testcase in a cross to aarch64) 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-11  Jakub Jelinek  <ja...@redhat.com>
> > 
> >     * 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.
> 
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

OK

> > --- gcc/gimple-lower-bitint.cc.jj   2024-01-08 13:58:21.448176859 +0100
> > +++ gcc/gimple-lower-bitint.cc      2024-01-11 11:46:49.147779946 +0100
> > @@ -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
> >          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)))))
> > 
> >     Jakub
> 
>       Jakub
> 
> 

-- 
Richard Biener <rguent...@suse.de>
SUSE Software Solutions Germany GmbH,
Frankenstrasse 146, 90461 Nuernberg, Germany;
GF: Ivo Totev, Andrew McDonald, Werner Knoblich; (HRB 36809, AG Nuernberg)

Reply via email to