264 lines · cpp
1// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple x86_64-unknown-unknown -emit-llvm %s -fexceptions -fcxx-exceptions -o - | FileCheck %s --check-prefixes=CHECK,CHECK-NORMAL2// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -emit-pch -o %t %s3// RUN: %clang_cc1 -fopenmp -x c++ -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefixes=CHECK,CHECK-NORMAL4 5// RUN: %clang_cc1 -verify -fopenmp -fopenmp-enable-irbuilder -x c++ -triple x86_64-unknown-unknown -emit-llvm %s -fexceptions -fcxx-exceptions -o - | FileCheck %s --check-prefixes=CHECK,CHECK-IRBUILDER6// RUN: %clang_cc1 -fopenmp -fopenmp-enable-irbuilder -x c++ -std=c++11 -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -emit-pch -o %t %s7// RUN: %clang_cc1 -fopenmp -fopenmp-enable-irbuilder -x c++ -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefixes=CHECK,CHECK-IRBUILDER8 9// RUN: %clang_cc1 -verify -fopenmp-simd -x c++ -triple x86_64-unknown-unknown -emit-llvm %s -fexceptions -fcxx-exceptions -o - | FileCheck --check-prefix SIMD-ONLY0 %s10// RUN: %clang_cc1 -fopenmp-simd -x c++ -std=c++11 -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -emit-pch -o %t %s11// RUN: %clang_cc1 -fopenmp-simd -x c++ -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck --check-prefix SIMD-ONLY0 %s12// SIMD-ONLY0-NOT: {{__kmpc|__tgt}}13// expected-no-diagnostics14 15#ifndef HEADER16#define HEADER17 18// CHECK: [[KMP_DIM:%.+]] = type { i64, i64, i64 }19extern int n;20int a[10], b[10], c[10], d[10];21void foo();22 23// CHECK-LABEL:bar24void bar() {25 int i,j;26// CHECK: call void @__kmpc_doacross_init(27// CHECK: call void @__kmpc_doacross_fini(28#pragma omp parallel for ordered(2)29 for (i = 0; i < n; ++i)30 for (j = 0; j < n; ++j)31 a[i] = b[i] + 1;32// CHECK: call void @__kmpc_doacross_init(33// CHECK: call void @__kmpc_doacross_fini(34 #pragma omp for collapse(2) ordered(2)35 for (int i = 0; i < n; i++)36 for (int j = 0; j < n; j++)37 ;38}39 40// CHECK-LABEL: @main()41int main() {42 int i;43// CHECK: [[DIMS:%.+]] = alloca [1 x [[KMP_DIM]]],44// CHECK-NORMAL: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num(ptr [[IDENT:@.+]])45// CHECK: icmp46// CHECK-NEXT: br i1 %47// CHECK: call void @llvm.memset.p0.i64(ptr align 8 [[DIMS]], i8 0, i64 24, i1 false)48// CHECK: [[DIM:%.+]] = getelementptr inbounds [1 x [[KMP_DIM]]], ptr [[DIMS]], i64 0, i64 049// CHECK: getelementptr inbounds nuw [[KMP_DIM]], ptr [[DIM]], i32 0, i32 150// CHECK: store i64 %{{.+}}, ptr %51// CHECK: getelementptr inbounds nuw [[KMP_DIM]], ptr [[DIM]], i32 0, i32 252// CHECK: store i64 1, ptr %53// CHECK: [[DIM:%.+]] = getelementptr inbounds [1 x [[KMP_DIM]]], ptr [[DIMS]], i64 0, i64 054// CHECK-NORMAL: call void @__kmpc_doacross_init(ptr [[IDENT]], i32 [[GTID]], i32 1, ptr [[DIM]])55// CHECK-NORMAL: call void @__kmpc_for_static_init_4(ptr @{{.+}}, i32 [[GTID]], i32 33, ptr %{{.+}}, ptr %{{.+}}, ptr %{{.+}}, ptr %{{.+}}, i32 1, i32 1)56#pragma omp for ordered(1)57 for (int i = 0; i < n; ++i) {58 a[i] = b[i] + 1;59 foo();60// CHECK: invoke void [[FOO:.+]](61// CHECK: load i32, ptr [[I:%.+]],62// CHECK-NEXT: sub nsw i32 %{{.+}}, 063// CHECK-NEXT: sdiv i32 %{{.+}}, 164// CHECK-NEXT: sext i32 %{{.+}} to i6465// CHECK-NEXT: [[TMP:%.+]] = getelementptr inbounds [1 x i64], ptr [[CNT:%.+]], i64 0, i64 066// CHECK-NEXT: store i64 %{{.+}}, ptr [[TMP]],67// CHECK-NEXT: [[TMP:%.+]] = getelementptr inbounds [1 x i64], ptr [[CNT]], i64 0, i64 068// CHECK-NORMAL-NEXT: call void @__kmpc_doacross_post(ptr [[IDENT]], i32 [[GTID]], ptr [[TMP]])69// CHECK-IRBUILDER-NEXT: [[GTID18:%.+]] = call i32 @__kmpc_global_thread_num(ptr [[IDENT:@.+]])70// CHECK-IRBUILDER-NEXT: call void @__kmpc_doacross_post(ptr [[IDENT]], i32 [[GTID18]], ptr [[TMP]])71#pragma omp ordered depend(source)72 c[i] = c[i] + 1;73 foo();74// CHECK: invoke void [[FOO]]75// CHECK: load i32, ptr [[I]],76// CHECK-NEXT: sub nsw i32 %{{.+}}, 277// CHECK-NEXT: sub nsw i32 %{{.+}}, 078// CHECK-NEXT: sdiv i32 %{{.+}}, 179// CHECK-NEXT: sext i32 %{{.+}} to i6480// CHECK-NEXT: [[TMP:%.+]] = getelementptr inbounds [1 x i64], ptr [[CNT:%.+]], i64 0, i64 081// CHECK-NEXT: store i64 %{{.+}}, ptr [[TMP]],82// CHECK-NEXT: [[TMP:%.+]] = getelementptr inbounds [1 x i64], ptr [[CNT]], i64 0, i64 083// CHECK-NORMAL-NEXT: call void @__kmpc_doacross_wait(ptr [[IDENT]], i32 [[GTID]], ptr [[TMP]])84// CHECK-IRBUILDER-NEXT: [[GTID30:%.+]] = call i32 @__kmpc_global_thread_num(ptr [[IDENT:@.+]])85// CHECK-IRBUILDER-NEXT: call void @__kmpc_doacross_wait(ptr [[IDENT]], i32 [[GTID30]], ptr [[TMP]])86#pragma omp ordered depend(sink : i - 2)87 d[i] = a[i - 2];88 }89 90 // CHECK: call void @__kmpc_for_static_fini(91 // CHECK-NORMAL: call void @__kmpc_doacross_fini(ptr [[IDENT]], i32 [[GTID]])92 // CHECK: ret i32 093 return 0;94}95 96// CHECK-LABEL: main197int main1() {98// CHECK: [[DIMS:%.+]] = alloca [1 x [[KMP_DIM]]],99// CHECK-NORMAL: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num(ptr [[IDENT:@.+]])100// CHECK: icmp101// CHECK-NEXT: br i1 %102// CHECK: call void @llvm.memset.p0.i64(ptr align 8 [[DIMS]], i8 0, i64 24, i1 false)103// CHECK: [[DIM:%.+]] = getelementptr inbounds [1 x [[KMP_DIM]]], ptr [[DIMS]], i64 0, i64 0104// CHECK: getelementptr inbounds nuw [[KMP_DIM]], ptr [[DIM]], i32 0, i32 1105// CHECK: store i64 %{{.+}}, ptr %106// CHECK: getelementptr inbounds nuw [[KMP_DIM]], ptr [[DIM]], i32 0, i32 2107// CHECK: store i64 1, ptr %108// CHECK: [[DIM:%.+]] = getelementptr inbounds [1 x [[KMP_DIM]]], ptr [[DIMS]], i64 0, i64 0109// CHECK-NORMAL: call void @__kmpc_doacross_init(ptr [[IDENT]], i32 [[GTID]], i32 1, ptr [[DIM]])110// CHECK-NORMAL: call void @__kmpc_for_static_init_4(ptr @{{.+}}, i32 [[GTID]], i32 33, ptr %{{.+}}, ptr %{{.+}}, ptr %{{.+}}, ptr %{{.+}}, i32 1, i32 1)111#pragma omp for ordered(1)112 for (int i = n; i > 0; --i) {113 a[i] = b[i] + 1;114 foo();115// CHECK: invoke void [[FOO:.+]](116// CHECK: [[UB_VAL:%.+]] = load i32, ptr [[UB:%.+]],117// CHECK-NEXT: [[I_VAL:%.+]] = load i32, ptr [[I:%.+]],118// CHECK-NEXT: sub i32 [[UB_VAL]], [[I_VAL]]119// CHECK-NEXT: udiv i32 %{{.+}}, 1120// CHECK-NEXT: zext i32 %{{.+}} to i64121// CHECK-NEXT: [[TMP:%.+]] = getelementptr inbounds [1 x i64], ptr [[CNT:%.+]], i64 0, i64 0122// CHECK-NEXT: store i64 %{{.+}}, ptr [[TMP]],123// CHECK-NEXT: [[TMP:%.+]] = getelementptr inbounds [1 x i64], ptr [[CNT]], i64 0, i64 0124// CHECK-NORMAL-NEXT: call void @__kmpc_doacross_post(ptr [[IDENT]], i32 [[GTID]], ptr [[TMP]])125// CHECK-IRBUILDER-NEXT: [[GTID17:%.+]] = call i32 @__kmpc_global_thread_num(ptr [[IDENT:@.+]])126// CHECK-IRBUILDER-NEXT: call void @__kmpc_doacross_post(ptr [[IDENT]], i32 [[GTID17]], ptr [[TMP]])127#pragma omp ordered depend(source)128 c[i] = c[i] + 1;129 foo();130// CHECK: invoke void [[FOO]]131// CHECK: [[UB_VAL:%.+]] = load i32, ptr [[UB]],132// CHECK-NEXT: [[I_VAL:%.+]] = load i32, ptr [[I]],133// CHECK-NEXT: [[SUB:%.+]] = sub nsw i32 [[I_VAL]], 2134// CHECK-NEXT: sub i32 [[UB_VAL]], [[SUB]]135// CHECK-NEXT: udiv i32 %{{.+}}, 1136// CHECK-NEXT: zext i32 %{{.+}} to i64137// CHECK-NEXT: [[TMP:%.+]] = getelementptr inbounds [1 x i64], ptr [[CNT:%.+]], i64 0, i64 0138// CHECK-NEXT: store i64 %{{.+}}, ptr [[TMP]],139// CHECK-NEXT: [[TMP:%.+]] = getelementptr inbounds [1 x i64], ptr [[CNT]], i64 0, i64 0140// CHECK-NORMAL-NEXT: call void @__kmpc_doacross_wait(ptr [[IDENT]], i32 [[GTID]], ptr [[TMP]])141// CHECK-IRBUILDER-NEXT: [[GTID29:%.+]] = call i32 @__kmpc_global_thread_num(ptr [[IDENT:@.+]])142// CHECK-IRBUILDER-NEXT: call void @__kmpc_doacross_wait(ptr [[IDENT]], i32 [[GTID29]], ptr [[TMP]])143#pragma omp ordered depend(sink : i - 2)144 d[i] = a[i - 2];145 }146 // CHECK: call void @__kmpc_for_static_fini(147 // CHECK-NORMAL: call void @__kmpc_doacross_fini(ptr [[IDENT]], i32 [[GTID]])148 // CHECK: ret i32 0149 return 0;150}151 152// CHECK: define {{.+}}TestStruct153template <typename T>154struct TestStruct {155 static const int M = 10;156 static const int N = 20;157 T i;158 T a[N][M];159 T b[N][M];160 T foo(T, T);161 T bar(T, T, T);162 void baz(T, T);163 TestStruct() {164// CHECK: [[DIMS:%.+]] = alloca [2 x [[KMP_DIM]]],165// CHECK-NORMAL: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num(ptr [[IDENT:@.+]])166// CHECK: call void @llvm.memset.p0.i64(ptr align 8 [[DIMS]], i8 0, i64 48, i1 false)167// CHECK: [[DIM:%.+]] = getelementptr inbounds [2 x [[KMP_DIM]]], ptr [[DIMS]], i64 0, i64 0168// CHECK: getelementptr inbounds nuw [[KMP_DIM]], ptr [[DIM]], i32 0, i32 1169// CHECK: store i64 10, ptr %170// CHECK: getelementptr inbounds nuw [[KMP_DIM]], ptr [[DIM]], i32 0, i32 2171// CHECK: store i64 1, ptr %172// CHECK: [[DIM:%.+]] = getelementptr inbounds [2 x [[KMP_DIM]]], ptr [[DIMS]], i64 0, i64 1173// CHECK: getelementptr inbounds nuw [[KMP_DIM]], ptr [[DIM]], i32 0, i32 1174// CHECK: store i64 %{{.+}}, ptr %175// CHECK: getelementptr inbounds nuw [[KMP_DIM]], ptr [[DIM]], i32 0, i32 2176// CHECK: store i64 1, ptr %177// CHECK: [[DIM:%.+]] = getelementptr inbounds [2 x [[KMP_DIM]]], ptr [[DIMS]], i64 0, i64 0178// CHECK-NORMAL: call void @__kmpc_doacross_init(ptr [[IDENT]], i32 [[GTID]], i32 2, ptr [[DIM]])179// CHECK-NORMAL: call void @__kmpc_for_static_init_4(ptr @{{.+}}, i32 [[GTID]], i32 33, ptr %{{.+}}, ptr %{{.+}}, ptr %{{.+}}, ptr %{{.+}}, i32 1, i32 1)180#pragma omp for ordered(2)181 for (T j = 0; j < M; j++)182 for (i = 0; i < n; i += 2) {183 a[i][j] = foo(i, j);184// CHECK: invoke {{.+TestStruct.+foo}}185// CHECK: load ptr, ptr %186// CHECK: load i32, ptr %187// CHECK: load i32, ptr %188// CHECK: load i32, ptr [[J:%.+]],189// CHECK-NEXT: sub nsw i32 %{{.+}}, 0190// CHECK-NEXT: sdiv i32 %{{.+}}, 1191// CHECK-NEXT: sext i32 %{{.+}} to i64192// CHECK-NORMAL-NEXT: [[TMP:%.+]] = getelementptr inbounds [2 x i64], ptr [[CNT:%.+]], i64 0, i64 0193// CHECK-NORMAL-NEXT: store i64 %{{.+}}, ptr [[TMP:%.+]],194// CHECK-NEXT: [[I:%.+]] = load ptr, ptr [[I_REF:%.+]],195// CHECK-NEXT: load i32, ptr [[I]],196// CHECK-NEXT: sub nsw i32 %{{.+}}, 2197// CHECK-NEXT: sub nsw i32 %{{.+}}, 0198// CHECK-NEXT: sdiv i32 %{{.+}}, 2199// CHECK-NEXT: sext i32 %{{.+}} to i64200// CHECK-IRBUILDER-NEXT: [[TMP:%.+]] = getelementptr inbounds [2 x i64], ptr [[CNT:%.+]], i64 0, i64 0201// CHECK-IRBUILDER-NEXT: store i64 %{{.+}}, ptr [[TMP:%.+]],202// CHECK-NEXT: [[TMP:%.+]] = getelementptr inbounds [2 x i64], ptr [[CNT]], i64 0, i64 1203// CHECK-NEXT: store i64 %{{.+}}, ptr [[TMP]],204// CHECK-NEXT: [[TMP:%.+]] = getelementptr inbounds [2 x i64], ptr [[CNT]], i64 0, i64 0205// CHECK-NORMAL-NEXT: call void @__kmpc_doacross_wait(ptr [[IDENT]], i32 [[GTID]], ptr [[TMP]])206// CHECK-IRBUILDER-NEXT: [[GTID18:%.+]] = call i32 @__kmpc_global_thread_num(ptr [[IDENT:@.+]])207// CHECK-IRBUILDER-NEXT: call void @__kmpc_doacross_wait(ptr [[IDENT]], i32 [[GTID18]], ptr [[TMP]])208// CHECK-NEXT: load i32, ptr [[J:%.+]],209// CHECK-NEXT: sub nsw i32 %{{.+}}, 1210// CHECK-NEXT: sub nsw i32 %{{.+}}, 0211// CHECK-NEXT: sdiv i32 %{{.+}}, 1212// CHECK-NEXT: sext i32 %{{.+}} to i64213// CHECK-NORMAL-NEXT: [[TMP:%.+]] = getelementptr inbounds [2 x i64], ptr [[CNT:%.+]], i64 0, i64 0214// CHECK-NORMAL-NEXT: store i64 %{{.+}}, ptr [[TMP]],215// CHECK-NEXT: [[I:%.+]] = load ptr, ptr [[I_REF]],216// CHECK-NEXT: load i32, ptr [[I]],217// CHECK-NEXT: sub nsw i32 %{{.+}}, 0218// CHECK-NEXT: sdiv i32 %{{.+}}, 2219// CHECK-NEXT: sext i32 %{{.+}} to i64220// CHECK-IRBUILDER-NEXT: [[TMP:%.+]] = getelementptr inbounds [2 x i64], ptr [[CNT:%.+]], i64 0, i64 0221// CHECK-IRBUILDER-NEXT: store i64 %{{.+}}, ptr [[TMP]],222// CHECK-NEXT: [[TMP:%.+]] = getelementptr inbounds [2 x i64], ptr [[CNT]], i64 0, i64 1223// CHECK-NEXT: store i64 %{{.+}}, ptr [[TMP]],224// CHECK-NEXT: [[TMP:%.+]] = getelementptr inbounds [2 x i64], ptr [[CNT]], i64 0, i64 0225// CHECK-NORMAL-NEXT: call void @__kmpc_doacross_wait(ptr [[IDENT]], i32 [[GTID]], ptr [[TMP]])226// CHECK-IRBUILDER-NEXT: [[GTID27:%.+]] = call i32 @__kmpc_global_thread_num(ptr [[IDENT:@.+]])227// CHECK-IRBUILDER-NEXT: call void @__kmpc_doacross_wait(ptr [[IDENT]], i32 [[GTID27]], ptr [[TMP]])228#pragma omp ordered depend(sink : j, i - 2) depend(sink : j - 1, i)229 b[i][j] = bar(a[i][j], b[i - 1][j], b[i][j - 1]);230// CHECK: invoke {{.+TestStruct.+bar}}231// CHECK: load ptr, ptr %232// CHECK: load i32, ptr %233// CHECK: load i32, ptr %234// CHECK: load i32, ptr [[J]],235// CHECK-NEXT: sub nsw i32 %{{.+}}, 0236// CHECK-NEXT: sdiv i32 %{{.+}}, 1237// CHECK-NEXT: sext i32 %{{.+}} to i64238// CHECK-NORMAL-NEXT: [[TMP:%.+]] = getelementptr inbounds [2 x i64], ptr [[CNT:%.+]], i64 0, i64 0239// CHECK-NORMAL-NEXT: store i64 %{{.+}}, ptr [[TMP]],240// CHECK-NEXT: [[I:%.+]] = load ptr, ptr [[I_REF]],241// CHECK-NEXT: load i32, ptr [[I]],242// CHECK-NEXT: sub nsw i32 %{{.+}}, 0243// CHECK-NEXT: sdiv i32 %{{.+}}, 2244// CHECK-NEXT: sext i32 %{{.+}} to i64245// CHECK-IRBUILDER-NEXT: [[TMP:%.+]] = getelementptr inbounds [2 x i64], ptr [[CNT:%.+]], i64 0, i64 0246// CHECK-IRBUILDER-NEXT: store i64 %{{.+}}, ptr [[TMP]],247// CHECK-NEXT: [[TMP:%.+]] = getelementptr inbounds [2 x i64], ptr [[CNT]], i64 0, i64 1248// CHECK-NEXT: store i64 %{{.+}}, ptr [[TMP]],249// CHECK-NEXT: [[TMP:%.+]] = getelementptr inbounds [2 x i64], ptr [[CNT]], i64 0, i64 0250// CHECK-NORMAL-NEXT: call void @__kmpc_doacross_post(ptr [[IDENT]], i32 [[GTID]], ptr [[TMP]])251// CHECK-IRBUILDER-NEXT: [[GTID58:%.+]] = call i32 @__kmpc_global_thread_num(ptr [[IDENT:@.+]])252// CHECK-IRBUILDER-NEXT: call void @__kmpc_doacross_post(ptr [[IDENT]], i32 [[GTID58]], ptr [[TMP]])253#pragma omp ordered depend(source)254 baz(a[i][j], b[i][j]);255 }256 }257 // CHECK: call void @__kmpc_for_static_fini(258 // CHECK-NORMAL: call void @__kmpc_doacross_fini(ptr [[IDENT]], i32 [[GTID]])259 // CHECK: ret260};261 262TestStruct<int> s;263#endif // HEADER264