https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97205
--- Comment #9 from Bernd Edlinger <bernd.edlinger at hotmail dot de> --- (In reply to rguent...@suse.de from comment #7) > On Wed, 28 Oct 2020, bernd.edlinger at hotmail dot de wrote: > > > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97205 > > > > --- Comment #6 from Bernd Edlinger <bernd.edlinger at hotmail dot de> --- > > (In reply to rguent...@suse.de from comment #3) > > > On Tue, 27 Oct 2020, bernd.edlinger at hotmail dot de wrote: > > > > --- a/gcc/emit-rtl.c > > > > +++ b/gcc/emit-rtl.c > > > > @@ -2089,7 +2089,8 @@ set_mem_attributes_minus_bitpos (rtx ref, tree t, > > > > int > > > > objectp, > > > > { > > > > gcc_assert (handled_component_p (t) > > > > || TREE_CODE (t) == MEM_REF > > > > - || TREE_CODE (t) == TARGET_MEM_REF); > > > > + || TREE_CODE (t) == TARGET_MEM_REF > > > > + || TREE_CODE (t) == SSA_NAME); > > > > > > Can you track down this? It's a red herring to have a MEM_EXPR > > > that just is a SSA_NAME. > > > > > > > This happens here: > > > > if (MEM_P (to_rtx)) > > { > > /* If the field is at offset zero, we could have been given > > the > > DECL_RTX of the parent struct. Don't munge it. */ > > to_rtx = shallow_copy_rtx (to_rtx); > > set_mem_attributes_minus_bitpos (to_rtx, to, 0, bitpos); > > if (volatilep) > > MEM_VOLATILE_P (to_rtx) = 1; > > } > > > > since the patch allows the SSA_NAME to reach this block. > > > > > > > > --- a/gcc/expr.c > > > > +++ b/gcc/expr.c > > > > @@ -5200,6 +5200,9 @@ expand_assignment (tree to, tree from, bool > > > > nontemporal) > > > > || (TREE_CODE (to) == MEM_REF > > > > && (REF_REVERSE_STORAGE_ORDER (to) > > > > || mem_ref_refers_to_non_mem_p (to))) > > > > + || (TREE_CODE (to) == SSA_NAME > > > > + && mode != BLKmode > > > > + && TYPE_ALIGN (TREE_TYPE (to)) < GET_MODE_ALIGNMENT (mode)) > > > > > > But an SSA name is a register, esp. one with non-BLKmode. And if > > > expanded to a stack location that stack location should better > > > be aligned... or be BLKmode. So I think the bug is elsewhere? > > > > > > > Hmm, to avoid the ICE the SSA_NAME would need a naturally > > aligned type, maybe replace it somehow in make_ssa_name_fn ... > > Ah, OK - only now looked at the testcase ;) Yes, I think for > registers we should ignore decl/type alignment and _always_ > use the natural (mode) alignment. That is, > > static unsigned int > align_local_variable (tree decl, bool really_expand) > { > unsigned int align; > > if (TREE_CODE (decl) == SSA_NAME) > align = TYPE_ALIGN (TREE_TYPE (decl)); > > should probably use GET_MODE_ALIGNMENT (TYPE_MODE (TREE_TYPE (decl))) > unless it is a BLKmode var. There's a duplicate code in > expand_one_stack_var_1, not sure why it special-cases SSA_NAMEs there. > Ah, yes, using a similar strategy as we did in r274986 where we aligned param_decls, I would say this completely untested patch goes in the same direction: diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c index f3f17d3..030d0cb 100644 --- a/gcc/cfgexpand.c +++ b/gcc/cfgexpand.c @@ -366,7 +366,18 @@ align_local_variable (tree decl, bool really_expand) unsigned int align; if (TREE_CODE (decl) == SSA_NAME) - align = TYPE_ALIGN (TREE_TYPE (decl)); + { + tree type = TREE_TYPE (decl); + machine_mode mode = TYPE_MODE (type); + + align = TYPE_ALIGN (type); + if (mode != BLKmode + && align < GET_MODE_ALIGNMENT (mode) + && ((optab_handler (movmisalign_optab, mode) + != CODE_FOR_nothing) + || targetm.slow_unaligned_access (mode, align))) + align = GET_MODE_ALIGNMENT (mode); + } else { align = LOCAL_DECL_ALIGNMENT (decl); @@ -1022,6 +1033,17 @@ expand_one_stack_var_at (tree decl, rtx base, unsigned base_align, } set_rtl (decl, x); + + if (TREE_CODE (decl) == SSA_NAME + && GET_MODE (x) != BLKmode + && MEM_ALIGN (x) < GET_MODE_ALIGNMENT (GET_MODE (x)) + && ((optab_handler (movmisalign_optab, GET_MODE (x)) + != CODE_FOR_nothing) + || targetm.slow_unaligned_access (GET_MODE (x), MEM_ALIGN (x)))) + { + gcc_checking_assert (GET_MODE_ALIGNMENT (GET_MODE (x)) <= base_align); + set_mem_align (x, GET_MODE_ALIGNMENT (GET_MODE (x))); + } } class stack_vars_data @@ -1327,13 +1349,11 @@ expand_one_stack_var_1 (tree var) { tree type = TREE_TYPE (var); size = tree_to_poly_uint64 (TYPE_SIZE_UNIT (type)); - byte_align = TYPE_ALIGN_UNIT (type); } else - { - size = tree_to_poly_uint64 (DECL_SIZE_UNIT (var)); - byte_align = align_local_variable (var, true); - } + size = tree_to_poly_uint64 (DECL_SIZE_UNIT (var)); + + byte_align = align_local_variable (var, true); /* We handle highly aligned variables in expand_stack_vars. */ gcc_assert (byte_align * BITS_PER_UNIT <= MAX_SUPPORTED_STACK_ALIGNMENT); > Also, when an SSA name gets a stack location, we should instead use > the underlying decl for the MEM_EXPR, not the SSA name. > At least the MEM_EXPRs from this test case don't do that. > > But isn't it possible that expand_expr_real_1 > > returns the original unaligned decl here? > > > > case GIMPLE_SINGLE_RHS: > > { > > r = expand_expr_real (gimple_assign_rhs1 (g), target, > > tmode, modifier, alt_rtl, > > inner_reference_p); > > break; > > } > > default: > > gcc_unreachable (); > > } > > set_curr_insn_location (saved_loc); > > if (REG_P (r) && !REG_EXPR (r)) > > set_reg_attrs_for_decl_rtl (SSA_NAME_VAR (exp), r); > > return r; My only concern left is if this code path might somehow return an misaligned MEM_P from that gimple_assign_rhs, but probably there is an obvious reason why that may never happen.