On Fri, Oct 28, 2011 at 02:01:36PM +0400, Kirill Yukhin wrote:
> this looks really cool. I have a liitle question, since I do not
> understand vectorizer as good.
> 
> Say, we have a snippet:
> int *p;
> int idx[N];
> int arr[M];
> for (...)
> {
>   p[i%4] += arr[idx[I]];
> }
> As far as I understand, we cannot do gather we, since p may point to
> somewere in arr,
> and, idx may took it twice.
> E.g. lets take
>   idx = {0, 1, 1, 2, 3, 4, 5, 6}
>   arr = {0, 1, 0, 0, 0, 0, 0, 0}
>   p = arr;
> Correct case will have, we'll have something like arr = {0, 2, 2, 0,...}
> If we'll have gather, arr may look like                    arr = {0,
> 2, 1, 0, ...}
> 
> So my question, does your patch catch such a cases?

Yes, it does.  It should be caught by the vect_analyze_data_refs
part after vect_check_gather succeeds, which updates all the data
dependence relations with the new dr, and if the other dr in the
dependence relation has DR_IS_WRITE, then if dr_may_alias_p
in initialize_data_dependent_relation didn't say that those two
aren't known not to alias, we set bad and give up on vectorizing
the loop.  I'm doing it there, because the vectorizer would otherwise
attempt later on to version for aliasing, but for gather it is not possible
(or sometimes is at least much more difficult) to add such a runtime
check.  For the above it will not say chrec_known and thus we give up.

A very unfortunate thing is that dr_may_alias_p doesn't use TBAA
if one dr is a write and the other is a read, I think that is because
of placement new.  It would be nice if we could use TBAA, at least
in some cases (e.g. when you read pointers/ints through gather
and store floats/doubles, or vice versa etc.).  I wonder if we couldn't
resurrect a gimple stmt for placement new, and simply if the loop to be
vectorized doesn't contain any of those stmts (and doesn't call any
functions or just calls const/pure functions - after all otherwise
we wouldn't vectorize it anyway), then we could use TBAA even for that.
But that is definitely out of the scope of this patch.
We could then also vectorize:
void
foo (int *p, float *q)
{
  int i;
  for (i = 0; i < 1024; i++)
    p[i] = q[i] * 2;
}
without versioning for aliasing, etc., and we wouldn't do that if there is
a placement new in that loop somewhere which could make it invalid.

        Jakub

Reply via email to