https://gcc.gnu.org/bugzilla/show_bug.cgi?id=127049
Richard Biener <rguenth at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Status|NEW |ASSIGNED
Assignee|unassigned at gcc dot gnu.org |rguenth at gcc dot
gnu.org
--- Comment #4 from Richard Biener <rguenth at gcc dot gnu.org> ---
struct LeafBucket {
int coords[3][32];
};
void foo (unsigned long size, struct LeafBucket *bucket)
{
bucket = __builtin_assume_aligned (bucket, 64);
for (unsigned long i = size; i < 32; ++i)
for (unsigned long d = 0; d < 3; ++d)
bucket->coords[d][i] = 1;
}
is analyzed correctly (-fdisable-tree-cunrolli). Likewise
struct LeafBucket {
int coords[3][32];
unsigned int ids[32];
};
struct LeafBucket bucket __attribute__((aligned(64)));
void foo (unsigned long size)
{
for (unsigned long i = size; i < 32; ++i)
for (unsigned long d = 0; d < 3; ++d)
bucket.coords[d][i] = 1;
}
It would be nice to have a smaller testcase w/o so much of the standard
library.
But yes, it seems somehow the offset from 'size' is not honored. We have
(gdb) p *dr_info->dr
$3 = {stmt = <gimple_assign 0x7ffff3b52c60>, ref = <array_ref 0x7ffff3ac3620>,
aux = 0x0, is_read = false, is_conditional_in_stmt = false, alias = {
ptr_info = 0x7ffff3a62930}, innermost = {
base_address = <pointer_plus_expr 0x7ffff3b6d0c8>,
offset = <nop_expr 0x7ffff3b68dc0>, init = <integer_cst 0x7ffff3b24e28>,
step = <integer_cst 0x7ffff3b24ee8>, base_alignment = 64,
base_misalignment = 0, offset_alignment = 4, step_alignment = 128},
indices = {base_object = <mem_ref 0x7ffff3b636e0>, access_fns = {
m_vec = 0x58109e0 = {0x7ffff3b6d118, 0x7ffff3b6cb68, 0x7ffff761b378}},
unconstrained_base = false}, alt_indices = {base_object = <tree 0x0>,
access_fns = {m_vec = 0x0}, unconstrained_base = false}}
see offset_alignment. But we only check drb for that (vect_dr_behavior):
(gdb) p *drb
$5 = {base_address = <pointer_plus_expr 0x7ffff3b6db68>,
offset = <integer_cst 0x7ffff6011a38>, init = <integer_cst 0x7ffff3b24e28>,
step = <integer_cst 0x7ffff60119c0>, base_alignment = 64,
base_misalignment = 0, offset_alignment = 128, step_alignment = 4}
which have different base addresses:
(gdb) p debug_generic_expr (drb->base_address)
(struct element_type &) _54 + (((sizetype) node_idx_512 - (sizetype) _589) *
128 + (sizetype) size_564) * 4
(gdb) p debug_generic_expr (dr_info->dr.innermost.base_address)
_54 + ((sizetype) node_idx_512 - (sizetype) _589) * 512
(gdb) p debug_generic_expr (dr_info->dr.innermost.offset)
(ssizetype) ((sizetype) i_492 * 4)
so to me it seems that 'drb' has somehow wrong alignments and
if (drb->offset_alignment < vect_align_c
|| !step_preserves_misalignment_p
/* We need to know whether the step wrt the vectorized loop is
negative when computing the starting misalignment below. */
|| TREE_CODE (drb->step) != INTEGER_CST)
{
if (dump_enabled_p ())
dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
"Unknown alignment for access: %T\n", ref);
return;
should have catched this or drb->misalignment should be set (size is unknown,
so alignment should be 4).
Oh, so I think the issue is that we do
/* Build a reference to the first location accessed by the
inner loop: *(BASE + INIT + OFFSET). By construction,
this address must be invariant in the inner loop, so we
can consider it as being used in the outer loop. */
tree base = unshare_expr (DR_BASE_ADDRESS (dr));
tree offset = unshare_expr (DR_OFFSET (dr));
tree init = unshare_expr (DR_INIT (dr));
tree init_offset = fold_build2 (PLUS_EXPR, TREE_TYPE (offset),
init, offset);
tree init_addr = fold_build_pointer_plus (base, init_offset);
tree init_ref = build_fold_indirect_ref (init_addr);
if (dump_enabled_p ())
dump_printf_loc (MSG_NOTE, vect_location,
"analyze in outer loop: %T\n", init_ref);
opt_result res
= dr_analyze_innermost (&STMT_VINFO_DR_WRT_VEC_LOOP (stmt_info),
init_ref, loop, stmt_info->stmt);
and dr_analyze_innermost does get_inner_reference and
get_object_alignment_1 on the base (which it returns literally).
But we build
<indirect_ref 0x7ffff3b6e0a0
type <record_type 0x7ffff420c348 element_type cxx-odr-p type_5 type_6 BLK
size <integer_cst 0x7ffff4672cd8 constant 4096>
unit-size <integer_cst 0x7ffff4672cc0 constant 512>
user align:512 warn_if_not_align:0 symtab:0 alias-set -1 canonical-type
0x7ffff4690f18
which is of course not correct.