re PR middle-end/71734 (FAIL: libgomp.fortran/simd4.f90 -O3 -g execution test)
authorYuri Rumyantsev <ysrumyan@gmail.com>
Thu, 28 Jul 2016 14:19:18 +0000 (14:19 +0000)
committerIlya Enkovich <ienkovich@gcc.gnu.org>
Thu, 28 Jul 2016 14:19:18 +0000 (14:19 +0000)
gcc/

2016-07-28  Yuri Rumyantsev  <ysrumyan@gmail.com>

PR tree-optimization/71734
* tree-ssa-loop-im.c (ref_indep_loop_p_1): Pass value of safelen
attribute instead of REF_LOOP and use it.
(ref_indep_loop_p_2): Use SAFELEN argument instead of REF_LOOP and
set it for Loops having non-zero safelen attribute.
(ref_indep_loop_p): Pass zero as initial value for safelen.

gcc/testsuite/

2016-07-28  Yuri Rumyantsev  <ysrumyan@gmail.com>

PR tree-optimization/71734
        * g++.dg/vect/pr70729-nest.cc: New test.

From-SVN: r238817

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/vect/pr70729-nest.cc [new file with mode: 0644]
gcc/tree-ssa-loop-im.c

index c4ffd7877a9c7e0f2a7a93b1339749498de4f53c..6bd694ab78dea7edc752a6ed7fd01a53be6b46da 100644 (file)
@@ -1,3 +1,12 @@
+2016-07-28  Yuri Rumyantsev  <ysrumyan@gmail.com>
+
+       PR tree-optimization/71734
+       * tree-ssa-loop-im.c (ref_indep_loop_p_1): Pass value of safelen
+       attribute instead of REF_LOOP and use it.
+       (ref_indep_loop_p_2): Use SAFELEN argument instead of REF_LOOP and
+       set it for Loops having non-zero safelen attribute.
+       (ref_indep_loop_p): Pass zero as initial value for safelen.
+
 2016-07-28  Ilya Enkovich  <ilya.enkovich@intel.com>
 
        PR middle-end/72657
index 343293c592e85016491e5a4ee00a96522ad23311..1db9f6e563495592447d6784f5ed9c6773b2cf84 100644 (file)
@@ -1,3 +1,8 @@
+2016-07-28  Yuri Rumyantsev  <ysrumyan@gmail.com>
+
+       PR tree-optimization/71734
+        * g++.dg/vect/pr70729-nest.cc: New test.
+
 2016-07-28  Renlin Li  <renlin.li@arm.com>
 
        Revert
diff --git a/gcc/testsuite/g++.dg/vect/pr70729-nest.cc b/gcc/testsuite/g++.dg/vect/pr70729-nest.cc
new file mode 100644 (file)
index 0000000..96171e5
--- /dev/null
@@ -0,0 +1,79 @@
+// { dg-do compile }
+// { dg-additional-options "-ffast-math -fopenmp-simd" }
+// { dg-additional-options "-msse2" { target x86_64-*-* i?86-*-* } }
+
+inline void* my_alloc (__SIZE_TYPE__ bytes) {void *ptr; __builtin_posix_memalign (&ptr, bytes, 128);}
+inline void my_free (void* memory) {__builtin_free (memory);}
+float W[100];
+
+template <typename T>
+class Vec
+{
+  const int isize;
+       T* data;
+
+public:
+
+  Vec (int n) : isize (n) {data = (T*)my_alloc (isize*sizeof (T));}
+  ~Vec () {my_free(data);}
+
+  Vec& operator = (const Vec& other)   
+    {
+      if (this != &other)
+       __builtin_memcpy (data, other.data, isize*sizeof (T));
+      return *this;
+    }
+
+  T& operator [] (int i) {return data[i];}
+  const T& operator [] (int i) const {return data[i];}
+  T& at (int i)  {return data[i];}
+  const T& at (int i) const {return data[i];}
+
+  operator T* ()  {return data;}
+  int size () const {return isize;}
+};
+
+template <typename T>                                  
+class Cl
+{
+public:
+
+  Cl (int n, int m);
+  const int N, M;
+  Vec<T> v_x, v_y;
+  Vec<int> v_i;
+  Vec<float> v_z;
+};
+
+struct Ss
+{
+    const int S_n, S_m;
+    Cl<float> v1;
+    float* C1;
+    float* C2;
+    Ss (int n1, int n2): S_n(n1), S_m(n2), v1(n1, n2)
+      {
+       C1 = new float[n1 * 3];
+       C2 = new float[n2 * 4]; 
+      }
+
+    ~Ss () { delete C1; delete C2;}
+   void foo (int n);
+};
+void Ss::foo (int n)
+{
+  float w;
+  for (int j = 0; j < n; j++)
+    {
+      w = W[j];
+#pragma omp simd
+      for (int i = 0; i < S_n; i++)
+       {
+         float w1 = C2[S_n + i] * w;
+         v1.v_i[i] += (int)w1;
+         C1[S_n + i] += w1;
+       }
+    }
+}
+// { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" { target x86_64-*-* i?86-*-* } } }
index c5aaef325052a5ad9f414803fb67853ec7ac4887..947724bceff3ea8b01fd4b3049ccf339fdde6923 100644 (file)
@@ -2113,7 +2113,7 @@ record_dep_loop (struct loop *loop, im_mem_ref *ref, bool stored_p)
    references in LOOP.  */
 
 static bool
-ref_indep_loop_p_1 (struct loop *ref_loop, struct loop *loop,
+ref_indep_loop_p_1 (int safelen, struct loop *loop,
                    im_mem_ref *ref, bool stored_p)
 {
   bitmap refs_to_check;
@@ -2129,12 +2129,12 @@ ref_indep_loop_p_1 (struct loop *ref_loop, struct loop *loop,
   if (bitmap_bit_p (refs_to_check, UNANALYZABLE_MEM_ID))
     return false;
 
-  if (ref_loop->safelen > 1)
+  if (safelen > 1)
     {
       if (dump_file && (dump_flags & TDF_DETAILS))
        {
-         fprintf (dump_file,"REF is independent in ref_loop#%d\n",
-                  ref_loop->num);
+         fprintf (dump_file,"REF is independent due to safelen %d\n",
+                  safelen);
          print_generic_expr (dump_file, ref->mem.ref, TDF_SLIM);
          fprintf (dump_file, "\n");
        }
@@ -2156,7 +2156,7 @@ ref_indep_loop_p_1 (struct loop *ref_loop, struct loop *loop,
    results.  */
 
 static bool
-ref_indep_loop_p_2 (struct loop *ref_loop, struct loop *loop,
+ref_indep_loop_p_2 (int safelen, struct loop *loop,
                    im_mem_ref *ref, bool stored_p)
 {
   stored_p |= (ref->stored && bitmap_bit_p (ref->stored, loop->num));
@@ -2166,15 +2166,18 @@ ref_indep_loop_p_2 (struct loop *ref_loop, struct loop *loop,
   if (bitmap_bit_p (&ref->dep_loop, LOOP_DEP_BIT (loop->num, stored_p)))
     return false;
 
+  if (loop->safelen > safelen)
+    safelen = loop->safelen;
+
   struct loop *inner = loop->inner;
   while (inner)
     {
-      if (!ref_indep_loop_p_2 (ref_loop, inner, ref, stored_p))
+      if (!ref_indep_loop_p_2 (safelen, inner, ref, stored_p))
        return false;
       inner = inner->next;
     }
 
-  bool indep_p = ref_indep_loop_p_1 (ref_loop, loop, ref, stored_p);
+  bool indep_p = ref_indep_loop_p_1 (safelen, loop, ref, stored_p);
 
   if (dump_file && (dump_flags & TDF_DETAILS))
     fprintf (dump_file, "Querying dependencies of ref %u in loop %d: %s\n",
@@ -2213,7 +2216,7 @@ ref_indep_loop_p (struct loop *loop, im_mem_ref *ref)
 {
   gcc_checking_assert (MEM_ANALYZABLE (ref));
 
-  return ref_indep_loop_p_2 (loop, loop, ref, false);
+  return ref_indep_loop_p_2 (0, loop, ref, false);
 }
 
 /* Returns true if we can perform store motion of REF from LOOP.  */