This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug tree-optimization/70729] Loop marked with omp simd pragma is not vectorized


https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70729

--- Comment #29 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
The #c27 r237844 change looks bogus to me.
First of all, IMNSHO you can argue this way only if ref is a reference seen in
loop LOOP, which is the case of e.g. *.omp_data_i_23(D).a ref in simd3.f90 -O2
-fopenmp -msse2, but not the D.3815[0] case tested during can_sm_ref_p - the
D.3815[0] = 0; as well as something = D.3815[0]; stmt found in the outer loop
obviously can be dependent on many of the loads and/or stores in the loop, be
it "omp simd array" or not.
Say for
void
foo (int *p, int *q)
{
  #pragma omp simd
  for (int i = 0; i < 1024; i++)
    p[i] += q[0];
}
sure, q[0] can't alias p[0] ... p[1022], the earlier iterations could write
something that changes its value, and then it would behave differently from
using VF = 1024, where everything is performed in parallel.
Though, actually, it can alias, just it would have to write the same value as
was there.  So, if this is used to determine if it is safe to hoist the load
before the loop, it is fine, if it is used to determine if &q[0] >= &p[0] &&
&q[0] <= &p[1023], then it is not fine.

For aliasing of q[0] and p[1023], I don't see why they couldn't alias in a
valid program.  #pragma omp simd I think guarantees that the last iteration is
executed last, it isn't necessarily executed last alone, it could be, or
together with one before last iteration, or (for simdlen INT_MAX) even all
iterations can be done concurrently, in hw or sw, so it is fine if it is
transformed into:
  int temp[1024], temp2[1024], temp3[1024];
  for (int i = 0; i < 1024; i++)
    temp[i] = p[i];
  for (int i = 0; i < 1024; i++)
    temp2[i] = q[0];
  /* The above two loops can be also swapped, or intermixed.  */
  for (int i = 0; i < 1024; i++)
    temp3[i] = temp[i] + temp2[i];
  for (int i = 0; i < 1024; i++)
    p[i] = temp3[i];
  /* Or the above loop reversed etc. */

If you have:
int
bar (int *p, int *q)
{
  q[0] = 0;
  #pragma omp simd
  for (int i = 0; i < 1024; i++)
    p[i]++;
  return q[0];
}
i.e. something similar to what misbehaves in simd3.f90 with the change, then
the answer is that q[0] isn't guaranteed to be independent of any references in
the simd loop.

BTW, the r237844 change is badly formatted, missing spaces before (, too long
lines...

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]