https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117424
--- Comment #12 from Richard Biener <rguenth at gcc dot gnu.org> ---
t.c:15:35: note: vect_compute_data_ref_alignment:
t.c:15:35: note: force alignment of *_3
...
t.c:15:35: note: ==> examining statement: _4 = *_3;
t.c:15:35: note: vect_model_load_cost: aligned.
the vectorizer over-aligns 'b' in ensure_base_align but RTL expansion
allocates the variable to
(gdb) p $rsp + 0xc
$1 = (void *) 0x7fffffffde0c
besides that, tree_could_trap_p is overly optimistic:
case MEM_REF:
...
if (TREE_CODE (TREE_OPERAND (expr, 0)) == ADDR_EXPR)
{
...
tree size = DECL_SIZE_UNIT (base);
if (size == NULL_TREE
|| !poly_int_tree_p (size)
|| maybe_le (wi::to_poly_offset (size), off))
return true;
/* Now we are sure the first byte of the access is inside
the object. */
return false;
but taking into account alignment it could still conclude the access doesn't
trap. tree_could_trap_p does not track the overall offset from all
handled-components, so it can only be optimistic in case the MEM_REF
would be fully within the decl.
So there are two bugs here - RTL expansion not honoring stack var alignment
and tree_could_trap_p being overly optimistic.
RTL expansion drops user alignment on the floor by expanding the variable
as a register and later we do
12147 /* Otherwise, if this is a constant or the object is not in
memory
12148 and need be, put it there. */
12149 else if (CONSTANT_P (op0) || (!MEM_P (op0) && must_force_mem))
12150 {
12151 memloc = assign_temp (TREE_TYPE (tem), 1, 1);
but that assigns a stack temp for 'int' without the required over-alignment
of the MEM. This is because we go BIT_FIELD_REF expansion again which
doesn't really honor an over-aligned access as we build it and later we
restore the slots alignment based on the BIT_FIELD_REF type. IMO the error
is again in the
/* Handle expansion of non-aliased memory with non-BLKmode. That
might end up in a register. */
if (mem_ref_refers_to_non_mem_p (exp))
{
if (TYPE_MODE (type) == BLKmode || maybe_lt (offset, 0))
{
temp = assign_stack_temp (DECL_MODE (base),
GET_MODE_SIZE (DECL_MODE (base)));
store_expr (base, temp, 0, false, false);
temp = adjust_address (temp, TYPE_MODE (type), offset);
if (TYPE_MODE (type) == BLKmode)
set_mem_size (temp, int_size_in_bytes (type));
return temp;
}
exp = build3 (BIT_FIELD_REF, type, base, TYPE_SIZE (type),
bitsize_int (offset * BITS_PER_UNIT));
REF_REVERSE_STORAGE_ORDER (exp) = reverse;
return expand_expr (exp, target, tmode, modifier);
path. The BIT_FIELD_REF path hopes to avoid allocating a temporary on the
stack, but as seen this doesn't work with respect to alignment (neither
would the mode based temporary allocation, but that could be fixed).