summaryrefslogtreecommitdiffstats
path: root/clang/test/OpenMP/target_data_use_device_ptr_codegen.cpp
diff options
context:
space:
mode:
authorSamuel Antao <sfantao@us.ibm.com>2016-07-28 14:23:26 +0000
committerSamuel Antao <sfantao@us.ibm.com>2016-07-28 14:23:26 +0000
commitcc10b85789a03b2b32d5b9c5873cdbb1ecac82b0 (patch)
tree6ec7eb5d8945e8937487aab4fef38be1f0591346 /clang/test/OpenMP/target_data_use_device_ptr_codegen.cpp
parent19459580afe9ca86af24e71470e7fd413b0852e2 (diff)
downloadbcm5719-llvm-cc10b85789a03b2b32d5b9c5873cdbb1ecac82b0.tar.gz
bcm5719-llvm-cc10b85789a03b2b32d5b9c5873cdbb1ecac82b0.zip
[OpenMP] Codegen for use_device_ptr clause.
Summary: This patch adds support for the use_device_ptr clause. It includes changes in SEMA that could not be tested without codegen, namely, the use of the first private logic and mappable expressions support. Reviewers: hfinkel, carlo.bertolli, arpith-jacob, kkwli0, ABataev Subscribers: caomhin, cfe-commits Differential Revision: https://reviews.llvm.org/D22691 llvm-svn: 276977
Diffstat (limited to 'clang/test/OpenMP/target_data_use_device_ptr_codegen.cpp')
-rw-r--r--clang/test/OpenMP/target_data_use_device_ptr_codegen.cpp464
1 files changed, 464 insertions, 0 deletions
diff --git a/clang/test/OpenMP/target_data_use_device_ptr_codegen.cpp b/clang/test/OpenMP/target_data_use_device_ptr_codegen.cpp
new file mode 100644
index 00000000000..c4b389a4cbb
--- /dev/null
+++ b/clang/test/OpenMP/target_data_use_device_ptr_codegen.cpp
@@ -0,0 +1,464 @@
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+
+///==========================================================================///
+// RUN: %clang_cc1 -DCK1 -verify -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-64
+// RUN: %clang_cc1 -DCK1 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-64
+// RUN: %clang_cc1 -DCK1 -verify -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-32
+// RUN: %clang_cc1 -DCK1 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK1 --check-prefix CK1-32
+#ifdef CK1
+
+double *g;
+
+// CK1: @g = global double*
+// CK1: [[MTYPE00:@.+]] = {{.*}}constant [1 x i32] [i32 99]
+// CK1: [[MTYPE01:@.+]] = {{.*}}constant [1 x i32] [i32 99]
+// CK1: [[MTYPE03:@.+]] = {{.*}}constant [1 x i32] [i32 99]
+// CK1: [[MTYPE04:@.+]] = {{.*}}constant [1 x i32] [i32 99]
+// CK1: [[MTYPE05:@.+]] = {{.*}}constant [1 x i32] [i32 99]
+// CK1: [[MTYPE06:@.+]] = {{.*}}constant [1 x i32] [i32 99]
+// CK1: [[MTYPE07:@.+]] = {{.*}}constant [1 x i32] [i32 99]
+// CK1: [[MTYPE08:@.+]] = {{.*}}constant [2 x i32] [{{i32 35, i32 99|i32 99, i32 35}}]
+// CK1: [[MTYPE09:@.+]] = {{.*}}constant [2 x i32] [i32 99, i32 99]
+// CK1: [[MTYPE10:@.+]] = {{.*}}constant [2 x i32] [i32 99, i32 99]
+// CK1: [[MTYPE11:@.+]] = {{.*}}constant [2 x i32] [i32 96, i32 35]
+// CK1: [[MTYPE12:@.+]] = {{.*}}constant [2 x i32] [i32 96, i32 35]
+
+// CK1-LABEL: @_Z3foo
+template<typename T>
+void foo(float *&lr, T *&tr) {
+ float *l;
+ T *t;
+
+ // CK1-DAG: [[RVAL:%.+]] = bitcast double* [[T:%.+]] to i8*
+ // CK1-DAG: [[T]] = load double*, double** [[DECL:@g]],
+ // CK1: [[BP:%.+]] = getelementptr inbounds [1 x i8*], [1 x i8*]* %{{.+}}, i32 0, i32 0
+ // CK1: store i8* [[RVAL]], i8** [[BP]],
+ // CK1: call void @__tgt_target_data_begin{{.+}}[[MTYPE00]]
+ // CK1: [[CBP:%.+]] = bitcast i8** [[BP]] to double**
+ // CK1: [[VAL:%.+]] = load double*, double** [[CBP]],
+ // CK1-NOT: store double* [[VAL]], double** [[DECL]],
+ // CK1: store double* [[VAL]], double** [[PVT:%.+]],
+ // CK1: [[TT:%.+]] = load double*, double** [[PVT]],
+ // CK1: getelementptr inbounds double, double* [[TT]], i32 1
+ #pragma omp target data map(g[:10]) use_device_ptr(g)
+ {
+ ++g;
+ }
+ // CK1: call void @__tgt_target_data_end{{.+}}[[MTYPE00]]
+ // CK1: [[TTT:%.+]] = load double*, double** [[DECL]],
+ // CK1: getelementptr inbounds double, double* [[TTT]], i32 1
+ ++g;
+
+ // CK1-DAG: [[RVAL:%.+]] = bitcast float* [[T1:%.+]] to i8*
+ // CK1-DAG: [[T1]] = load float*, float** [[DECL:%.+]],
+ // CK1: [[BP:%.+]] = getelementptr inbounds [1 x i8*], [1 x i8*]* %{{.+}}, i32 0, i32 0
+ // CK1: store i8* [[RVAL]], i8** [[BP]],
+ // CK1: call void @__tgt_target_data_begin{{.+}}[[MTYPE01]]
+ // CK1: [[CBP:%.+]] = bitcast i8** [[BP]] to float**
+ // CK1: [[VAL:%.+]] = load float*, float** [[CBP]],
+ // CK1-NOT: store float* [[VAL]], float** [[DECL]],
+ // CK1: store float* [[VAL]], float** [[PVT:%.+]],
+ // CK1: [[TT1:%.+]] = load float*, float** [[PVT]],
+ // CK1: getelementptr inbounds float, float* [[TT1]], i32 1
+ #pragma omp target data map(l[:10]) use_device_ptr(l)
+ {
+ ++l;
+ }
+ // CK1: call void @__tgt_target_data_end{{.+}}[[MTYPE01]]
+ // CK1: [[TTT:%.+]] = load float*, float** [[DECL]],
+ // CK1: getelementptr inbounds float, float* [[TTT]], i32 1
+ ++l;
+
+ // CK1-NOT: call void @__tgt_target
+ // CK1: [[TTT:%.+]] = load float*, float** [[DECL]],
+ // CK1: getelementptr inbounds float, float* [[TTT]], i32 1
+ #pragma omp target data map(l[:10]) use_device_ptr(l) if(0)
+ {
+ ++l;
+ }
+ // CK1-NOT: call void @__tgt_target
+ // CK1: [[TTT:%.+]] = load float*, float** [[DECL]],
+ // CK1: getelementptr inbounds float, float* [[TTT]], i32 1
+ ++l;
+
+ // CK1-DAG: [[RVAL:%.+]] = bitcast float* [[T1:%.+]] to i8*
+ // CK1-DAG: [[T1]] = load float*, float** [[DECL:%.+]],
+ // CK1: [[BP:%.+]] = getelementptr inbounds [1 x i8*], [1 x i8*]* %{{.+}}, i32 0, i32 0
+ // CK1: store i8* [[RVAL]], i8** [[BP]],
+ // CK1: call void @__tgt_target_data_begin{{.+}}[[MTYPE03]]
+ // CK1: [[CBP:%.+]] = bitcast i8** [[BP]] to float**
+ // CK1: [[VAL:%.+]] = load float*, float** [[CBP]],
+ // CK1-NOT: store float* [[VAL]], float** [[DECL]],
+ // CK1: store float* [[VAL]], float** [[PVT:%.+]],
+ // CK1: [[TT1:%.+]] = load float*, float** [[PVT]],
+ // CK1: getelementptr inbounds float, float* [[TT1]], i32 1
+ #pragma omp target data map(l[:10]) use_device_ptr(l) if(1)
+ {
+ ++l;
+ }
+ // CK1: call void @__tgt_target_data_end{{.+}}[[MTYPE03]]
+ // CK1: [[TTT:%.+]] = load float*, float** [[DECL]],
+ // CK1: getelementptr inbounds float, float* [[TTT]], i32 1
+ ++l;
+
+ // CK1: [[CMP:%.+]] = icmp ne float* %{{.+}}, null
+ // CK1: br i1 [[CMP]], label %[[BTHEN:.+]], label %[[BELSE:.+]]
+
+ // CK1: [[BTHEN]]:
+ // CK1-DAG: [[RVAL:%.+]] = bitcast float* [[T1:%.+]] to i8*
+ // CK1-DAG: [[T1]] = load float*, float** [[DECL:%.+]],
+ // CK1: [[BP:%.+]] = getelementptr inbounds [1 x i8*], [1 x i8*]* %{{.+}}, i32 0, i32 0
+ // CK1: store i8* [[RVAL]], i8** [[BP]],
+ // CK1: call void @__tgt_target_data_begin{{.+}}[[MTYPE04]]
+ // CK1: [[CBP:%.+]] = bitcast i8** [[BP]] to float**
+ // CK1: [[VAL:%.+]] = load float*, float** [[CBP]],
+ // CK1-NOT: store float* [[VAL]], float** [[DECL]],
+ // CK1: store float* [[VAL]], float** [[PVT:%.+]],
+ // CK1: [[TT1:%.+]] = load float*, float** [[PVT]],
+ // CK1: getelementptr inbounds float, float* [[TT1]], i32 1
+ // CK1: br label %[[BEND:.+]]
+
+ // CK1: [[BELSE]]:
+ // CK1: [[TTT:%.+]] = load float*, float** [[DECL]],
+ // CK1: getelementptr inbounds float, float* [[TTT]], i32 1
+ // CK1: br label %[[BEND]]
+ #pragma omp target data map(l[:10]) use_device_ptr(l) if(lr != 0)
+ {
+ ++l;
+ }
+ // CK1: [[BEND]]:
+ // CK1: [[CMP:%.+]] = icmp ne float* %{{.+}}, null
+ // CK1: br i1 [[CMP]], label %[[BTHEN:.+]], label %[[BELSE:.+]]
+
+ // CK1: [[BTHEN]]:
+ // CK1: call void @__tgt_target_data_end{{.+}}[[MTYPE04]]
+ // CK1: br label %[[BEND:.+]]
+
+ // CK1: [[BELSE]]:
+ // CK1: br label %[[BEND]]
+
+ // CK1: [[BEND]]:
+ // CK1: [[TTT:%.+]] = load float*, float** [[DECL]],
+ // CK1: getelementptr inbounds float, float* [[TTT]], i32 1
+ ++l;
+
+ // CK1-DAG: [[RVAL:%.+]] = bitcast float* [[T1:%.+]] to i8*
+ // CK1-DAG: [[T1]] = load float*, float** [[T2:%.+]],
+ // CK1-DAG: [[T2]] = load float**, float*** [[DECL:%.+]],
+ // CK1: [[BP:%.+]] = getelementptr inbounds [1 x i8*], [1 x i8*]* %{{.+}}, i32 0, i32 0
+ // CK1: store i8* [[RVAL]], i8** [[BP]],
+ // CK1: call void @__tgt_target_data_begin{{.+}}[[MTYPE05]]
+ // CK1: [[CBP:%.+]] = bitcast i8** [[BP]] to float**
+ // CK1: [[VAL:%.+]] = load float*, float** [[CBP]],
+ // CK1: store float* [[VAL]], float** [[PVTV:%.+]],
+ // CK1-NOT: store float** [[PVTV]], float*** [[DECL]],
+ // CK1: store float** [[PVTV]], float*** [[PVT:%.+]],
+ // CK1: [[TT1:%.+]] = load float**, float*** [[PVT]],
+ // CK1: [[TT2:%.+]] = load float*, float** [[TT1]],
+ // CK1: getelementptr inbounds float, float* [[TT2]], i32 1
+ #pragma omp target data map(lr[:10]) use_device_ptr(lr)
+ {
+ ++lr;
+ }
+ // CK1: call void @__tgt_target_data_end{{.+}}[[MTYPE05]]
+ // CK1: [[TTT:%.+]] = load float**, float*** [[DECL]],
+ // CK1: [[TTTT:%.+]] = load float*, float** [[TTT]],
+ // CK1: getelementptr inbounds float, float* [[TTTT]], i32 1
+ ++lr;
+
+ // CK1-DAG: [[RVAL:%.+]] = bitcast i32* [[T1:%.+]] to i8*
+ // CK1-DAG: [[T1]] = load i32*, i32** [[DECL:%.+]],
+ // CK1: [[BP:%.+]] = getelementptr inbounds [1 x i8*], [1 x i8*]* %{{.+}}, i32 0, i32 0
+ // CK1: store i8* [[RVAL]], i8** [[BP]],
+ // CK1: call void @__tgt_target_data_begin{{.+}}[[MTYPE06]]
+ // CK1: [[CBP:%.+]] = bitcast i8** [[BP]] to i32**
+ // CK1: [[VAL:%.+]] = load i32*, i32** [[CBP]],
+ // CK1-NOT: store i32* [[VAL]], i32** [[DECL]],
+ // CK1: store i32* [[VAL]], i32** [[PVT:%.+]],
+ // CK1: [[TT1:%.+]] = load i32*, i32** [[PVT]],
+ // CK1: getelementptr inbounds i32, i32* [[TT1]], i32 1
+ #pragma omp target data map(t[:10]) use_device_ptr(t)
+ {
+ ++t;
+ }
+ // CK1: call void @__tgt_target_data_end{{.+}}[[MTYPE06]]
+ // CK1: [[TTT:%.+]] = load i32*, i32** [[DECL]],
+ // CK1: getelementptr inbounds i32, i32* [[TTT]], i32 1
+ ++t;
+
+ // CK1-DAG: [[RVAL:%.+]] = bitcast i32* [[T1:%.+]] to i8*
+ // CK1-DAG: [[T1]] = load i32*, i32** [[T2:%.+]],
+ // CK1-DAG: [[T2]] = load i32**, i32*** [[DECL:%.+]],
+ // CK1: [[BP:%.+]] = getelementptr inbounds [1 x i8*], [1 x i8*]* %{{.+}}, i32 0, i32 0
+ // CK1: store i8* [[RVAL]], i8** [[BP]],
+ // CK1: call void @__tgt_target_data_begin{{.+}}[[MTYPE07]]
+ // CK1: [[CBP:%.+]] = bitcast i8** [[BP]] to i32**
+ // CK1: [[VAL:%.+]] = load i32*, i32** [[CBP]],
+ // CK1: store i32* [[VAL]], i32** [[PVTV:%.+]],
+ // CK1-NOT: store i32** [[PVTV]], i32*** [[DECL]],
+ // CK1: store i32** [[PVTV]], i32*** [[PVT:%.+]],
+ // CK1: [[TT1:%.+]] = load i32**, i32*** [[PVT]],
+ // CK1: [[TT2:%.+]] = load i32*, i32** [[TT1]],
+ // CK1: getelementptr inbounds i32, i32* [[TT2]], i32 1
+ #pragma omp target data map(tr[:10]) use_device_ptr(tr)
+ {
+ ++tr;
+ }
+ // CK1: call void @__tgt_target_data_end{{.+}}[[MTYPE07]]
+ // CK1: [[TTT:%.+]] = load i32**, i32*** [[DECL]],
+ // CK1: [[TTTT:%.+]] = load i32*, i32** [[TTT]],
+ // CK1: getelementptr inbounds i32, i32* [[TTTT]], i32 1
+ ++tr;
+
+ // CK1-DAG: [[RVAL:%.+]] = bitcast float* [[T1:%.+]] to i8*
+ // CK1-DAG: [[T1]] = load float*, float** [[DECL:%.+]],
+ // CK1: [[BP:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* %{{.+}}, i32 0, i32
+ // CK1: store i8* [[RVAL]], i8** [[BP]],
+ // CK1: call void @__tgt_target_data_begin{{.+}}[[MTYPE08]]
+ // CK1: [[CBP:%.+]] = bitcast i8** [[BP]] to float**
+ // CK1: [[VAL:%.+]] = load float*, float** [[CBP]],
+ // CK1-NOT: store float* [[VAL]], float** [[DECL]],
+ // CK1: store float* [[VAL]], float** [[PVT:%.+]],
+ // CK1: [[TT1:%.+]] = load float*, float** [[PVT]],
+ // CK1: getelementptr inbounds float, float* [[TT1]], i32 1
+ #pragma omp target data map(l[:10], t[:10]) use_device_ptr(l)
+ {
+ ++l; ++t;
+ }
+ // CK1: call void @__tgt_target_data_end{{.+}}[[MTYPE08]]
+ // CK1: [[TTT:%.+]] = load float*, float** [[DECL]],
+ // CK1: getelementptr inbounds float, float* [[TTT]], i32 1
+ ++l; ++t;
+
+
+ // CK1: call void @__tgt_target_data_begin{{.+}}[[MTYPE09]]
+ // CK1: [[_CBP:%.+]] = bitcast i8** {{%.+}} to float**
+ // CK1: [[_VAL:%.+]] = load float*, float** [[_CBP]],
+ // CK1: store float* [[_VAL]], float** [[_PVT:%.+]],
+ // CK1: [[CBP:%.+]] = bitcast i8** {{%.+}} to i32**
+ // CK1: [[VAL:%.+]] = load i32*, i32** [[CBP]],
+ // CK1: store i32* [[VAL]], i32** [[PVT:%.+]],
+ // CK1: [[_TT1:%.+]] = load float*, float** [[_PVT]],
+ // CK1: getelementptr inbounds float, float* [[_TT1]], i32 1
+ // CK1: [[TT1:%.+]] = load i32*, i32** [[PVT]],
+ // CK1: getelementptr inbounds i32, i32* [[TT1]], i32 1
+ #pragma omp target data map(l[:10], t[:10]) use_device_ptr(l) use_device_ptr(t)
+ {
+ ++l; ++t;
+ }
+ // CK1: call void @__tgt_target_data_end{{.+}}[[MTYPE09]]
+ // CK1: [[_TTT:%.+]] = load float*, float** {{%.+}},
+ // CK1: getelementptr inbounds float, float* [[_TTT]], i32 1
+ // CK1: [[TTT:%.+]] = load i32*, i32** {{%.+}},
+ // CK1: getelementptr inbounds i32, i32* [[TTT]], i32 1
+ ++l; ++t;
+
+ // CK1: call void @__tgt_target_data_begin{{.+}}[[MTYPE10]]
+ // CK1: [[_CBP:%.+]] = bitcast i8** {{%.+}} to float**
+ // CK1: [[_VAL:%.+]] = load float*, float** [[_CBP]],
+ // CK1: store float* [[_VAL]], float** [[_PVT:%.+]],
+ // CK1: [[CBP:%.+]] = bitcast i8** {{%.+}} to i32**
+ // CK1: [[VAL:%.+]] = load i32*, i32** [[CBP]],
+ // CK1: store i32* [[VAL]], i32** [[PVT:%.+]],
+ // CK1: [[_TT1:%.+]] = load float*, float** [[_PVT]],
+ // CK1: getelementptr inbounds float, float* [[_TT1]], i32 1
+ // CK1: [[TT1:%.+]] = load i32*, i32** [[PVT]],
+ // CK1: getelementptr inbounds i32, i32* [[TT1]], i32 1
+ #pragma omp target data map(l[:10], t[:10]) use_device_ptr(l,t)
+ {
+ ++l; ++t;
+ }
+ // CK1: call void @__tgt_target_data_end{{.+}}[[MTYPE10]]
+ // CK1: [[_TTT:%.+]] = load float*, float** {{%.+}},
+ // CK1: getelementptr inbounds float, float* [[_TTT]], i32 1
+ // CK1: [[TTT:%.+]] = load i32*, i32** {{%.+}},
+ // CK1: getelementptr inbounds i32, i32* [[TTT]], i32 1
+ ++l; ++t;
+
+ // CK1-DAG: [[RVAL:%.+]] = bitcast i32* [[T1:%.+]] to i8*
+ // CK1-DAG: [[T1]] = load i32*, i32** [[DECL:%.+]],
+ // CK1: [[BP:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* %{{.+}}, i32 0, i32 0
+ // CK1: store i8* [[RVAL]], i8** [[BP]],
+ // CK1: call void @__tgt_target_data_begin{{.+}}[[MTYPE11]]
+ // CK1: [[CBP:%.+]] = bitcast i8** [[BP]] to i32**
+ // CK1: [[VAL:%.+]] = load i32*, i32** [[CBP]],
+ // CK1-NOT: store i32* [[VAL]], i32** [[DECL]],
+ // CK1: store i32* [[VAL]], i32** [[PVT:%.+]],
+ // CK1: [[TT1:%.+]] = load i32*, i32** [[PVT]],
+ // CK1: getelementptr inbounds i32, i32* [[TT1]], i32 1
+ #pragma omp target data map(l[:10]) use_device_ptr(t)
+ {
+ ++l; ++t;
+ }
+ // CK1: call void @__tgt_target_data_end{{.+}}[[MTYPE11]]
+ // CK1: [[TTT:%.+]] = load i32*, i32** [[DECL]],
+ // CK1: getelementptr inbounds i32, i32* [[TTT]], i32 1
+ ++l; ++t;
+
+ // CK1-DAG: [[RVAL:%.+]] = bitcast i32* [[T1:%.+]] to i8*
+ // CK1-DAG: [[T1]] = load i32*, i32** [[T2:%.+]],
+ // CK1-DAG: [[T2]] = load i32**, i32*** [[DECL:%.+]],
+ // CK1: [[BP:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* %{{.+}}, i32 0, i32 0
+ // CK1: store i8* [[RVAL]], i8** [[BP]],
+ // CK1: call void @__tgt_target_data_begin{{.+}}[[MTYPE12]]
+ // CK1: [[CBP:%.+]] = bitcast i8** [[BP]] to i32**
+ // CK1: [[VAL:%.+]] = load i32*, i32** [[CBP]],
+ // CK1: store i32* [[VAL]], i32** [[PVTV:%.+]],
+ // CK1-NOT: store i32** [[PVTV]], i32*** [[DECL]],
+ // CK1: store i32** [[PVTV]], i32*** [[PVT:%.+]],
+ // CK1: [[TT1:%.+]] = load i32**, i32*** [[PVT]],
+ // CK1: [[TT2:%.+]] = load i32*, i32** [[TT1]],
+ // CK1: getelementptr inbounds i32, i32* [[TT2]], i32 1
+ #pragma omp target data map(l[:10]) use_device_ptr(tr)
+ {
+ ++l; ++tr;
+ }
+ // CK1: call void @__tgt_target_data_end{{.+}}[[MTYPE12]]
+ // CK1: [[TTT:%.+]] = load i32**, i32*** [[DECL]],
+ // CK1: [[TTTT:%.+]] = load i32*, i32** [[TTT]],
+ // CK1: getelementptr inbounds i32, i32* [[TTTT]], i32 1
+ ++l; ++tr;
+
+}
+
+void bar(float *&a, int *&b) {
+ foo<int>(a,b);
+}
+
+#endif
+///==========================================================================///
+// RUN: %clang_cc1 -DCK2 -verify -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-64
+// RUN: %clang_cc1 -DCK2 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-64
+// RUN: %clang_cc1 -DCK2 -verify -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-32
+// RUN: %clang_cc1 -DCK2 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK2 --check-prefix CK2-32
+#ifdef CK2
+
+// CK2: [[ST:%.+]] = type { double*, double** }
+// CK2: [[MTYPE00:@.+]] = {{.*}}constant [2 x i32] [i32 35, i32 83]
+// CK2: [[MTYPE01:@.+]] = {{.*}}constant [3 x i32] [i32 32, i32 19, i32 83]
+// CK2: [[MTYPE02:@.+]] = {{.*}}constant [2 x i32] [i32 96, i32 35]
+// CK2: [[MTYPE03:@.+]] = {{.*}}constant [4 x i32] [i32 96, i32 32, i32 19, i32 83]
+
+template <typename T>
+struct ST {
+ T *a;
+ double *&b;
+ ST(double *&b) : a(0), b(b) {}
+
+ // CK2-LABEL: @{{.*}}foo{{.*}}
+ void foo(double *&arg) {
+ int *la = 0;
+
+ // CK2: [[BP:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* %{{.+}}, i32 0, i32 1
+ // CK2: store i8* [[RVAL:%.+]], i8** [[BP]],
+ // CK2: call void @__tgt_target_data_begin{{.+}}[[MTYPE00]]
+ // CK2: [[CBP:%.+]] = bitcast i8** [[BP]] to double**
+ // CK2: [[VAL:%.+]] = load double*, double** [[CBP]],
+ // CK2: store double* [[VAL]], double** [[PVT:%.+]],
+ // CK2: store double** [[PVT]], double*** [[PVT2:%.+]],
+ // CK2: [[TT1:%.+]] = load double**, double*** [[PVT2]],
+ // CK2: [[TT2:%.+]] = load double*, double** [[TT1]],
+ // CK2: getelementptr inbounds double, double* [[TT2]], i32 1
+ #pragma omp target data map(a[:10]) use_device_ptr(a)
+ {
+ a++;
+ }
+ // CK2: call void @__tgt_target_data_end{{.+}}[[MTYPE00]]
+ // CK2: [[DECL:%.+]] = getelementptr inbounds [[ST]], [[ST]]* %this1, i32 0, i32 0
+ // CK2: [[TTT:%.+]] = load double*, double** [[DECL]],
+ // CK2: getelementptr inbounds double, double* [[TTT]], i32 1
+ a++;
+
+ // CK2: [[BP:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* %{{.+}}, i32 0, i32 2
+ // CK2: store i8* [[RVAL:%.+]], i8** [[BP]],
+ // CK2: call void @__tgt_target_data_begin{{.+}}[[MTYPE01]]
+ // CK2: [[CBP:%.+]] = bitcast i8** [[BP]] to double**
+ // CK2: [[VAL:%.+]] = load double*, double** [[CBP]],
+ // CK2: store double* [[VAL]], double** [[PVT:%.+]],
+ // CK2: store double** [[PVT]], double*** [[PVT2:%.+]],
+ // CK2: [[TT1:%.+]] = load double**, double*** [[PVT2]],
+ // CK2: [[TT2:%.+]] = load double*, double** [[TT1]],
+ // CK2: getelementptr inbounds double, double* [[TT2]], i32 1
+ #pragma omp target data map(b[:10]) use_device_ptr(b)
+ {
+ b++;
+ }
+ // CK2: call void @__tgt_target_data_end{{.+}}[[MTYPE01]]
+ // CK2: [[DECL:%.+]] = getelementptr inbounds [[ST]], [[ST]]* %{{.+}}, i32 0, i32 1
+ // CK2: [[TTT:%.+]] = load double**, double*** [[DECL]],
+ // CK2: [[TTTT:%.+]] = load double*, double** [[TTT]],
+ // CK2: getelementptr inbounds double, double* [[TTTT]], i32 1
+ b++;
+
+ // CK2: [[BP:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* %{{.+}}, i32 0, i32 0
+ // CK2: store i8* [[RVAL:%.+]], i8** [[BP]],
+ // CK2: call void @__tgt_target_data_begin{{.+}}[[MTYPE02]]
+ // CK2: [[CBP:%.+]] = bitcast i8** [[BP]] to double**
+ // CK2: [[VAL:%.+]] = load double*, double** [[CBP]],
+ // CK2: store double* [[VAL]], double** [[PVT:%.+]],
+ // CK2: store double** [[PVT]], double*** [[PVT2:%.+]],
+ // CK2: [[TT1:%.+]] = load double**, double*** [[PVT2]],
+ // CK2: [[TT2:%.+]] = load double*, double** [[TT1]],
+ // CK2: getelementptr inbounds double, double* [[TT2]], i32 1
+ #pragma omp target data map(la[:10]) use_device_ptr(a)
+ {
+ a++;
+ la++;
+ }
+ // CK2: call void @__tgt_target_data_end{{.+}}[[MTYPE02]]
+ // CK2: [[DECL:%.+]] = getelementptr inbounds [[ST]], [[ST]]* %this1, i32 0, i32 0
+ // CK2: [[TTT:%.+]] = load double*, double** [[DECL]],
+ // CK2: getelementptr inbounds double, double* [[TTT]], i32 1
+ a++;
+ la++;
+
+ // CK2: [[BP:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* %{{.+}}, i32 0, i32 0
+ // CK2: store i8* [[RVAL:%.+]], i8** [[BP]],
+ // CK2: [[_BP:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* %{{.+}}, i32 0, i32 3
+ // CK2: store i8* [[_RVAL:%.+]], i8** [[_BP]],
+ // CK2: call void @__tgt_target_data_begin{{.+}}[[MTYPE03]]
+ // CK2: [[CBP:%.+]] = bitcast i8** [[BP]] to double**
+ // CK2: [[VAL:%.+]] = load double*, double** [[CBP]],
+ // CK2: store double* [[VAL]], double** [[PVT:%.+]],
+ // CK2: store double** [[PVT]], double*** [[PVT2:%.+]],
+ // CK2: [[_CBP:%.+]] = bitcast i8** [[_BP]] to double**
+ // CK2: [[_VAL:%.+]] = load double*, double** [[_CBP]],
+ // CK2: store double* [[_VAL]], double** [[_PVT:%.+]],
+ // CK2: store double** [[_PVT]], double*** [[_PVT2:%.+]],
+ // CK2: [[TT1:%.+]] = load double**, double*** [[PVT2]],
+ // CK2: [[TT2:%.+]] = load double*, double** [[TT1]],
+ // CK2: getelementptr inbounds double, double* [[TT2]], i32 1
+ // CK2: [[_TT1:%.+]] = load double**, double*** [[_PVT2]],
+ // CK2: [[_TT2:%.+]] = load double*, double** [[_TT1]],
+ // CK2: getelementptr inbounds double, double* [[_TT2]], i32 1
+ #pragma omp target data map(b[:10]) use_device_ptr(a, b)
+ {
+ a++;
+ b++;
+ }
+ // CK2: call void @__tgt_target_data_end{{.+}}[[MTYPE03]]
+ // CK2: [[DECL:%.+]] = getelementptr inbounds [[ST]], [[ST]]* %this1, i32 0, i32 0
+ // CK2: [[TTT:%.+]] = load double*, double** [[DECL]],
+ // CK2: getelementptr inbounds double, double* [[TTT]], i32 1
+ // CK2: [[_DECL:%.+]] = getelementptr inbounds [[ST]], [[ST]]* %this1, i32 0, i32 1
+ // CK2: [[_TTT:%.+]] = load double**, double*** [[_DECL]],
+ // CK2: [[_TTTT:%.+]] = load double*, double** [[_TTT]],
+ // CK2: getelementptr inbounds double, double* [[_TTTT]], i32 1
+ a++;
+ b++;
+ }
+};
+
+void bar(double *arg){
+ ST<double> A(arg);
+ A.foo(arg);
+ ++arg;
+}
+#endif
+#endif
OpenPOWER on IntegriCloud