brintos

brintos / llvm-project-archived public Read only

0
0
Text · 11.4 KiB · 024a69b Raw
275 lines · cpp
1// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple x86_64-unknown-unknown -emit-llvm %s -o - | FileCheck %s2// RUN: %clang_cc1 -fopenmp -x c++ -triple x86_64-unknown-unknown -emit-pch -o %t %s3// RUN: %clang_cc1 -fopenmp -x c++ -triple x86_64-unknown-unknown -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s4 5// RUN: %clang_cc1 -verify -fopenmp-simd -x c++ -triple x86_64-unknown-unknown -emit-llvm %s -o - | FileCheck --check-prefix SIMD-ONLY0 %s6// RUN: %clang_cc1 -fopenmp-simd -x c++ -triple x86_64-unknown-unknown -emit-pch -o %t %s7// RUN: %clang_cc1 -fopenmp-simd -x c++ -triple x86_64-unknown-unknown -include-pch %t -verify %s -emit-llvm -o - | FileCheck --check-prefix SIMD-ONLY0 %s8// SIMD-ONLY0-NOT: {{__kmpc|__tgt}}9//10// expected-no-diagnostics11#ifndef HEADER12#define HEADER13void foo();14void bar();15 16// CHECK-LABEL: baz17void baz() {18  int a = 0;19 20  // CHECK: store i32 0, ptr [[A_ADDR:%.+]],21  // CHECK: store i32 0, ptr [[OMP_CNT:%.+]],22  // CHECK: br label %[[OMP_HEADER:.+]]23 24  // CHECK: [[OMP_HEADER]]:25  // CHECK: [[CNT_VAL:%.+]] = load i32, ptr [[OMP_CNT]],26  // CHECK: [[CMP:%.+]] = icmp slt i32 [[CNT_VAL]], 1027  // CHECK: br i1 [[CMP]], label %[[OMP_BODY:.+]], label %[[OMP_END:.+]]28#pragma omp simd reduction(inscan, + : a)29  for (int i = 0; i < 10; ++i) {30    // CHECK: [[OMP_BODY]]:31 32    // i = OMP_CNT*1 + 0;33    // CHECK: [[CNT_VAL:%.+]] = load i32, ptr [[OMP_CNT]],34    // CHECK: [[MUL:%.+]] = mul nsw i32 [[CNT_VAL]], 135    // CHECK: [[ADD:%.+]] = add nsw i32 0, [[MUL]]36    // CHECK: store i32 [[ADD]], ptr [[I_ADDR:%.+]],37 38    // A_PRIV = 0;39    // CHECK: store i32 0, ptr [[A_PRIV_ADDR:%.+]],40 41    // goto DISPATCH;42    // CHECK: br label %[[DISPATCH:[^,]+]]43 44    // INPUT_PHASE:45    // foo();46    // goto REDUCE;47    // CHECK: [[INPUT_PHASE:.+]]:48    // CHECK: call void @{{.*}}foo{{.*}}()49    // CHECK: br label %[[REDUCE:[^,]+]]50    foo();51 52    // DISPATCH:53    // goto INPUT_PHASE;54    // CHECK: [[DISPATCH]]:55    // CHECK: br label %[[INPUT_PHASE]]56 57    // REDUCE:58    // A = A_PRIV + A;59    // A_PRIV = A;60    // goto SCAN_PHASE;61    // CHECK: [[REDUCE]]:62    // CHECK: [[A:%.+]] = load i32, ptr [[A_ADDR]],63    // CHECK: [[A_PRIV:%.+]] = load i32, ptr [[A_PRIV_ADDR]],64    // CHECK: [[SUM:%.+]] = add nsw i32 [[A]], [[A_PRIV]]65    // CHECK: store i32 [[SUM]], ptr [[A_ADDR]],66    // CHECK: [[A:%.+]] = load i32, ptr [[A_ADDR]],67    // CHECK: store i32 [[A]], ptr [[A_PRIV_ADDR]],68    // CHECK: br label %[[SCAN_PHASE:[^,]+]]69#pragma omp scan inclusive(a)70 71    // SCAN_PHASE:72    // bar();73    // goto CONTINUE;74    // CHECK: [[SCAN_PHASE]]:75    // CHECK: call void @{{.*}}bar{{.*}}()76    // CHECK: br label %[[CONTINUE:[^,]+]]77    bar();78 79    // CHECK: [[CONTINUE]]:80    // CHECK: br label %[[INC_BLOCK:[^,]+]]81 82    // ++OMP_CNT;83    // CHECK: [[INC_BLOCK]]:84    // CHECK: [[CNT:%.+]] = load i32, ptr [[OMP_CNT]],85    // CHECK: [[INC:%.+]] = add nsw i32 [[CNT]], 186    // CHECK: store i32 [[INC]], ptr [[OMP_CNT]],87    // CHECK: br label %[[OMP_HEADER]]88  }89  // CHECK: [[OMP_END]]:90}91 92struct S {93  int a;94  S() {}95  ~S() {}96  S& operator+(const S&);97  S& operator=(const S&);98};99 100// CHECK-LABEL: xyz101void xyz() {102  S s[2];103 104  // CHECK: [[S_BEGIN:%.+]] = getelementptr inbounds [2 x %struct.S], ptr [[S_ADDR:%.+]], i{{.+}} 0, i{{.+}} 0105  // CHECK: [[S_END:%.+]] = getelementptr {{.*}}%struct.S, ptr [[S_BEGIN]], i{{.+}} 2106  // CHECK: br label %[[ARRAY_INIT:.+]]107  // CHECK: [[ARRAY_INIT]]:108  // CHECK: [[S_CUR:%.+]] = phi ptr [ [[S_BEGIN]], %{{.+}} ], [ [[S_NEXT:%.+]], %[[ARRAY_INIT]] ]109  // CHECK: call void [[CONSTR:@.+]](ptr {{[^,]*}} [[S_CUR]])110  // CHECK: [[S_NEXT]] = getelementptr inbounds %struct.S, ptr [[S_CUR]], i{{.+}} 1111  // CHECK: [[IS_DONE:%.+]] = icmp eq ptr [[S_NEXT]], [[S_END]]112  // CHECK: br i1 [[IS_DONE]], label %[[DONE:.+]], label %[[ARRAY_INIT]]113  // CHECK: [[DONE]]:114  // CHECK: store i32 0, ptr [[OMP_CNT:%.+]],115  // CHECK: br label %[[OMP_HEADER:.+]]116 117  // CHECK: [[OMP_HEADER]]:118  // CHECK: [[CNT_VAL:%.+]] = load i32, ptr [[OMP_CNT]],119  // CHECK: [[CMP:%.+]] = icmp slt i32 [[CNT_VAL]], 10120  // CHECK: br i1 [[CMP]], label %[[OMP_BODY:.+]], label %[[OMP_END:.+]]121#pragma omp simd reduction(inscan, + : s)122  for (int i = 0; i < 10; ++i) {123    // CHECK: [[OMP_BODY]]:124 125    // i = OMP_CNT*1 + 0;126    // CHECK: [[CNT_VAL:%.+]] = load i32, ptr [[OMP_CNT]],127    // CHECK: [[MUL:%.+]] = mul nsw i32 [[CNT_VAL]], 1128    // CHECK: [[ADD:%.+]] = add nsw i32 0, [[MUL]]129    // CHECK: store i32 [[ADD]], ptr [[I_ADDR:%.+]],130 131    // S S_PRIV[2];132    // CHECK: [[S_BEGIN:%.+]] = getelementptr inbounds [2 x %struct.S], ptr [[S_PRIV_ADDR:%.+]], i{{.+}} 0, i{{.+}} 0133    // CHECK: [[S_END:%.+]] = getelementptr {{.*}}%struct.S, ptr [[S_BEGIN]], i{{.+}} 2134    // CHECK: [[IS_DONE:%.+]] = icmp eq ptr [[S_BEGIN]], [[S_END]]135    // CHECK: br i1 [[IS_DONE]], label %[[DONE:.+]], label %[[ARRAY_INIT:[^,]+]]136    // CHECK: [[ARRAY_INIT]]:137    // CHECK: [[S_CUR:%.+]] = phi ptr [ [[S_BEGIN]], %[[OMP_BODY]] ], [ [[S_NEXT:%.+]], %[[ARRAY_INIT]] ]138    // CHECK: call void [[CONSTR]](ptr {{[^,]*}} [[S_CUR]])139    // CHECK: [[S_NEXT]] = getelementptr {{.*}}%struct.S, ptr [[S_CUR]], i{{.+}} 1140    // CHECK: [[IS_DONE:%.+]] = icmp eq ptr [[S_NEXT]], [[S_END]]141    // CHECK: br i1 [[IS_DONE]], label %[[DONE:.+]], label %[[ARRAY_INIT]]142    // CHECK: [[DONE]]:143 144    // goto DISPATCH;145    // CHECK: br label %[[DISPATCH:[^,]+]]146 147    // SCAN_PHASE:148    // foo();149    // goto CONTINUE;150    // CHECK: [[SCAN_PHASE:.+]]:151    // CHECK: call void @{{.*}}foo{{.*}}()152    // CHECK: br label %[[CONTINUE:[^,]+]]153    foo();154 155    // DISPATCH:156    // goto INPUT_PHASE;157    // CHECK: [[DISPATCH]]:158    // CHECK: br label %[[INPUT_PHASE:[^,]+]]159 160    // REDUCE:161    // TEMP = S;162    // S = S_PRIV + S;163    // S_PRIV = TEMP;164    // goto SCAN_PHASE;165    // CHECK: [[REDUCE:.+]]:166 167    // S TEMP[2];168    // CHECK: [[TEMP_ARR_BEG:%.+]] = getelementptr inbounds [2 x %struct.S], ptr [[TEMP_ARR:%.+]], i32 0, i32 0169    // CHECK: [[TEMP_ARR_END:%.+]] = getelementptr inbounds %struct.S, ptr [[TEMP_ARR_BEG]], i64 2170    // CHECK: br label %[[BODY:[^,]+]]171    // CHECK: [[BODY]]:172    // CHECK: [[CUR:%.+]] = phi ptr [ [[TEMP_ARR_BEG]], %[[REDUCE]] ], [ [[NEXT:%.+]], %[[BODY]] ]173    // CHECK: call void [[CONSTR]](ptr {{[^,]*}} [[CUR]])174    // CHECK: [[NEXT]] = getelementptr inbounds %struct.S, ptr [[CUR]], i64 1175    // CHECK: [[IS_DONE:%.+]] = icmp eq ptr [[NEXT]], [[TEMP_ARR_END]]176    // CHECK: br i1 [[IS_DONE]], label %[[EXIT:[^,]+]], label %[[BODY]]177    // CHECK: [[EXIT]]:178 179    // TEMP = S;180    // CHECK: [[TEMP_ARR_BEG:%.+]] = getelementptr inbounds [2 x %struct.S], ptr [[TEMP_ARR]], i32 0, i32 0181    // CHECK: [[TEMP_ARR_END:%.+]] = getelementptr inbounds %struct.S, ptr [[TEMP_ARR_BEG]], i64 2182    // CHECK: [[IS_EMPTY:%.+]] = icmp eq ptr [[TEMP_ARR_BEG]], [[TEMP_ARR_END]]183    // CHECK: br i1 [[IS_EMPTY]], label %[[EXIT:[^,]+]], label %[[BODY:[^,]+]]184    // CHECK: [[BODY]]:185    // CHECK: [[CUR_SRC:%.+]] = phi ptr [ [[S_ADDR]], %{{.+}} ], [ [[SRC_NEXT:%.+]], %[[BODY]] ]186    // CHECK: [[CUR_DEST:%.+]] = phi ptr [ [[TEMP_ARR_BEG]], %{{.+}} ], [ [[DEST_NEXT:%.+]], %[[BODY]] ]187    // CHECK: call {{.*}}ptr [[S_COPY:@.+]](ptr {{[^,]*}} [[CUR_DEST]], ptr {{.*}}[[CUR_SRC]])188    // CHECK: [[DEST_NEXT:%.+]] = getelementptr %struct.S, ptr [[CUR_DEST]], i32 1189    // CHECK: [[SRC_NEXT:%.+]] = getelementptr %struct.S, ptr [[CUR_SRC]], i32 1190    // CHECK: [[IS_DONE:%.+]] = icmp eq ptr [[DEST_NEXT]], [[TEMP_ARR_END]]191    // CHECK: br i1 [[IS_DONE]], label %[[EXIT]], label %[[BODY]]192    // CHECK: [[EXIT]]:193 194    // S = S_PRIV + S;195    // CHECK: [[LHS_END:%.+]] = getelementptr {{.*}}%struct.S, ptr [[S_ADDR]], i{{.+}} 2196    // CHECK: [[IS_DONE:%.+]] = icmp eq ptr [[S_ADDR]], [[LHS_END]]197    // CHECK: br i1 [[IS_DONE]], label %[[DONE:.+]], label %[[ARRAY_REDUCE_COPY:[^,]+]]198    // CHECK: [[ARRAY_REDUCE_COPY]]:199    // CHECK: [[SRC_CUR:%.+]] = phi ptr [ [[S_PRIV_ADDR]], %[[EXIT]] ], [ [[SRC_NEXT:%.+]], %[[ARRAY_REDUCE_COPY]] ]200    // CHECK: [[DEST_CUR:%.+]] = phi ptr [ [[S_ADDR]], %[[EXIT]] ], [ [[DEST_NEXT:%.+]], %[[ARRAY_REDUCE_COPY]] ]201    // CHECK: [[SUM:%.+]] = call {{.*}}ptr @{{.+}}(ptr {{[^,]*}} [[DEST_CUR]], ptr {{.*}}[[SRC_CUR]])202    // CHECK: call {{.*}}ptr [[S_COPY]](ptr {{[^,]*}} [[DEST_CUR]], ptr {{.*}}[[SUM]])203    // CHECK: [[DEST_NEXT]] = getelementptr {{.*}}%struct.S, ptr [[DEST_CUR]], i{{.+}} 1204    // CHECK: [[SRC_NEXT]] = getelementptr {{.*}}%struct.S, ptr [[SRC_CUR]], i{{.+}} 1205    // CHECK: [[IS_DONE:%.+]] = icmp eq ptr [[DEST_NEXT]], [[LHS_END]]206    // CHECK: br i1 [[IS_DONE]], label %[[DONE:.+]], label %[[ARRAY_REDUCE_COPY]]207    // CHECK: [[DONE]]:208 209    // S_PRIV = TEMP;210    // CHECK: [[RHS_END:%.+]] = getelementptr inbounds %struct.S, ptr [[S_PRIV_ADDR]], i64 2211    // CHECK: [[IS_EMPTY:%.+]] = icmp eq ptr [[S_PRIV_ADDR]], [[RHS_END]]212    // CHECK: br i1 [[IS_EMPTY]], label %[[EXIT:[^,]+]], label %[[BODY:[^,]+]]213    // CHECK: [[BODY]]:214    // CHECK: [[CUR_SRC:%.+]] = phi ptr [ [[TEMP_ARR]], %[[DONE]] ], [ [[SRC_NEXT:%.+]], %[[BODY]] ]215    // CHECK: [[CUR_DEST:%.+]] = phi ptr [ [[S_PRIV_ADDR]], %[[DONE]] ], [ [[DEST_NEXT:%.+]], %[[BODY]] ]216    // CHECK: call {{.*}}ptr [[S_COPY]](ptr {{[^,]*}} [[CUR_DEST]], ptr {{.*}}[[CUR_SRC]])217    // CHECK: [[DEST_NEXT]] = getelementptr %struct.S, ptr [[CUR_DEST]], i32 1218    // CHECK: [[SRC_NEXT]] = getelementptr %struct.S, ptr [[CUR_SRC]], i32 1219    // CHECK: [[IS_DONE:%.+]] = icmp eq ptr [[DEST_NEXT]], [[RHS_END]]220    // CHECK: br i1 [[IS_DONE]], label %[[DONE:[^,]+]], label %[[BODY]]221    // CHECK: [[DONE]]:222 223    // TEMP.~S()224    // CHECK: [[TEMP_ARR_BEG:%.+]] = getelementptr inbounds [2 x %struct.S], ptr [[TEMP_ARR]], i32 0, i32 0225    // CHECK: [[TEMP_ARR_END:%.+]] = getelementptr inbounds %struct.S, ptr [[TEMP_ARR_BEG]], i64 2226    // CHECK: br label %[[BODY:[^,]+]]227    // CHECK: [[BODY]]:228    // CHECK: [[CUR:%.+]] = phi ptr [ [[TEMP_ARR_END]], %[[DONE]] ], [ [[PREV:%.+]], %[[BODY]] ]229    // CHECK: [[PREV]] = getelementptr inbounds %struct.S, ptr [[CUR]], i64 -1230    // CHECK: call void [[DESTR:@.+]](ptr {{[^,]*}} [[PREV]])231    // CHECK: [[IS_DONE:%.+]] = icmp eq ptr [[PREV]], [[TEMP_ARR_BEG]]232    // CHECK: br i1 [[IS_DONE]], label %[[EXIT:[^,]+]], label %[[BODY]]233    // CHECK: [[EXIT]]:234 235    // goto SCAN_PHASE;236    // CHECK: br label %[[SCAN_PHASE]]237#pragma omp scan exclusive(s)238 239    // INPUT_PHASE:240    // bar();241    // goto REDUCE;242    // CHECK: [[INPUT_PHASE]]:243    // CHECK: call void @{{.*}}bar{{.*}}()244    // CHECK: br label %[[REDUCE]]245    bar();246 247    // CHECK: [[CONTINUE]]:248 249    // S_PRIV[2].~S();250    // CHECK: [[S_BEGIN:%.+]] = getelementptr inbounds [2 x %struct.S], ptr [[S_PRIV_ADDR]], i{{.+}} 0, i{{.+}} 0251    // CHECK: [[S_END:%.+]] = getelementptr {{.*}}%struct.S, ptr [[S_BEGIN]], i{{.+}} 2252    // CHECK: br label %[[ARRAY_DESTR:[^,]+]]253    // CHECK: [[ARRAY_DESTR]]:254    // CHECK: [[S_CUR:%.+]] = phi ptr [ [[S_END]], %[[CONTINUE]] ], [ [[S_PREV:%.+]], %[[ARRAY_DESTR]] ]255    // CHECK: [[S_PREV]] = getelementptr {{.*}}%struct.S, ptr [[S_CUR]], i{{.+}} -1256    // CHECK: call void [[DESTR]](ptr {{[^,]*}} [[S_PREV]])257    // CHECK: [[IS_DONE:%.+]] = icmp eq ptr [[S_PREV]], [[S_BEGIN]]258    // CHECK: br i1 [[IS_DONE]], label %[[DONE:.+]], label %[[ARRAY_DESTR]]259    // CHECK: [[DONE]]:260    // CHECK: br label %[[INC_BLOCK:[^,]+]]261 262    // ++OMP_CNT;263    // CHECK: [[INC_BLOCK]]:264    // CHECK: [[CNT:%.+]] = load i32, ptr [[OMP_CNT]],265    // CHECK: [[INC:%.+]] = add nsw i32 [[CNT]], 1266    // CHECK: store i32 [[INC]], ptr [[OMP_CNT]],267    // CHECK: br label %[[OMP_HEADER]]268  }269  // CHECK: [[OMP_END]]:270}271 272// CHECK-NOT: !{!"llvm.loop.parallel_accesses"273 274#endif // HEADER275