1*532dc62bSNikita Popov // RUN: %clang_cc1 -no-opaque-pointers -verify -fopenmp -fopenmp-version=50 -x c++ -triple x86_64-unknown-unknown -emit-llvm %s -o - | FileCheck %s
2*532dc62bSNikita Popov // RUN: %clang_cc1 -no-opaque-pointers -fopenmp -fopenmp-version=50 -x c++ -triple x86_64-unknown-unknown -emit-pch -o %t %s
3*532dc62bSNikita Popov // RUN: %clang_cc1 -no-opaque-pointers -fopenmp -fopenmp-version=50 -x c++ -triple x86_64-unknown-unknown -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
443101d10SAlexey Bataev 
5*532dc62bSNikita Popov // RUN: %clang_cc1 -no-opaque-pointers -verify -fopenmp-simd -fopenmp-version=50 -x c++ -triple x86_64-unknown-unknown -emit-llvm %s -o - | FileCheck --check-prefix SIMD-ONLY0 %s
6*532dc62bSNikita Popov // RUN: %clang_cc1 -no-opaque-pointers -fopenmp-simd -fopenmp-version=50 -x c++ -triple x86_64-unknown-unknown -emit-pch -o %t %s
7*532dc62bSNikita Popov // RUN: %clang_cc1 -no-opaque-pointers -fopenmp-simd -fopenmp-version=50 -x c++ -triple x86_64-unknown-unknown -include-pch %t -verify %s -emit-llvm -o - | FileCheck --check-prefix SIMD-ONLY0 %s
843101d10SAlexey Bataev // SIMD-ONLY0-NOT: {{__kmpc|__tgt}}
943101d10SAlexey Bataev //
1043101d10SAlexey Bataev // expected-no-diagnostics
1143101d10SAlexey Bataev #ifndef HEADER
1243101d10SAlexey Bataev #define HEADER
1343101d10SAlexey Bataev void foo();
1443101d10SAlexey Bataev void bar();
1543101d10SAlexey Bataev 
1643101d10SAlexey Bataev // CHECK-LABEL: baz
baz()1743101d10SAlexey Bataev void baz() {
1843101d10SAlexey Bataev   int a = 0;
1943101d10SAlexey Bataev 
2043101d10SAlexey Bataev   // CHECK: store i32 0, i32* [[A_ADDR:%.+]],
2143101d10SAlexey Bataev   // CHECK: store i32 0, i32* [[OMP_CNT:%.+]],
2243101d10SAlexey Bataev   // CHECK: br label %[[OMP_HEADER:.+]]
2343101d10SAlexey Bataev 
2443101d10SAlexey Bataev   // CHECK: [[OMP_HEADER]]:
2543101d10SAlexey Bataev   // CHECK: [[CNT_VAL:%.+]] = load i32, i32* [[OMP_CNT]],
2643101d10SAlexey Bataev   // CHECK: [[CMP:%.+]] = icmp slt i32 [[CNT_VAL]], 10
2743101d10SAlexey Bataev   // CHECK: br i1 [[CMP]], label %[[OMP_BODY:.+]], label %[[OMP_END:.+]]
2843101d10SAlexey Bataev #pragma omp simd reduction(inscan, + : a)
2943101d10SAlexey Bataev   for (int i = 0; i < 10; ++i) {
3043101d10SAlexey Bataev     // CHECK: [[OMP_BODY]]:
3143101d10SAlexey Bataev 
3243101d10SAlexey Bataev     // i = OMP_CNT*1 + 0;
3343101d10SAlexey Bataev     // CHECK: [[CNT_VAL:%.+]] = load i32, i32* [[OMP_CNT]],
3443101d10SAlexey Bataev     // CHECK: [[MUL:%.+]] = mul nsw i32 [[CNT_VAL]], 1
3543101d10SAlexey Bataev     // CHECK: [[ADD:%.+]] = add nsw i32 0, [[MUL]]
3643101d10SAlexey Bataev     // CHECK: store i32 [[ADD]], i32* [[I_ADDR:%.+]],
3743101d10SAlexey Bataev 
3843101d10SAlexey Bataev     // A_PRIV = 0;
3943101d10SAlexey Bataev     // CHECK: store i32 0, i32* [[A_PRIV_ADDR:%.+]],
4043101d10SAlexey Bataev 
4143101d10SAlexey Bataev     // goto DISPATCH;
4243101d10SAlexey Bataev     // CHECK: br label %[[DISPATCH:[^,]+]]
4343101d10SAlexey Bataev 
4443101d10SAlexey Bataev     // INPUT_PHASE:
4543101d10SAlexey Bataev     // foo();
4643101d10SAlexey Bataev     // goto REDUCE;
4743101d10SAlexey Bataev     // CHECK: [[INPUT_PHASE:.+]]:
4843101d10SAlexey Bataev     // CHECK: call void @{{.*}}foo{{.*}}()
4943101d10SAlexey Bataev     // CHECK: br label %[[REDUCE:[^,]+]]
5043101d10SAlexey Bataev     foo();
5143101d10SAlexey Bataev 
5243101d10SAlexey Bataev     // DISPATCH:
5343101d10SAlexey Bataev     // goto INPUT_PHASE;
5443101d10SAlexey Bataev     // CHECK: [[DISPATCH]]:
5543101d10SAlexey Bataev     // CHECK: br label %[[INPUT_PHASE]]
5643101d10SAlexey Bataev 
5743101d10SAlexey Bataev     // REDUCE:
5843101d10SAlexey Bataev     // A = A_PRIV + A;
5943101d10SAlexey Bataev     // A_PRIV = A;
6043101d10SAlexey Bataev     // goto SCAN_PHASE;
6143101d10SAlexey Bataev     // CHECK: [[REDUCE]]:
6243101d10SAlexey Bataev     // CHECK: [[A:%.+]] = load i32, i32* [[A_ADDR]],
6343101d10SAlexey Bataev     // CHECK: [[A_PRIV:%.+]] = load i32, i32* [[A_PRIV_ADDR]],
6443101d10SAlexey Bataev     // CHECK: [[SUM:%.+]] = add nsw i32 [[A]], [[A_PRIV]]
6543101d10SAlexey Bataev     // CHECK: store i32 [[SUM]], i32* [[A_ADDR]],
6643101d10SAlexey Bataev     // CHECK: [[A:%.+]] = load i32, i32* [[A_ADDR]],
6743101d10SAlexey Bataev     // CHECK: store i32 [[A]], i32* [[A_PRIV_ADDR]],
6843101d10SAlexey Bataev     // CHECK: br label %[[SCAN_PHASE:[^,]+]]
6943101d10SAlexey Bataev #pragma omp scan inclusive(a)
7043101d10SAlexey Bataev 
7143101d10SAlexey Bataev     // SCAN_PHASE:
7243101d10SAlexey Bataev     // bar();
7343101d10SAlexey Bataev     // goto CONTINUE;
7443101d10SAlexey Bataev     // CHECK: [[SCAN_PHASE]]:
7543101d10SAlexey Bataev     // CHECK: call void @{{.*}}bar{{.*}}()
7643101d10SAlexey Bataev     // CHECK: br label %[[CONTINUE:[^,]+]]
7743101d10SAlexey Bataev     bar();
7843101d10SAlexey Bataev 
7943101d10SAlexey Bataev     // CHECK: [[CONTINUE]]:
8043101d10SAlexey Bataev     // CHECK: br label %[[INC_BLOCK:[^,]+]]
8143101d10SAlexey Bataev 
8243101d10SAlexey Bataev     // ++OMP_CNT;
8343101d10SAlexey Bataev     // CHECK: [[INC_BLOCK]]:
8443101d10SAlexey Bataev     // CHECK: [[CNT:%.+]] = load i32, i32* [[OMP_CNT]],
8543101d10SAlexey Bataev     // CHECK: [[INC:%.+]] = add nsw i32 [[CNT]], 1
8643101d10SAlexey Bataev     // CHECK: store i32 [[INC]], i32* [[OMP_CNT]],
8743101d10SAlexey Bataev     // CHECK: br label %[[OMP_HEADER]]
8843101d10SAlexey Bataev   }
8943101d10SAlexey Bataev   // CHECK: [[OMP_END]]:
9043101d10SAlexey Bataev }
9143101d10SAlexey Bataev 
9243101d10SAlexey Bataev struct S {
9343101d10SAlexey Bataev   int a;
SS9443101d10SAlexey Bataev   S() {}
~SS9543101d10SAlexey Bataev   ~S() {}
9643101d10SAlexey Bataev   S& operator+(const S&);
9743101d10SAlexey Bataev   S& operator=(const S&);
9843101d10SAlexey Bataev };
9943101d10SAlexey Bataev 
10043101d10SAlexey Bataev // CHECK-LABEL: xyz
xyz()10143101d10SAlexey Bataev void xyz() {
10243101d10SAlexey Bataev   S s[2];
10343101d10SAlexey Bataev 
10443101d10SAlexey Bataev   // CHECK: [[S_BEGIN:%.+]] = getelementptr inbounds [2 x %struct.S], [2 x %struct.S]* [[S_ADDR:%.+]], i{{.+}} 0, i{{.+}} 0
10543101d10SAlexey Bataev   // CHECK: [[S_END:%.+]] = getelementptr {{.*}}%struct.S, %struct.S* [[S_BEGIN]], i{{.+}} 2
10643101d10SAlexey Bataev   // CHECK: br label %[[ARRAY_INIT:.+]]
10743101d10SAlexey Bataev   // CHECK: [[ARRAY_INIT]]:
10843101d10SAlexey Bataev   // CHECK: [[S_CUR:%.+]] = phi %struct.S* [ [[S_BEGIN]], %{{.+}} ], [ [[S_NEXT:%.+]], %[[ARRAY_INIT]] ]
10969cd776eSCJ Johnson   // CHECK: call void [[CONSTR:@.+]](%struct.S* {{[^,]*}} [[S_CUR]])
11043101d10SAlexey Bataev   // CHECK: [[S_NEXT]] = getelementptr inbounds %struct.S, %struct.S* [[S_CUR]], i{{.+}} 1
11143101d10SAlexey Bataev   // CHECK: [[IS_DONE:%.+]] = icmp eq %struct.S* [[S_NEXT]], [[S_END]]
11243101d10SAlexey Bataev   // CHECK: br i1 [[IS_DONE]], label %[[DONE:.+]], label %[[ARRAY_INIT]]
11343101d10SAlexey Bataev   // CHECK: [[DONE]]:
11443101d10SAlexey Bataev   // CHECK: store i32 0, i32* [[OMP_CNT:%.+]],
11543101d10SAlexey Bataev   // CHECK: br label %[[OMP_HEADER:.+]]
11643101d10SAlexey Bataev 
11743101d10SAlexey Bataev   // CHECK: [[OMP_HEADER]]:
11843101d10SAlexey Bataev   // CHECK: [[CNT_VAL:%.+]] = load i32, i32* [[OMP_CNT]],
11943101d10SAlexey Bataev   // CHECK: [[CMP:%.+]] = icmp slt i32 [[CNT_VAL]], 10
12043101d10SAlexey Bataev   // CHECK: br i1 [[CMP]], label %[[OMP_BODY:.+]], label %[[OMP_END:.+]]
12143101d10SAlexey Bataev #pragma omp simd reduction(inscan, + : s)
12243101d10SAlexey Bataev   for (int i = 0; i < 10; ++i) {
12343101d10SAlexey Bataev     // CHECK: [[OMP_BODY]]:
12443101d10SAlexey Bataev 
12543101d10SAlexey Bataev     // i = OMP_CNT*1 + 0;
12643101d10SAlexey Bataev     // CHECK: [[CNT_VAL:%.+]] = load i32, i32* [[OMP_CNT]],
12743101d10SAlexey Bataev     // CHECK: [[MUL:%.+]] = mul nsw i32 [[CNT_VAL]], 1
12843101d10SAlexey Bataev     // CHECK: [[ADD:%.+]] = add nsw i32 0, [[MUL]]
12943101d10SAlexey Bataev     // CHECK: store i32 [[ADD]], i32* [[I_ADDR:%.+]],
13043101d10SAlexey Bataev 
13143101d10SAlexey Bataev     // S S_PRIV[2];
13243101d10SAlexey Bataev     // CHECK: [[S_BEGIN:%.+]] = getelementptr inbounds [2 x %struct.S], [2 x %struct.S]* [[S_PRIV_ADDR:%.+]], i{{.+}} 0, i{{.+}} 0
13343101d10SAlexey Bataev     // CHECK: [[S_END:%.+]] = getelementptr {{.*}}%struct.S, %struct.S* [[S_BEGIN]], i{{.+}} 2
13443101d10SAlexey Bataev     // CHECK: [[IS_DONE:%.+]] = icmp eq %struct.S* [[S_BEGIN]], [[S_END]]
13543101d10SAlexey Bataev     // CHECK: br i1 [[IS_DONE]], label %[[DONE:.+]], label %[[ARRAY_INIT:[^,]+]]
13643101d10SAlexey Bataev     // CHECK: [[ARRAY_INIT]]:
13743101d10SAlexey Bataev     // CHECK: [[S_CUR:%.+]] = phi %struct.S* [ [[S_BEGIN]], %[[OMP_BODY]] ], [ [[S_NEXT:%.+]], %[[ARRAY_INIT]] ]
13869cd776eSCJ Johnson     // CHECK: call void [[CONSTR]](%struct.S* {{[^,]*}} [[S_CUR]])
13943101d10SAlexey Bataev     // CHECK: [[S_NEXT]] = getelementptr {{.*}}%struct.S, %struct.S* [[S_CUR]], i{{.+}} 1
14043101d10SAlexey Bataev     // CHECK: [[IS_DONE:%.+]] = icmp eq %struct.S* [[S_NEXT]], [[S_END]]
14143101d10SAlexey Bataev     // CHECK: br i1 [[IS_DONE]], label %[[DONE:.+]], label %[[ARRAY_INIT]]
14243101d10SAlexey Bataev     // CHECK: [[DONE]]:
14343101d10SAlexey Bataev     // CHECK: [[LHS_BEGIN:%.+]] = bitcast [2 x %struct.S]* [[S_ADDR]] to %struct.S*
14443101d10SAlexey Bataev     // CHECK: [[RHS_BEGIN:%.+]] = bitcast [2 x %struct.S]* [[S_PRIV_ADDR]] to %struct.S*
14543101d10SAlexey Bataev 
14643101d10SAlexey Bataev     // goto DISPATCH;
14743101d10SAlexey Bataev     // CHECK: br label %[[DISPATCH:[^,]+]]
14843101d10SAlexey Bataev 
14943101d10SAlexey Bataev     // SCAN_PHASE:
15043101d10SAlexey Bataev     // foo();
15143101d10SAlexey Bataev     // goto CONTINUE;
15243101d10SAlexey Bataev     // CHECK: [[SCAN_PHASE:.+]]:
15343101d10SAlexey Bataev     // CHECK: call void @{{.*}}foo{{.*}}()
15443101d10SAlexey Bataev     // CHECK: br label %[[CONTINUE:[^,]+]]
15543101d10SAlexey Bataev     foo();
15643101d10SAlexey Bataev 
15743101d10SAlexey Bataev     // DISPATCH:
15843101d10SAlexey Bataev     // goto INPUT_PHASE;
15943101d10SAlexey Bataev     // CHECK: [[DISPATCH]]:
16043101d10SAlexey Bataev     // CHECK: br label %[[INPUT_PHASE:[^,]+]]
16143101d10SAlexey Bataev 
16243101d10SAlexey Bataev     // REDUCE:
16343101d10SAlexey Bataev     // TEMP = S;
16443101d10SAlexey Bataev     // S = S_PRIV + S;
16543101d10SAlexey Bataev     // S_PRIV = TEMP;
16643101d10SAlexey Bataev     // goto SCAN_PHASE;
16743101d10SAlexey Bataev     // CHECK: [[REDUCE:.+]]:
16843101d10SAlexey Bataev 
16943101d10SAlexey Bataev     // S TEMP[2];
17043101d10SAlexey Bataev     // CHECK: [[TEMP_ARR_BEG:%.+]] = getelementptr inbounds [2 x %struct.S], [2 x %struct.S]* [[TEMP_ARR:%.+]], i32 0, i32 0
17143101d10SAlexey Bataev     // CHECK: [[TEMP_ARR_END:%.+]] = getelementptr inbounds %struct.S, %struct.S* [[TEMP_ARR_BEG]], i64 2
17243101d10SAlexey Bataev     // CHECK: br label %[[BODY:[^,]+]]
17343101d10SAlexey Bataev     // CHECK: [[BODY]]:
17443101d10SAlexey Bataev     // CHECK: [[CUR:%.+]] = phi %struct.S* [ [[TEMP_ARR_BEG]], %[[REDUCE]] ], [ [[NEXT:%.+]], %[[BODY]] ]
17569cd776eSCJ Johnson     // CHECK: call void [[CONSTR]](%struct.S* {{[^,]*}} [[CUR]])
17643101d10SAlexey Bataev     // CHECK: [[NEXT]] = getelementptr inbounds %struct.S, %struct.S* [[CUR]], i64 1
17743101d10SAlexey Bataev     // CHECK: [[IS_DONE:%.+]] = icmp eq %struct.S* [[NEXT]], [[TEMP_ARR_END]]
17843101d10SAlexey Bataev     // CHECK: br i1 [[IS_DONE]], label %[[EXIT:[^,]+]], label %[[BODY]]
17943101d10SAlexey Bataev     // CHECK: [[EXIT]]:
18043101d10SAlexey Bataev 
18143101d10SAlexey Bataev     // TEMP = S;
18243101d10SAlexey Bataev     // CHECK: [[TEMP_ARR_BEG:%.+]] = getelementptr inbounds [2 x %struct.S], [2 x %struct.S]* [[TEMP_ARR]], i32 0, i32 0
18343101d10SAlexey Bataev     // CHECK: [[TEMP_ARR_END:%.+]] = getelementptr %struct.S, %struct.S* [[TEMP_ARR_BEG]], i64 2
18443101d10SAlexey Bataev     // CHECK: [[IS_EMPTY:%.+]] = icmp eq %struct.S* [[TEMP_ARR_BEG]], [[TEMP_ARR_END]]
18543101d10SAlexey Bataev     // CHECK: br i1 [[IS_EMPTY]], label %[[EXIT:[^,]+]], label %[[BODY:[^,]+]]
18643101d10SAlexey Bataev     // CHECK: [[BODY]]:
18743101d10SAlexey Bataev     // CHECK: [[CUR_SRC:%.+]] = phi %struct.S* [ [[LHS_BEGIN]], %{{.+}} ], [ [[SRC_NEXT:%.+]], %[[BODY]] ]
18843101d10SAlexey Bataev     // CHECK: [[CUR_DEST:%.+]] = phi %struct.S* [ [[TEMP_ARR_BEG]], %{{.+}} ], [ [[DEST_NEXT:%.+]], %[[BODY]] ]
18969cd776eSCJ Johnson     // CHECK: call {{.*}}%struct.S* [[S_COPY:@.+]](%struct.S* {{[^,]*}} [[CUR_DEST]], %struct.S* {{.*}}[[CUR_SRC]])
19043101d10SAlexey Bataev     // CHECK: [[DEST_NEXT:%.+]] = getelementptr %struct.S, %struct.S* [[CUR_DEST]], i32 1
19143101d10SAlexey Bataev     // CHECK: [[SRC_NEXT:%.+]] = getelementptr %struct.S, %struct.S* [[CUR_SRC]], i32 1
19243101d10SAlexey Bataev     // CHECK: [[IS_DONE:%.+]] = icmp eq %struct.S* [[DEST_NEXT]], [[TEMP_ARR_END]]
19343101d10SAlexey Bataev     // CHECK: br i1 [[IS_DONE]], label %[[EXIT]], label %[[BODY]]
19443101d10SAlexey Bataev     // CHECK: [[EXIT]]:
19543101d10SAlexey Bataev 
19643101d10SAlexey Bataev     // S = S_PRIV + S;
19743101d10SAlexey Bataev     // CHECK: [[LHS_END:%.+]] = getelementptr {{.*}}%struct.S, %struct.S* [[LHS_BEGIN]], i{{.+}} 2
19843101d10SAlexey Bataev     // CHECK: [[IS_DONE:%.+]] = icmp eq %struct.S* [[LHS_BEGIN]], [[LHS_END]]
19943101d10SAlexey Bataev     // CHECK: br i1 [[IS_DONE]], label %[[DONE:.+]], label %[[ARRAY_REDUCE_COPY:[^,]+]]
20043101d10SAlexey Bataev     // CHECK: [[ARRAY_REDUCE_COPY]]:
20143101d10SAlexey Bataev     // CHECK: [[SRC_CUR:%.+]] = phi %struct.S* [ [[RHS_BEGIN]], %[[EXIT]] ], [ [[SRC_NEXT:%.+]], %[[ARRAY_REDUCE_COPY]] ]
20243101d10SAlexey Bataev     // CHECK: [[DEST_CUR:%.+]] = phi %struct.S* [ [[LHS_BEGIN]], %[[EXIT]] ], [ [[DEST_NEXT:%.+]], %[[ARRAY_REDUCE_COPY]] ]
20369cd776eSCJ Johnson     // CHECK: [[SUM:%.+]] = call {{.*}}%struct.S* @{{.+}}(%struct.S* {{[^,]*}} [[DEST_CUR]], %struct.S* {{.*}}[[SRC_CUR]])
20469cd776eSCJ Johnson     // CHECK: call {{.*}}%struct.S* [[S_COPY]](%struct.S* {{[^,]*}} [[DEST_CUR]], %struct.S* {{.*}}[[SUM]])
20543101d10SAlexey Bataev     // CHECK: [[DEST_NEXT]] = getelementptr {{.*}}%struct.S, %struct.S* [[DEST_CUR]], i{{.+}} 1
20643101d10SAlexey Bataev     // CHECK: [[SRC_NEXT]] = getelementptr {{.*}}%struct.S, %struct.S* [[SRC_CUR]], i{{.+}} 1
20743101d10SAlexey Bataev     // CHECK: [[IS_DONE:%.+]] = icmp eq %struct.S* [[DEST_NEXT]], [[LHS_END]]
20843101d10SAlexey Bataev     // CHECK: br i1 [[IS_DONE]], label %[[DONE:.+]], label %[[ARRAY_REDUCE_COPY]]
20943101d10SAlexey Bataev     // CHECK: [[DONE]]:
21043101d10SAlexey Bataev 
21143101d10SAlexey Bataev     // S_PRIV = TEMP;
21243101d10SAlexey Bataev     // CHECK: [[TEMP_ARR_BEG:%.+]] = bitcast [2 x %struct.S]* [[TEMP_ARR]] to %struct.S*
21343101d10SAlexey Bataev     // CHECK: [[RHS_END:%.+]] = getelementptr %struct.S, %struct.S* [[RHS_BEGIN]], i64 2
21443101d10SAlexey Bataev     // CHECK: [[IS_EMPTY:%.+]] = icmp eq %struct.S* [[RHS_BEGIN]], [[RHS_END]]
21543101d10SAlexey Bataev     // CHECK: br i1 [[IS_EMPTY]], label %[[EXIT:[^,]+]], label %[[BODY:[^,]+]]
21643101d10SAlexey Bataev     // CHECK: [[BODY]]:
21743101d10SAlexey Bataev     // CHECK: [[CUR_SRC:%.+]] = phi %struct.S* [ [[TEMP_ARR_BEG]], %[[DONE]] ], [ [[SRC_NEXT:%.+]], %[[BODY]] ]
21843101d10SAlexey Bataev     // CHECK: [[CUR_DEST:%.+]] = phi %struct.S* [ [[RHS_BEGIN]], %[[DONE]] ], [ [[DEST_NEXT:%.+]], %[[BODY]] ]
21969cd776eSCJ Johnson     // CHECK: call {{.*}}%struct.S* [[S_COPY]](%struct.S* {{[^,]*}} [[CUR_DEST]], %struct.S* {{.*}}[[CUR_SRC]])
22043101d10SAlexey Bataev     // CHECK: [[DEST_NEXT]] = getelementptr %struct.S, %struct.S* [[CUR_DEST]], i32 1
22143101d10SAlexey Bataev     // CHECK: [[SRC_NEXT]] = getelementptr %struct.S, %struct.S* [[CUR_SRC]], i32 1
22243101d10SAlexey Bataev     // CHECK: [[IS_DONE:%.+]] = icmp eq %struct.S* [[DEST_NEXT]], [[RHS_END]]
22343101d10SAlexey Bataev     // CHECK: br i1 [[IS_DONE]], label %[[DONE:[^,]+]], label %[[BODY]]
22443101d10SAlexey Bataev     // CHECK: [[DONE]]:
22543101d10SAlexey Bataev 
22643101d10SAlexey Bataev     // TEMP.~S()
22743101d10SAlexey Bataev     // CHECK: [[TEMP_ARR_BEG:%.+]] = getelementptr inbounds [2 x %struct.S], [2 x %struct.S]* [[TEMP_ARR]], i32 0, i32 0
22843101d10SAlexey Bataev     // CHECK: [[TEMP_ARR_END:%.+]] = getelementptr inbounds %struct.S, %struct.S* [[TEMP_ARR_BEG]], i64 2
22943101d10SAlexey Bataev     // CHECK: br label %[[BODY:[^,]+]]
23043101d10SAlexey Bataev     // CHECK: [[BODY]]:
23143101d10SAlexey Bataev     // CHECK: [[CUR:%.+]] = phi %struct.S* [ [[TEMP_ARR_END]], %[[DONE]] ], [ [[PREV:%.+]], %[[BODY]] ]
23243101d10SAlexey Bataev     // CHECK: [[PREV]] = getelementptr inbounds %struct.S, %struct.S* [[CUR]], i64 -1
23369cd776eSCJ Johnson     // CHECK: call void [[DESTR:@.+]](%struct.S* {{[^,]*}} [[PREV]])
23443101d10SAlexey Bataev     // CHECK: [[IS_DONE:%.+]] = icmp eq %struct.S* [[PREV]], [[TEMP_ARR_BEG]]
23543101d10SAlexey Bataev     // CHECK: br i1 [[IS_DONE]], label %[[EXIT:[^,]+]], label %[[BODY]]
23643101d10SAlexey Bataev     // CHECK: [[EXIT]]:
23743101d10SAlexey Bataev 
23843101d10SAlexey Bataev     // goto SCAN_PHASE;
23943101d10SAlexey Bataev     // CHECK: br label %[[SCAN_PHASE]]
24043101d10SAlexey Bataev #pragma omp scan exclusive(s)
24143101d10SAlexey Bataev 
24243101d10SAlexey Bataev     // INPUT_PHASE:
24343101d10SAlexey Bataev     // bar();
24443101d10SAlexey Bataev     // goto REDUCE;
24543101d10SAlexey Bataev     // CHECK: [[INPUT_PHASE]]:
24643101d10SAlexey Bataev     // CHECK: call void @{{.*}}bar{{.*}}()
24743101d10SAlexey Bataev     // CHECK: br label %[[REDUCE]]
24843101d10SAlexey Bataev     bar();
24943101d10SAlexey Bataev 
25043101d10SAlexey Bataev     // CHECK: [[CONTINUE]]:
25143101d10SAlexey Bataev 
25243101d10SAlexey Bataev     // S_PRIV[2].~S();
25343101d10SAlexey Bataev     // CHECK: [[S_BEGIN:%.+]] = getelementptr inbounds [2 x %struct.S], [2 x %struct.S]* [[S_PRIV_ADDR]], i{{.+}} 0, i{{.+}} 0
25443101d10SAlexey Bataev     // CHECK: [[S_END:%.+]] = getelementptr {{.*}}%struct.S, %struct.S* [[S_BEGIN]], i{{.+}} 2
25543101d10SAlexey Bataev     // CHECK: br label %[[ARRAY_DESTR:[^,]+]]
25643101d10SAlexey Bataev     // CHECK: [[ARRAY_DESTR]]:
25743101d10SAlexey Bataev     // CHECK: [[S_CUR:%.+]] = phi %struct.S* [ [[S_END]], %[[CONTINUE]] ], [ [[S_PREV:%.+]], %[[ARRAY_DESTR]] ]
25843101d10SAlexey Bataev     // CHECK: [[S_PREV]] = getelementptr {{.*}}%struct.S, %struct.S* [[S_CUR]], i{{.+}} -1
25969cd776eSCJ Johnson     // CHECK: call void [[DESTR]](%struct.S* {{[^,]*}} [[S_PREV]])
26043101d10SAlexey Bataev     // CHECK: [[IS_DONE:%.+]] = icmp eq %struct.S* [[S_PREV]], [[S_BEGIN]]
26143101d10SAlexey Bataev     // CHECK: br i1 [[IS_DONE]], label %[[DONE:.+]], label %[[ARRAY_DESTR]]
26243101d10SAlexey Bataev     // CHECK: [[DONE]]:
26343101d10SAlexey Bataev     // CHECK: br label %[[INC_BLOCK:[^,]+]]
26443101d10SAlexey Bataev 
26543101d10SAlexey Bataev     // ++OMP_CNT;
26643101d10SAlexey Bataev     // CHECK: [[INC_BLOCK]]:
26743101d10SAlexey Bataev     // CHECK: [[CNT:%.+]] = load i32, i32* [[OMP_CNT]],
26843101d10SAlexey Bataev     // CHECK: [[INC:%.+]] = add nsw i32 [[CNT]], 1
26943101d10SAlexey Bataev     // CHECK: store i32 [[INC]], i32* [[OMP_CNT]],
27043101d10SAlexey Bataev     // CHECK: br label %[[OMP_HEADER]]
27143101d10SAlexey Bataev   }
27243101d10SAlexey Bataev   // CHECK: [[OMP_END]]:
27343101d10SAlexey Bataev }
27443101d10SAlexey Bataev 
27543101d10SAlexey Bataev // CHECK-NOT: !{!"llvm.loop.parallel_accesses"
27643101d10SAlexey Bataev 
27743101d10SAlexey Bataev #endif // HEADER
278