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