1651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -ast-print %s | FileCheck %s
2651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// RUN: %clang_cc1 -fopenmp=libiomp5 -x c++ -std=c++11 -emit-pch -o %t %s
3651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// RUN: %clang_cc1 -fopenmp=libiomp5 -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
4651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// expected-no-diagnostics
5651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
6651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#ifndef HEADER
7651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#define HEADER
8651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
9651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesvoid foo() {}
10651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesint g_ind = 1;
11651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinestemplate<class T, class N> T reduct(T* arr, N num) {
12651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  N i;
13651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  N ind;
14651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  N myind;
15651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  T sum = (T)0;
16651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: T sum = (T)0;
17ef8225444452a1486bd721f3285301fe84643b00Stephen Hines#pragma omp simd private(myind, g_ind), linear(ind), aligned(arr)
18ef8225444452a1486bd721f3285301fe84643b00Stephen Hines// CHECK-NEXT: #pragma omp simd private(myind,g_ind) linear(ind) aligned(arr)
19651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  for (i = 0; i < num; ++i) {
20651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    myind = ind;
21651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    T cur = arr[myind];
22651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    ind += g_ind;
23651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    sum += cur;
24651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
25651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
26651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
27651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinestemplate<class T> struct S {
28651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  S(const T &a)
29651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    :m_a(a)
30651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  {}
31651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  T result(T *v) const {
32651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    T res;
33651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    T val;
346bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    T lin = 0;
35651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: T res;
36651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: T val;
376bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// CHECK: T lin = 0;
38ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    #pragma omp simd private(val)  safelen(7) linear(lin : -5) lastprivate(res)
39ef8225444452a1486bd721f3285301fe84643b00Stephen Hines// CHECK-NEXT: #pragma omp simd private(val) safelen(7) linear(lin: -5) lastprivate(res)
40651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    for (T i = 7; i < m_a; ++i) {
41651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      val = v[i-7] + m_a;
42651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      res = val;
436bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      lin -= 5;
44651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    }
45651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    const T clen = 3;
46651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: T clen = 3;
47651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    #pragma omp simd safelen(clen-1)
48651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK-NEXT: #pragma omp simd safelen(clen - 1)
49651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    for(T i = clen+2; i < 20; ++i) {
50651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK-NEXT: for (T i = clen + 2; i < 20; ++i) {
51651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      v[i] = v[v-clen] + 1;
52651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK-NEXT: v[i] = v[v - clen] + 1;
53651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    }
54651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK-NEXT: }
55651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    return res;
56651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
57651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  ~S()
58651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  {}
59651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  T m_a;
60651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines};
61651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
62651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinestemplate<int LEN> struct S2 {
63651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  static void func(int n, float *a, float *b, float *c) {
646bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    int k1 = 0, k2 = 0;
65ef8225444452a1486bd721f3285301fe84643b00Stephen Hines#pragma omp simd safelen(LEN) linear(k1,k2:LEN) aligned(a:LEN)
66651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    for(int i = 0; i < n; i++) {
67651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      c[i] = a[i] + b[i];
686bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      c[k1] = a[k1] + b[k1];
696bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      c[k2] = a[k2] + b[k2];
706bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      k1 = k1 + LEN;
716bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      k2 = k2 + LEN;
72651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    }
73651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
74651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines};
75651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
76651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// S2<4>::func is called below in main.
77651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: template <int LEN = 4> struct S2 {
78651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK-NEXT: static void func(int n, float *a, float *b, float *c)     {
796bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// CHECK-NEXT:   int k1 = 0, k2 = 0;
80ef8225444452a1486bd721f3285301fe84643b00Stephen Hines// CHECK-NEXT: #pragma omp simd safelen(4) linear(k1,k2: 4) aligned(a: 4)
81651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK-NEXT:   for (int i = 0; i < n; i++) {
82651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK-NEXT:     c[i] = a[i] + b[i];
836bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// CHECK-NEXT:     c[k1] = a[k1] + b[k1];
846bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// CHECK-NEXT:     c[k2] = a[k2] + b[k2];
856bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// CHECK-NEXT:     k1 = k1 + 4;
866bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// CHECK-NEXT:     k2 = k2 + 4;
87651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK-NEXT:   }
88651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK-NEXT: }
89651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
90651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesint main (int argc, char **argv) {
91651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  int b = argc, c, d, e, f, g;
92651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  int k1=0,k2=0;
93651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  static int *a;
94651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: static int *a;
95651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#pragma omp simd
96651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK-NEXT: #pragma omp simd
97651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  for (int i=0; i < 2; ++i)*a=2;
98651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK-NEXT: for (int i = 0; i < 2; ++i)
99651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK-NEXT: *a = 2;
100ef8225444452a1486bd721f3285301fe84643b00Stephen Hines#pragma omp simd private(argc, b),lastprivate(d,f) collapse(2) aligned(a : 4)
101651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  for (int i = 0; i < 10; ++i)
102651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  for (int j = 0; j < 10; ++j) {foo(); k1 += 8; k2 += 8;}
103ef8225444452a1486bd721f3285301fe84643b00Stephen Hines// CHECK-NEXT: #pragma omp simd private(argc,b) lastprivate(d,f) collapse(2) aligned(a: 4)
104651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK-NEXT: for (int i = 0; i < 10; ++i)
105651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK-NEXT: for (int j = 0; j < 10; ++j) {
106651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK-NEXT: foo();
107651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK-NEXT: k1 += 8;
108651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK-NEXT: k2 += 8;
109651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK-NEXT: }
110651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  for (int i = 0; i < 10; ++i)foo();
111651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK-NEXT: for (int i = 0; i < 10; ++i)
112651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK-NEXT: foo();
113651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  const int CLEN = 4;
114651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK-NEXT: const int CLEN = 4;
115ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  #pragma omp simd aligned(a:CLEN) linear(a:CLEN) safelen(CLEN) collapse( 1 )
116ef8225444452a1486bd721f3285301fe84643b00Stephen Hines// CHECK-NEXT: #pragma omp simd aligned(a: CLEN) linear(a: CLEN) safelen(CLEN) collapse(1)
117651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  for (int i = 0; i < 10; ++i)foo();
118651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK-NEXT: for (int i = 0; i < 10; ++i)
119651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK-NEXT: foo();
120651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
121651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  float arr[16];
122651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  S2<4>::func(0,arr,arr,arr);
123651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  return (0);
124651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
125651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
126651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#endif
127