1b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar// RUN: %clang_cc1 -verify -fopenmp -ast-print %s | FileCheck %s
2b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -emit-pch -o %t %s
3b6d6993e6e6d3daf4d9876794254d20a134e37c2Pirama Arumuga Nainar// RUN: %clang_cc1 -fopenmp -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
4176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// expected-no-diagnostics
5176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
6176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines#ifndef HEADER
7176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines#define HEADER
8176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
9176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesvoid foo() {}
104967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
114967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarstruct S1 {
124967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  S1() : a(0) {}
134967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  S1(int v) : a(v) {}
144967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  int a;
154967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  typedef int type;
164967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar};
174967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
184967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainartemplate <typename T>
194967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarclass S7 : public T {
204967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarprotected:
214967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  T a;
224967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  S7() : a(0) {}
234967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
244967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarpublic:
254967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  S7(typename T::type v) : a(v) {
264967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar#pragma omp parallel for simd private(a) private(this->a) private(T::a)
274967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    for (int k = 0; k < a.a; ++k)
284967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      ++this->a.a;
294967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
304967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  S7 &operator=(S7 &s) {
314967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar#pragma omp parallel for simd private(a) private(this->a)
324967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    for (int k = 0; k < s.a.a; ++k)
334967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      ++s.a.a;
344967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    return *this;
354967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
364967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar};
374967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
384967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar// CHECK: #pragma omp parallel for simd private(this->a) private(this->a) private(this->S1::a)
394967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar// CHECK: #pragma omp parallel for simd private(this->a) private(this->a) private(T::a)
404967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar// CHECK: #pragma omp parallel for simd private(this->a) private(this->a)
414967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
424967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarclass S8 : public S7<S1> {
434967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  S8() {}
444967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
454967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarpublic:
464967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  S8(int v) : S7<S1>(v){
474967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar#pragma omp parallel for simd private(a) private(this->a) private(S7<S1>::a)
484967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    for (int k = 0; k < a.a; ++k)
494967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      ++this->a.a;
504967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
514967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  S8 &operator=(S8 &s) {
524967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar#pragma omp parallel for simd private(a) private(this->a)
534967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    for (int k = 0; k < s.a.a; ++k)
544967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      ++s.a.a;
554967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    return *this;
564967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
574967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar};
584967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
594967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar// CHECK: #pragma omp parallel for simd private(this->a) private(this->a) private(this->S7<S1>::a)
604967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar// CHECK: #pragma omp parallel for simd private(this->a) private(this->a)
614967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
62176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesint g_ind = 1;
63176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinestemplate<class T, class N> T reduct(T* arr, N num) {
64176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  N i;
65176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  N ind;
66176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  N myind;
67176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  T sum = (T)0;
68176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// CHECK: T sum = (T)0;
6987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar#pragma omp parallel for simd private(myind, g_ind), linear(ind), aligned(arr) if (parallel :num)
7087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar// CHECK-NEXT: #pragma omp parallel for simd private(myind,g_ind) linear(ind) aligned(arr) if(parallel: num)
71176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  for (i = 0; i < num; ++i) {
72176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    myind = ind;
73176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    T cur = arr[myind];
74176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    ind += g_ind;
75176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    sum += cur;
76176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  }
77176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines}
78176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
79176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinestemplate<class T> struct S {
80176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  S(const T &a)
81176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    :m_a(a)
82176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  {}
83176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  T result(T *v) const {
84176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    T res;
85176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    T val;
86176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    T lin = 0;
87176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// CHECK: T res;
88176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// CHECK: T val;
89176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// CHECK: T lin = 0;
9087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar    #pragma omp parallel for simd private(val)  safelen(7) linear(lin : -5) lastprivate(res) simdlen(5) if(7)
9187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar// CHECK-NEXT: #pragma omp parallel for simd private(val) safelen(7) linear(lin: -5) lastprivate(res) simdlen(5) if(7)
92176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    for (T i = 7; i < m_a; ++i) {
93176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      val = v[i-7] + m_a;
94176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      res = val;
95176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      lin -= 5;
96176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    }
97176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    const T clen = 3;
98176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// CHECK: T clen = 3;
994967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    #pragma omp parallel for simd safelen(clen-1) simdlen(clen-1) ordered
1004967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar// CHECK-NEXT: #pragma omp parallel for simd safelen(clen - 1) simdlen(clen - 1) ordered
101176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    for(T i = clen+2; i < 20; ++i) {
102176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// CHECK-NEXT: for (T i = clen + 2; i < 20; ++i) {
103176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      v[i] = v[v-clen] + 1;
104176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// CHECK-NEXT: v[i] = v[v - clen] + 1;
105176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    }
106176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// CHECK-NEXT: }
107176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    return res;
108176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  }
109176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  ~S()
110176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  {}
111176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  T m_a;
112176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines};
113176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
114176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinestemplate<int LEN> struct S2 {
115176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  static void func(int n, float *a, float *b, float *c) {
116176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    int k1 = 0, k2 = 0;
11787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar#pragma omp parallel for simd safelen(LEN) linear(k1,k2:LEN) aligned(a:LEN) simdlen(LEN)
118176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    for(int i = 0; i < n; i++) {
119176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      c[i] = a[i] + b[i];
120176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      c[k1] = a[k1] + b[k1];
121176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      c[k2] = a[k2] + b[k2];
122176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      k1 = k1 + LEN;
123176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      k2 = k2 + LEN;
124176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    }
125176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  }
126176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines};
127176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
128176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// S2<4>::func is called below in main.
129176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// CHECK: template <int LEN = 4> struct S2 {
130176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// CHECK-NEXT: static void func(int n, float *a, float *b, float *c)     {
131176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// CHECK-NEXT:   int k1 = 0, k2 = 0;
13287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar// CHECK-NEXT: #pragma omp parallel for simd safelen(4) linear(k1,k2: 4) aligned(a: 4) simdlen(4)
133176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// CHECK-NEXT:   for (int i = 0; i < n; i++) {
134176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// CHECK-NEXT:     c[i] = a[i] + b[i];
135176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// CHECK-NEXT:     c[k1] = a[k1] + b[k1];
136176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// CHECK-NEXT:     c[k2] = a[k2] + b[k2];
137176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// CHECK-NEXT:     k1 = k1 + 4;
138176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// CHECK-NEXT:     k2 = k2 + 4;
139176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// CHECK-NEXT:   }
140176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// CHECK-NEXT: }
141176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
142176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesint main (int argc, char **argv) {
143176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  int b = argc, c, d, e, f, g;
144176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  int k1=0,k2=0;
145176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  static int *a;
146176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// CHECK: static int *a;
1474967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar#pragma omp parallel for simd if(parallel :b) ordered
1484967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar// CHECK-NEXT: #pragma omp parallel for simd if(parallel: b) ordered
149176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  for (int i=0; i < 2; ++i)*a=2;
150176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// CHECK-NEXT: for (int i = 0; i < 2; ++i)
151176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// CHECK-NEXT: *a = 2;
152176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines#pragma omp  parallel
15387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar#pragma omp parallel for simd private(argc, b),lastprivate(d,f) collapse(2) aligned(a : 4) ,firstprivate( g ) if(g)
154176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  for (int i = 0; i < 10; ++i)
155176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  for (int j = 0; j < 10; ++j) {foo(); k1 += 8; k2 += 8;}
156176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// CHECK-NEXT: #pragma omp parallel
15787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar// CHECK-NEXT: #pragma omp parallel for simd private(argc,b) lastprivate(d,f) collapse(2) aligned(a: 4) firstprivate(g) if(g)
158176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// CHECK-NEXT: for (int i = 0; i < 10; ++i)
159176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// CHECK-NEXT: for (int j = 0; j < 10; ++j) {
160176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// CHECK-NEXT: foo();
161176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// CHECK-NEXT: k1 += 8;
162176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// CHECK-NEXT: k2 += 8;
163176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// CHECK-NEXT: }
164176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  for (int i = 0; i < 10; ++i)foo();
165176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// CHECK-NEXT: for (int i = 0; i < 10; ++i)
166176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// CHECK-NEXT: foo();
167176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  const int CLEN = 4;
168176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// CHECK-NEXT: const int CLEN = 4;
16987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  #pragma omp parallel for simd aligned(a:CLEN) linear(a:CLEN) safelen(CLEN) collapse( 1 ) simdlen(CLEN)
17087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar// CHECK-NEXT: #pragma omp parallel for simd aligned(a: CLEN) linear(a: CLEN) safelen(CLEN) collapse(1) simdlen(CLEN)
171176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  for (int i = 0; i < 10; ++i)foo();
172176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// CHECK-NEXT: for (int i = 0; i < 10; ++i)
173176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// CHECK-NEXT: foo();
174176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
175176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  float arr[16];
176176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  S2<4>::func(0,arr,arr,arr);
177176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  return (0);
178176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines}
179176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
180176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines#endif
181