From: Yuri Rumyantsev Date: Thu, 28 Jul 2016 14:19:18 +0000 (+0000) Subject: re PR middle-end/71734 (FAIL: libgomp.fortran/simd4.f90 -O3 -g execution test) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=513d866d5b3b2b62fce9ad91fd032a02f17ed6eb;p=gcc.git re PR middle-end/71734 (FAIL: libgomp.fortran/simd4.f90 -O3 -g execution test) gcc/ 2016-07-28 Yuri Rumyantsev 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 PR tree-optimization/71734 * g++.dg/vect/pr70729-nest.cc: New test. From-SVN: r238817 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c4ffd7877a9..6bd694ab78d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2016-07-28 Yuri Rumyantsev + + 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 PR middle-end/72657 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 343293c592e..1db9f6e5634 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2016-07-28 Yuri Rumyantsev + + PR tree-optimization/71734 + * g++.dg/vect/pr70729-nest.cc: New test. + 2016-07-28 Renlin Li 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 index 00000000000..96171e5ec94 --- /dev/null +++ b/gcc/testsuite/g++.dg/vect/pr70729-nest.cc @@ -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 +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 +class Cl +{ +public: + + Cl (int n, int m); + const int N, M; + Vec v_x, v_y; + Vec v_i; + Vec v_z; +}; + +struct Ss +{ + const int S_n, S_m; + Cl 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-*-* } } } diff --git a/gcc/tree-ssa-loop-im.c b/gcc/tree-ssa-loop-im.c index c5aaef32505..947724bceff 100644 --- a/gcc/tree-ssa-loop-im.c +++ b/gcc/tree-ssa-loop-im.c @@ -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. */