https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96075
Richard Biener <rguenth at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Ever confirmed|0 |1 Assignee|unassigned at gcc dot gnu.org |rguenth at gcc dot gnu.org CC| |rsandifo at gcc dot gnu.org Status|UNCONFIRMED |ASSIGNED Last reconfirmed| |2020-07-06 --- Comment #3 from Richard Biener <rguenth at gcc dot gnu.org> --- So we end up calling get_negative_load_store_type for this group which seems to only handle contiguous accesses but this one is single element interleaving aka contiguous with gap. vect_supportable_dr_alignment returns dr_aligned which is seemingly OK for #(Data Ref: # bb: 3 # stmt: _4 = y[_2]; # ref: y[_2]; # base_object: y; # Access function 0: {1022, +, -2}_1 but then as said the vls type is computed as VMAT_CONTIGUOUS_REVERSE where we eventually do if (memory_access_type == VMAT_CONTIGUOUS_DOWN || memory_access_type == VMAT_CONTIGUOUS_REVERSE) offset = size_int (-TYPE_VECTOR_SUBPARTS (vectype) + 1); invalidating that alignment... /* If this is a backward running DR then first access in the larger vectype actually is N-1 elements before the address in the DR. Adjust misalign accordingly. */ if (tree_int_cst_sgn (drb->step) < 0) /* PLUS because STEP is negative. */ misalignment += ((TYPE_VECTOR_SUBPARTS (vectype) - 1) * TREE_INT_CST_LOW (drb->step)); looks a bit odd since this does not offset by N-1 elements but N-1 "steps" (where a step is two elements in this case). Here's probably where the problem resides. On the GCC 7 branch we see /* If this is a backward running DR then first access in the larger vectype actually is N-1 elements before the address in the DR. Adjust misalign accordingly. */ if (tree_int_cst_sgn (step) < 0) { tree offset = ssize_int (TYPE_VECTOR_SUBPARTS (vectype) - 1); /* DR_STEP(dr) is the same as -TYPE_SIZE of the scalar type, otherwise we wouldn't be here. */ offset = fold_build2 (MULT_EXPR, ssizetype, offset, step); /* PLUS because STEP was negative. */ misalign = size_binop (PLUS_EXPR, misalign, offset); } and mind that comment about DR_STEP isn't true ... diff --git a/gcc/tree-vect-data-refs.c b/gcc/tree-vect-data-refs.c index 2462276e7c2..959c2d3378f 100644 --- a/gcc/tree-vect-data-refs.c +++ b/gcc/tree-vect-data-refs.c @@ -1109,7 +1109,7 @@ vect_compute_data_ref_alignment (vec_info *vinfo, dr_vec_info *dr_info) if (tree_int_cst_sgn (drb->step) < 0) /* PLUS because STEP is negative. */ misalignment += ((TYPE_VECTOR_SUBPARTS (vectype) - 1) - * TREE_INT_CST_LOW (drb->step)); + * -TREE_INT_CST_LOW (TYPE_SIZE_UNIT (TREE_TYPE (vectype)))); unsigned int const_misalignment; if (!known_misalignment (misalignment, vect_align_c, &const_misalignment)) fixes that.