Hi!

On aarch64 the backend decides to use non-BLKmode for some arrays
like unsigned long[4] - OImode in that case, but the corresponding
BITINT_TYPEs have BLKmode (like structures containing that many limb
elements).  This both isn't a good idea (we really want such underlying vars
to live in memory and access them there, rather than live in registers and
access their parts in there) and causes ICEs during expansion
(VIEW_CONVERT_EXPR from such OImode array to BLKmode BITINT_TYPE), so the
following patch makes sure such arrays reflect the BLKmode of BITINT_TYPEs
it is accessed with (if any).

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2024-01-18  Jakub Jelinek  <ja...@redhat.com>

        * gimple-lower-bitint.cc (gimple_lower_bitint): When creating
        array VAR_DECL for BITINT_TYPE SSA_NAMEs which have BLKmode, force
        DECL_MODE of those vars to be BLKmode as well.

--- gcc/gimple-lower-bitint.cc.jj       2024-01-17 14:43:33.498961304 +0100
+++ gcc/gimple-lower-bitint.cc  2024-01-17 14:50:50.252889131 +0100
@@ -6348,7 +6348,15 @@ gimple_lower_bitint (void)
          tree s = ssa_name (i);
          int p = var_to_partition (large_huge.m_map, s);
          if (large_huge.m_vars[p] != NULL_TREE)
-           continue;
+           {
+             /* If BITINT_TYPE is BLKmode, make sure the underlying
+                variable is BLKmode as well.  */
+             if (TYPE_MODE (TREE_TYPE (s)) == BLKmode
+                 && VAR_P (large_huge.m_vars[p])
+                 && DECL_MODE (large_huge.m_vars[p]) != BLKmode)
+               DECL_MODE (large_huge.m_vars[p]) = BLKmode;
+             continue;
+           }
          if (atype == NULL_TREE
              || !tree_int_cst_equal (TYPE_SIZE (atype),
                                      TYPE_SIZE (TREE_TYPE (s))))
@@ -6359,6 +6367,11 @@ gimple_lower_bitint (void)
            }
          large_huge.m_vars[p] = create_tmp_var (atype, "bitint");
          mark_addressable (large_huge.m_vars[p]);
+         /* If BITINT_TYPE is BLKmode, make sure the underlying
+            variable is BLKmode as well.  */
+         if (TYPE_MODE (TREE_TYPE (s)) == BLKmode
+             && DECL_MODE (large_huge.m_vars[p]) != BLKmode)
+           DECL_MODE (large_huge.m_vars[p]) = BLKmode;
        }
     }
 

        Jakub

Reply via email to