Richard Biener <richard.guent...@gmail.com> writes: > On Mon, Jun 26, 2017 at 1:50 PM, Richard Sandiford > <richard.sandif...@linaro.org> wrote: >> Richard Biener <richard.guent...@gmail.com> writes: >>> On Mon, Jun 26, 2017 at 1:14 PM, Richard Sandiford >>> <richard.sandif...@linaro.org> wrote: >>>> I don't think the problem is the lack of a cap. In the test case we >>>> see that: >>>> >>>> 1. B is known at compile time to be X * vecsize + Y when considered in >>>> isolation, because the base alignment derived from its DR_REF >= >>>> vecsize. >>>> So DR_MISALIGNMENT (B) == Y. >>>> >>>> 2. A's misalignment wrt vecsize is not known at compile time when >>>> considered in isolation, because no useful base alignment can be >>>> derived from its DR_REF. (The DR_REF is to a plain int rather than >>>> to a structure with a high alignment.) So DR_MISALIGNMENT (A) == -1. >>>> >>>> 3. A and B when considered as a pair trivially have the same misalignment >>>> wrt vecsize, for the reasons above. >>>> >>>> Each of these results is individually correct. The problem is that the >>>> assert is conflating two things: it's saying that if we know two datarefs >>>> have the same misaligment, we must either be able to calculate a >>>> compile-time misalignment for both datarefs in isolation, or we must >>>> fail to calculate a compile-time misalignment for both datarefs in >>>> isolation. That isn't true: it's valid to have situations in which the >>>> compile-time misalignment is known for one dataref in isolation but not >>>> for the other. >>> >>> True. So the assert should then become >>> >>> gcc_assert (! known_alignment_for_access_p (dr) >>> || DR_MISALIGNMENT (dr) / dr_size == >>> DR_MISALIGNMENT (dr_peel) / dr_peel_size); >>> >>> ? >> >> I think it would need to be: >> >> gcc_assert (!known_alignment_for_access_p (dr) >> || !known_alignment_for_access_p (dr_peel) >> || (DR_MISALIGNMENT (dr) / dr_size >> == DR_MISALIGNMENT (dr_peel) / dr_peel_size)); > > I think for !known_alignment_for_access_p (dr_peel) the assert doesn't make > any sense (DR_MISALIGNMENT is -1), so yes, you are right. > >> But yeah, that would work too. The idea with the assert in the patch was >> that for unconditional references we probably *do* want to try to compute >> the same compile-time misalignment, but for optimisation reasons rather >> than correctness. Maybe that's more properly a gcc_checking_assert >> though, since nothing goes wrong if it fails. So perhaps: > > We shouldn't have asserts for optimization reasons, even with checking > IMHO.
OK. >> gcc_checking_assert (DR_IS_CONDITIONAL_IN_STMT (dr) >> || DR_IS_CONDITIONAL_IN_STMT (dr_peel) >> || (known_alignment_for_access_p (dr) >> == known_alignment_for_access_p (dr_peel))); >> >> as a follow-on assert. >> >> Should I split it into two patches, one to change the gcc_assert and >> another to add the optimisation? > > Yes please. Here's the patch to relax the assert. I'll post the rest in a new thread. Tested as before. OK to install? Thanks, Richard 2017-06-28 Richard Sandiford <richard.sandif...@linaro.org> gcc/ PR tree-optimization/81136 * tree-vect-data-refs.c (vect_update_misalignment_for_peel): Only assert that two references with the same misalignment have the same compile-time misalignment if those compile-time misalignments are known. gcc/testsuite/ PR tree-optimization/81136 * gcc.dg/vect/pr81136.c: New test. Index: gcc/tree-vect-data-refs.c =================================================================== --- gcc/tree-vect-data-refs.c 2017-06-26 19:41:19.549571836 +0100 +++ gcc/tree-vect-data-refs.c 2017-06-28 14:25:58.811888377 +0100 @@ -906,8 +906,10 @@ vect_update_misalignment_for_peel (struc { if (current_dr != dr) continue; - gcc_assert (DR_MISALIGNMENT (dr) / dr_size == - DR_MISALIGNMENT (dr_peel) / dr_peel_size); + gcc_assert (!known_alignment_for_access_p (dr) + || !known_alignment_for_access_p (dr_peel) + || (DR_MISALIGNMENT (dr) / dr_size + == DR_MISALIGNMENT (dr_peel) / dr_peel_size)); SET_DR_MISALIGNMENT (dr, 0); return; } Index: gcc/testsuite/gcc.dg/vect/pr81136.c =================================================================== --- /dev/null 2017-06-28 07:28:02.991792729 +0100 +++ gcc/testsuite/gcc.dg/vect/pr81136.c 2017-06-28 14:25:58.810888422 +0100 @@ -0,0 +1,16 @@ +/* { dg-do compile } */ + +struct __attribute__((aligned (32))) +{ + char misaligner; + int foo[100]; + int bar[100]; +} *a; + +void +fn1 (int n) +{ + int *b = a->foo; + for (int i = 0; i < n; i++) + a->bar[i] = b[i]; +}