[gcc r14-7178] lower-bitint: Fix handling of casts on arches with abi_limb_mode != limb_mode

Jakub Jelinek jakub@gcc.gnu.org
Fri Jan 12 10:18:13 GMT 2024


https://gcc.gnu.org/g:4ff5e7cec91013f2b2e5c680d13bfd20e2a19763

commit r14-7178-g4ff5e7cec91013f2b2e5c680d13bfd20e2a19763
Author: Jakub Jelinek <jakub@redhat.com>
Date:   Fri Jan 12 11:16:41 2024 +0100

    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  <jakub@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.

Diff:
---
 gcc/gimple-lower-bitint.cc | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/gcc/gimple-lower-bitint.cc b/gcc/gimple-lower-bitint.cc
index 8993a6136e7..68e01897ba4 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)))))


More information about the Gcc-cvs mailing list