https://gcc.gnu.org/g:b55277a4f8543f52c6d1664bb05e8eb90f46aaf3

commit r16-3563-gb55277a4f8543f52c6d1664bb05e8eb90f46aaf3
Author: Jakub Jelinek <[email protected]>
Date:   Thu Sep 4 10:45:17 2025 +0200

    bitint: Fix torture/bitint-14.c on bitint_extended targets [PR117599]
    
    This patch fixes regressions of the gcc.dg/torture/bitint-* tests
    caused by r16-3036-ga76a032354ee48 with --enable-checking=all.
    
    The errors are similar to the following:
    
    ../../gcc/testsuite/gcc.dg/torture/bitint-14.c:54:1: error: type mismatch 
in 'array_ref'
    <unnamed-signed:63>
    
    unsigned long
    
    _42 = VIEW_CONVERT_EXPR<unsigned long[10]>(r575[i_10])[8];
    during GIMPLE pass: bitintlower0
    ../../gcc/testsuite/gcc.dg/torture/bitint-14.c:54:1: internal compiler 
error: verify_gimple failed
    
    The first two hunks aren't strictly necessary, I'm just trying to
    avoid calling build_qualified_type when it won't be needed.
    
    At least on s390x-linux (tried cross) bitint-14.c doesn't ICE with it
    anymore.
    
    Though, I must say the more I look at the limb_access changes, the less
    I like the abi_load_p stuff, so I think what we eventually should do instead
    is return values with m_limb_type always.
    For bitint_extended case (but only if we can prove that the extension there
    is for the right precision and right sign) or !write_p just return it,
    otherwise cast to lower precision and back to m_limb_type.
    And on the other side on stores, for !bitint_extended happily store whatever
    the whole m_limb_type value contains, for bitint_extended do the cast to
    smaller precision and back on the writes.
    
    2025-09-04  Jakub Jelinek  <[email protected]>
    
            PR target/117599
            * gimple-lower-bitint.cc (bitint_large_huge::limb_access): Move
            build_qualified_type calls into the if/else if/else bodies, for
            the last one set ltype to m_limb_type first, drop limb_type_a
            and use ltype instead.

Diff:
---
 gcc/gimple-lower-bitint.cc | 24 +++++++++++-------------
 1 file changed, 11 insertions(+), 13 deletions(-)

diff --git a/gcc/gimple-lower-bitint.cc b/gcc/gimple-lower-bitint.cc
index 1e434ce7a0c9..9b4d49395ae3 100644
--- a/gcc/gimple-lower-bitint.cc
+++ b/gcc/gimple-lower-bitint.cc
@@ -622,12 +622,12 @@ bitint_large_huge::limb_access (tree type, tree var, tree 
idx, bool write_p,
   tree ltype = (bitint_extended && abi_load_p) ? atype : m_limb_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)
-                                        | ENCODE_QUAL_ADDR_SPACE (as));
   tree ret;
   if (DECL_P (var) && tree_fits_uhwi_p (idx))
     {
+      if (as != TYPE_ADDR_SPACE (ltype))
+       ltype = build_qualified_type (ltype, TYPE_QUALS (ltype)
+                                     | ENCODE_QUAL_ADDR_SPACE (as));
       tree ptype = build_pointer_type (strip_array_types (TREE_TYPE (var)));
       unsigned HOST_WIDE_INT off = tree_to_uhwi (idx) * m_limb_size;
       ret = build2 (MEM_REF, ltype,
@@ -638,6 +638,9 @@ bitint_large_huge::limb_access (tree type, tree var, tree 
idx, bool write_p,
     }
   else if (TREE_CODE (var) == MEM_REF && tree_fits_uhwi_p (idx))
     {
+      if (as != TYPE_ADDR_SPACE (ltype))
+       ltype = build_qualified_type (ltype, TYPE_QUALS (ltype)
+                                     | ENCODE_QUAL_ADDR_SPACE (as));
       ret
        = build2 (MEM_REF, ltype, unshare_expr (TREE_OPERAND (var, 0)),
                  size_binop (PLUS_EXPR, TREE_OPERAND (var, 1),
@@ -650,6 +653,10 @@ bitint_large_huge::limb_access (tree type, tree var, tree 
idx, bool write_p,
     }
   else
     {
+      ltype = m_limb_type;
+      if (as != TYPE_ADDR_SPACE (ltype))
+       ltype = build_qualified_type (ltype, TYPE_QUALS (ltype)
+                                     | ENCODE_QUAL_ADDR_SPACE (as));
       var = unshare_expr (var);
       if (TREE_CODE (TREE_TYPE (var)) != ARRAY_TYPE
          || !useless_type_conversion_p (m_limb_type,
@@ -657,16 +664,7 @@ 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);
-
-         /* Build the array type with m_limb_type from the right address
-            space.  */
-         tree limb_type_a = m_limb_type;
-         if (as != TYPE_ADDR_SPACE (m_limb_type))
-           limb_type_a = build_qualified_type (m_limb_type,
-                                               TYPE_QUALS (m_limb_type)
-                                               | ENCODE_QUAL_ADDR_SPACE (as));
-
-         tree atype = build_array_type_nelts (limb_type_a, nelts);
+         tree atype = build_array_type_nelts (ltype, nelts);
          var = build1 (VIEW_CONVERT_EXPR, atype, var);
        }
       ret = build4 (ARRAY_REF, ltype, var, idx, NULL_TREE, NULL_TREE);

Reply via email to