1 // expected-no-diagnostics 2 #ifndef HEADER 3 #define HEADER 4 5 ///==========================================================================/// 6 // 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 7 // 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 8 // 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 9 // 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 10 // 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 11 // 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 12 #ifdef CK1 13 14 double *g; 15 16 // CK1: @g = global double* 17 // CK1: [[MTYPE00:@.+]] = {{.*}}constant [1 x i32] [i32 99] 18 // CK1: [[MTYPE01:@.+]] = {{.*}}constant [1 x i32] [i32 99] 19 // CK1: [[MTYPE03:@.+]] = {{.*}}constant [1 x i32] [i32 99] 20 // CK1: [[MTYPE04:@.+]] = {{.*}}constant [1 x i32] [i32 99] 21 // CK1: [[MTYPE05:@.+]] = {{.*}}constant [1 x i32] [i32 99] 22 // CK1: [[MTYPE06:@.+]] = {{.*}}constant [1 x i32] [i32 99] 23 // CK1: [[MTYPE07:@.+]] = {{.*}}constant [1 x i32] [i32 99] 24 // CK1: [[MTYPE08:@.+]] = {{.*}}constant [2 x i32] [{{i32 35, i32 99|i32 99, i32 35}}] 25 // CK1: [[MTYPE09:@.+]] = {{.*}}constant [2 x i32] [i32 99, i32 99] 26 // CK1: [[MTYPE10:@.+]] = {{.*}}constant [2 x i32] [i32 99, i32 99] 27 // CK1: [[MTYPE11:@.+]] = {{.*}}constant [2 x i32] [i32 96, i32 35] 28 // CK1: [[MTYPE12:@.+]] = {{.*}}constant [2 x i32] [i32 96, i32 35] 29 30 // CK1-LABEL: @_Z3foo 31 template<typename T> 32 void foo(float *&lr, T *&tr) { 33 float *l; 34 T *t; 35 36 // CK1-DAG: [[RVAL:%.+]] = bitcast double* [[T:%.+]] to i8* 37 // CK1-DAG: [[T]] = load double*, double** [[DECL:@g]], 38 // CK1: [[BP:%.+]] = getelementptr inbounds [1 x i8*], [1 x i8*]* %{{.+}}, i32 0, i32 0 39 // CK1: store i8* [[RVAL]], i8** [[BP]], 40 // CK1: call void @__tgt_target_data_begin{{.+}}[[MTYPE00]] 41 // CK1: [[CBP:%.+]] = bitcast i8** [[BP]] to double** 42 // CK1: [[VAL:%.+]] = load double*, double** [[CBP]], 43 // CK1-NOT: store double* [[VAL]], double** [[DECL]], 44 // CK1: store double* [[VAL]], double** [[PVT:%.+]], 45 // CK1: [[TT:%.+]] = load double*, double** [[PVT]], 46 // CK1: getelementptr inbounds double, double* [[TT]], i32 1 47 #pragma omp target data map(g[:10]) use_device_ptr(g) 48 { 49 ++g; 50 } 51 // CK1: call void @__tgt_target_data_end{{.+}}[[MTYPE00]] 52 // CK1: [[TTT:%.+]] = load double*, double** [[DECL]], 53 // CK1: getelementptr inbounds double, double* [[TTT]], i32 1 54 ++g; 55 56 // CK1-DAG: [[RVAL:%.+]] = bitcast float* [[T1:%.+]] to i8* 57 // CK1-DAG: [[T1]] = load float*, float** [[DECL:%.+]], 58 // CK1: [[BP:%.+]] = getelementptr inbounds [1 x i8*], [1 x i8*]* %{{.+}}, i32 0, i32 0 59 // CK1: store i8* [[RVAL]], i8** [[BP]], 60 // CK1: call void @__tgt_target_data_begin{{.+}}[[MTYPE01]] 61 // CK1: [[CBP:%.+]] = bitcast i8** [[BP]] to float** 62 // CK1: [[VAL:%.+]] = load float*, float** [[CBP]], 63 // CK1-NOT: store float* [[VAL]], float** [[DECL]], 64 // CK1: store float* [[VAL]], float** [[PVT:%.+]], 65 // CK1: [[TT1:%.+]] = load float*, float** [[PVT]], 66 // CK1: getelementptr inbounds float, float* [[TT1]], i32 1 67 #pragma omp target data map(l[:10]) use_device_ptr(l) 68 { 69 ++l; 70 } 71 // CK1: call void @__tgt_target_data_end{{.+}}[[MTYPE01]] 72 // CK1: [[TTT:%.+]] = load float*, float** [[DECL]], 73 // CK1: getelementptr inbounds float, float* [[TTT]], i32 1 74 ++l; 75 76 // CK1-NOT: call void @__tgt_target 77 // CK1: [[TTT:%.+]] = load float*, float** [[DECL]], 78 // CK1: getelementptr inbounds float, float* [[TTT]], i32 1 79 #pragma omp target data map(l[:10]) use_device_ptr(l) if(0) 80 { 81 ++l; 82 } 83 // CK1-NOT: call void @__tgt_target 84 // CK1: [[TTT:%.+]] = load float*, float** [[DECL]], 85 // CK1: getelementptr inbounds float, float* [[TTT]], i32 1 86 ++l; 87 88 // CK1-DAG: [[RVAL:%.+]] = bitcast float* [[T1:%.+]] to i8* 89 // CK1-DAG: [[T1]] = load float*, float** [[DECL:%.+]], 90 // CK1: [[BP:%.+]] = getelementptr inbounds [1 x i8*], [1 x i8*]* %{{.+}}, i32 0, i32 0 91 // CK1: store i8* [[RVAL]], i8** [[BP]], 92 // CK1: call void @__tgt_target_data_begin{{.+}}[[MTYPE03]] 93 // CK1: [[CBP:%.+]] = bitcast i8** [[BP]] to float** 94 // CK1: [[VAL:%.+]] = load float*, float** [[CBP]], 95 // CK1-NOT: store float* [[VAL]], float** [[DECL]], 96 // CK1: store float* [[VAL]], float** [[PVT:%.+]], 97 // CK1: [[TT1:%.+]] = load float*, float** [[PVT]], 98 // CK1: getelementptr inbounds float, float* [[TT1]], i32 1 99 #pragma omp target data map(l[:10]) use_device_ptr(l) if(1) 100 { 101 ++l; 102 } 103 // CK1: call void @__tgt_target_data_end{{.+}}[[MTYPE03]] 104 // CK1: [[TTT:%.+]] = load float*, float** [[DECL]], 105 // CK1: getelementptr inbounds float, float* [[TTT]], i32 1 106 ++l; 107 108 // CK1: [[CMP:%.+]] = icmp ne float* %{{.+}}, null 109 // CK1: br i1 [[CMP]], label %[[BTHEN:.+]], label %[[BELSE:.+]] 110 111 // CK1: [[BTHEN]]: 112 // CK1-DAG: [[RVAL:%.+]] = bitcast float* [[T1:%.+]] to i8* 113 // CK1-DAG: [[T1]] = load float*, float** [[DECL:%.+]], 114 // CK1: [[BP:%.+]] = getelementptr inbounds [1 x i8*], [1 x i8*]* %{{.+}}, i32 0, i32 0 115 // CK1: store i8* [[RVAL]], i8** [[BP]], 116 // CK1: call void @__tgt_target_data_begin{{.+}}[[MTYPE04]] 117 // CK1: [[CBP:%.+]] = bitcast i8** [[BP]] to float** 118 // CK1: [[VAL:%.+]] = load float*, float** [[CBP]], 119 // CK1-NOT: store float* [[VAL]], float** [[DECL]], 120 // CK1: store float* [[VAL]], float** [[PVT:%.+]], 121 // CK1: [[TT1:%.+]] = load float*, float** [[PVT]], 122 // CK1: getelementptr inbounds float, float* [[TT1]], i32 1 123 // CK1: br label %[[BEND:.+]] 124 125 // CK1: [[BELSE]]: 126 // CK1: [[TTT:%.+]] = load float*, float** [[DECL]], 127 // CK1: getelementptr inbounds float, float* [[TTT]], i32 1 128 // CK1: br label %[[BEND]] 129 #pragma omp target data map(l[:10]) use_device_ptr(l) if(lr != 0) 130 { 131 ++l; 132 } 133 // CK1: [[BEND]]: 134 // CK1: [[CMP:%.+]] = icmp ne float* %{{.+}}, null 135 // CK1: br i1 [[CMP]], label %[[BTHEN:.+]], label %[[BELSE:.+]] 136 137 // CK1: [[BTHEN]]: 138 // CK1: call void @__tgt_target_data_end{{.+}}[[MTYPE04]] 139 // CK1: br label %[[BEND:.+]] 140 141 // CK1: [[BELSE]]: 142 // CK1: br label %[[BEND]] 143 144 // CK1: [[BEND]]: 145 // CK1: [[TTT:%.+]] = load float*, float** [[DECL]], 146 // CK1: getelementptr inbounds float, float* [[TTT]], i32 1 147 ++l; 148 149 // CK1-DAG: [[RVAL:%.+]] = bitcast float* [[T1:%.+]] to i8* 150 // CK1-DAG: [[T1]] = load float*, float** [[T2:%.+]], 151 // CK1-DAG: [[T2]] = load float**, float*** [[DECL:%.+]], 152 // CK1: [[BP:%.+]] = getelementptr inbounds [1 x i8*], [1 x i8*]* %{{.+}}, i32 0, i32 0 153 // CK1: store i8* [[RVAL]], i8** [[BP]], 154 // CK1: call void @__tgt_target_data_begin{{.+}}[[MTYPE05]] 155 // CK1: [[CBP:%.+]] = bitcast i8** [[BP]] to float** 156 // CK1: [[VAL:%.+]] = load float*, float** [[CBP]], 157 // CK1: store float* [[VAL]], float** [[PVTV:%.+]], 158 // CK1-NOT: store float** [[PVTV]], float*** [[DECL]], 159 // CK1: store float** [[PVTV]], float*** [[PVT:%.+]], 160 // CK1: [[TT1:%.+]] = load float**, float*** [[PVT]], 161 // CK1: [[TT2:%.+]] = load float*, float** [[TT1]], 162 // CK1: getelementptr inbounds float, float* [[TT2]], i32 1 163 #pragma omp target data map(lr[:10]) use_device_ptr(lr) 164 { 165 ++lr; 166 } 167 // CK1: call void @__tgt_target_data_end{{.+}}[[MTYPE05]] 168 // CK1: [[TTT:%.+]] = load float**, float*** [[DECL]], 169 // CK1: [[TTTT:%.+]] = load float*, float** [[TTT]], 170 // CK1: getelementptr inbounds float, float* [[TTTT]], i32 1 171 ++lr; 172 173 // CK1-DAG: [[RVAL:%.+]] = bitcast i32* [[T1:%.+]] to i8* 174 // CK1-DAG: [[T1]] = load i32*, i32** [[DECL:%.+]], 175 // CK1: [[BP:%.+]] = getelementptr inbounds [1 x i8*], [1 x i8*]* %{{.+}}, i32 0, i32 0 176 // CK1: store i8* [[RVAL]], i8** [[BP]], 177 // CK1: call void @__tgt_target_data_begin{{.+}}[[MTYPE06]] 178 // CK1: [[CBP:%.+]] = bitcast i8** [[BP]] to i32** 179 // CK1: [[VAL:%.+]] = load i32*, i32** [[CBP]], 180 // CK1-NOT: store i32* [[VAL]], i32** [[DECL]], 181 // CK1: store i32* [[VAL]], i32** [[PVT:%.+]], 182 // CK1: [[TT1:%.+]] = load i32*, i32** [[PVT]], 183 // CK1: getelementptr inbounds i32, i32* [[TT1]], i32 1 184 #pragma omp target data map(t[:10]) use_device_ptr(t) 185 { 186 ++t; 187 } 188 // CK1: call void @__tgt_target_data_end{{.+}}[[MTYPE06]] 189 // CK1: [[TTT:%.+]] = load i32*, i32** [[DECL]], 190 // CK1: getelementptr inbounds i32, i32* [[TTT]], i32 1 191 ++t; 192 193 // CK1-DAG: [[RVAL:%.+]] = bitcast i32* [[T1:%.+]] to i8* 194 // CK1-DAG: [[T1]] = load i32*, i32** [[T2:%.+]], 195 // CK1-DAG: [[T2]] = load i32**, i32*** [[DECL:%.+]], 196 // CK1: [[BP:%.+]] = getelementptr inbounds [1 x i8*], [1 x i8*]* %{{.+}}, i32 0, i32 0 197 // CK1: store i8* [[RVAL]], i8** [[BP]], 198 // CK1: call void @__tgt_target_data_begin{{.+}}[[MTYPE07]] 199 // CK1: [[CBP:%.+]] = bitcast i8** [[BP]] to i32** 200 // CK1: [[VAL:%.+]] = load i32*, i32** [[CBP]], 201 // CK1: store i32* [[VAL]], i32** [[PVTV:%.+]], 202 // CK1-NOT: store i32** [[PVTV]], i32*** [[DECL]], 203 // CK1: store i32** [[PVTV]], i32*** [[PVT:%.+]], 204 // CK1: [[TT1:%.+]] = load i32**, i32*** [[PVT]], 205 // CK1: [[TT2:%.+]] = load i32*, i32** [[TT1]], 206 // CK1: getelementptr inbounds i32, i32* [[TT2]], i32 1 207 #pragma omp target data map(tr[:10]) use_device_ptr(tr) 208 { 209 ++tr; 210 } 211 // CK1: call void @__tgt_target_data_end{{.+}}[[MTYPE07]] 212 // CK1: [[TTT:%.+]] = load i32**, i32*** [[DECL]], 213 // CK1: [[TTTT:%.+]] = load i32*, i32** [[TTT]], 214 // CK1: getelementptr inbounds i32, i32* [[TTTT]], i32 1 215 ++tr; 216 217 // CK1-DAG: [[RVAL:%.+]] = bitcast float* [[T1:%.+]] to i8* 218 // CK1-DAG: [[T1]] = load float*, float** [[DECL:%.+]], 219 // CK1: [[BP:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* %{{.+}}, i32 0, i32 220 // CK1: store i8* [[RVAL]], i8** [[BP]], 221 // CK1: call void @__tgt_target_data_begin{{.+}}[[MTYPE08]] 222 // CK1: [[CBP:%.+]] = bitcast i8** [[BP]] to float** 223 // CK1: [[VAL:%.+]] = load float*, float** [[CBP]], 224 // CK1-NOT: store float* [[VAL]], float** [[DECL]], 225 // CK1: store float* [[VAL]], float** [[PVT:%.+]], 226 // CK1: [[TT1:%.+]] = load float*, float** [[PVT]], 227 // CK1: getelementptr inbounds float, float* [[TT1]], i32 1 228 #pragma omp target data map(l[:10], t[:10]) use_device_ptr(l) 229 { 230 ++l; ++t; 231 } 232 // CK1: call void @__tgt_target_data_end{{.+}}[[MTYPE08]] 233 // CK1: [[TTT:%.+]] = load float*, float** [[DECL]], 234 // CK1: getelementptr inbounds float, float* [[TTT]], i32 1 235 ++l; ++t; 236 237 238 // CK1: call void @__tgt_target_data_begin{{.+}}[[MTYPE09]] 239 // CK1: [[_CBP:%.+]] = bitcast i8** {{%.+}} to float** 240 // CK1: [[_VAL:%.+]] = load float*, float** [[_CBP]], 241 // CK1: store float* [[_VAL]], float** [[_PVT:%.+]], 242 // CK1: [[CBP:%.+]] = bitcast i8** {{%.+}} to i32** 243 // CK1: [[VAL:%.+]] = load i32*, i32** [[CBP]], 244 // CK1: store i32* [[VAL]], i32** [[PVT:%.+]], 245 // CK1: [[_TT1:%.+]] = load float*, float** [[_PVT]], 246 // CK1: getelementptr inbounds float, float* [[_TT1]], i32 1 247 // CK1: [[TT1:%.+]] = load i32*, i32** [[PVT]], 248 // CK1: getelementptr inbounds i32, i32* [[TT1]], i32 1 249 #pragma omp target data map(l[:10], t[:10]) use_device_ptr(l) use_device_ptr(t) 250 { 251 ++l; ++t; 252 } 253 // CK1: call void @__tgt_target_data_end{{.+}}[[MTYPE09]] 254 // CK1: [[_TTT:%.+]] = load float*, float** {{%.+}}, 255 // CK1: getelementptr inbounds float, float* [[_TTT]], i32 1 256 // CK1: [[TTT:%.+]] = load i32*, i32** {{%.+}}, 257 // CK1: getelementptr inbounds i32, i32* [[TTT]], i32 1 258 ++l; ++t; 259 260 // CK1: call void @__tgt_target_data_begin{{.+}}[[MTYPE10]] 261 // CK1: [[_CBP:%.+]] = bitcast i8** {{%.+}} to float** 262 // CK1: [[_VAL:%.+]] = load float*, float** [[_CBP]], 263 // CK1: store float* [[_VAL]], float** [[_PVT:%.+]], 264 // CK1: [[CBP:%.+]] = bitcast i8** {{%.+}} to i32** 265 // CK1: [[VAL:%.+]] = load i32*, i32** [[CBP]], 266 // CK1: store i32* [[VAL]], i32** [[PVT:%.+]], 267 // CK1: [[_TT1:%.+]] = load float*, float** [[_PVT]], 268 // CK1: getelementptr inbounds float, float* [[_TT1]], i32 1 269 // CK1: [[TT1:%.+]] = load i32*, i32** [[PVT]], 270 // CK1: getelementptr inbounds i32, i32* [[TT1]], i32 1 271 #pragma omp target data map(l[:10], t[:10]) use_device_ptr(l,t) 272 { 273 ++l; ++t; 274 } 275 // CK1: call void @__tgt_target_data_end{{.+}}[[MTYPE10]] 276 // CK1: [[_TTT:%.+]] = load float*, float** {{%.+}}, 277 // CK1: getelementptr inbounds float, float* [[_TTT]], i32 1 278 // CK1: [[TTT:%.+]] = load i32*, i32** {{%.+}}, 279 // CK1: getelementptr inbounds i32, i32* [[TTT]], i32 1 280 ++l; ++t; 281 282 // CK1-DAG: [[RVAL:%.+]] = bitcast i32* [[T1:%.+]] to i8* 283 // CK1-DAG: [[T1]] = load i32*, i32** [[DECL:%.+]], 284 // CK1: [[BP:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* %{{.+}}, i32 0, i32 0 285 // CK1: store i8* [[RVAL]], i8** [[BP]], 286 // CK1: call void @__tgt_target_data_begin{{.+}}[[MTYPE11]] 287 // CK1: [[CBP:%.+]] = bitcast i8** [[BP]] to i32** 288 // CK1: [[VAL:%.+]] = load i32*, i32** [[CBP]], 289 // CK1-NOT: store i32* [[VAL]], i32** [[DECL]], 290 // CK1: store i32* [[VAL]], i32** [[PVT:%.+]], 291 // CK1: [[TT1:%.+]] = load i32*, i32** [[PVT]], 292 // CK1: getelementptr inbounds i32, i32* [[TT1]], i32 1 293 #pragma omp target data map(l[:10]) use_device_ptr(t) 294 { 295 ++l; ++t; 296 } 297 // CK1: call void @__tgt_target_data_end{{.+}}[[MTYPE11]] 298 // CK1: [[TTT:%.+]] = load i32*, i32** [[DECL]], 299 // CK1: getelementptr inbounds i32, i32* [[TTT]], i32 1 300 ++l; ++t; 301 302 // CK1-DAG: [[RVAL:%.+]] = bitcast i32* [[T1:%.+]] to i8* 303 // CK1-DAG: [[T1]] = load i32*, i32** [[T2:%.+]], 304 // CK1-DAG: [[T2]] = load i32**, i32*** [[DECL:%.+]], 305 // CK1: [[BP:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* %{{.+}}, i32 0, i32 0 306 // CK1: store i8* [[RVAL]], i8** [[BP]], 307 // CK1: call void @__tgt_target_data_begin{{.+}}[[MTYPE12]] 308 // CK1: [[CBP:%.+]] = bitcast i8** [[BP]] to i32** 309 // CK1: [[VAL:%.+]] = load i32*, i32** [[CBP]], 310 // CK1: store i32* [[VAL]], i32** [[PVTV:%.+]], 311 // CK1-NOT: store i32** [[PVTV]], i32*** [[DECL]], 312 // CK1: store i32** [[PVTV]], i32*** [[PVT:%.+]], 313 // CK1: [[TT1:%.+]] = load i32**, i32*** [[PVT]], 314 // CK1: [[TT2:%.+]] = load i32*, i32** [[TT1]], 315 // CK1: getelementptr inbounds i32, i32* [[TT2]], i32 1 316 #pragma omp target data map(l[:10]) use_device_ptr(tr) 317 { 318 ++l; ++tr; 319 } 320 // CK1: call void @__tgt_target_data_end{{.+}}[[MTYPE12]] 321 // CK1: [[TTT:%.+]] = load i32**, i32*** [[DECL]], 322 // CK1: [[TTTT:%.+]] = load i32*, i32** [[TTT]], 323 // CK1: getelementptr inbounds i32, i32* [[TTTT]], i32 1 324 ++l; ++tr; 325 326 } 327 328 void bar(float *&a, int *&b) { 329 foo<int>(a,b); 330 } 331 332 #endif 333 ///==========================================================================/// 334 // 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 335 // 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 336 // 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 337 // 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 338 // 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 339 // 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 340 #ifdef CK2 341 342 // CK2: [[ST:%.+]] = type { double*, double** } 343 // CK2: [[MTYPE00:@.+]] = {{.*}}constant [2 x i32] [i32 35, i32 83] 344 // CK2: [[MTYPE01:@.+]] = {{.*}}constant [3 x i32] [i32 32, i32 19, i32 83] 345 // CK2: [[MTYPE02:@.+]] = {{.*}}constant [2 x i32] [i32 96, i32 35] 346 // CK2: [[MTYPE03:@.+]] = {{.*}}constant [4 x i32] [i32 96, i32 32, i32 19, i32 83] 347 348 template <typename T> 349 struct ST { 350 T *a; 351 double *&b; 352 ST(double *&b) : a(0), b(b) {} 353 354 // CK2-LABEL: @{{.*}}foo{{.*}} 355 void foo(double *&arg) { 356 int *la = 0; 357 358 // CK2: [[BP:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* %{{.+}}, i32 0, i32 1 359 // CK2: store i8* [[RVAL:%.+]], i8** [[BP]], 360 // CK2: call void @__tgt_target_data_begin{{.+}}[[MTYPE00]] 361 // CK2: [[CBP:%.+]] = bitcast i8** [[BP]] to double** 362 // CK2: [[VAL:%.+]] = load double*, double** [[CBP]], 363 // CK2: store double* [[VAL]], double** [[PVT:%.+]], 364 // CK2: store double** [[PVT]], double*** [[PVT2:%.+]], 365 // CK2: [[TT1:%.+]] = load double**, double*** [[PVT2]], 366 // CK2: [[TT2:%.+]] = load double*, double** [[TT1]], 367 // CK2: getelementptr inbounds double, double* [[TT2]], i32 1 368 #pragma omp target data map(a[:10]) use_device_ptr(a) 369 { 370 a++; 371 } 372 // CK2: call void @__tgt_target_data_end{{.+}}[[MTYPE00]] 373 // CK2: [[DECL:%.+]] = getelementptr inbounds [[ST]], [[ST]]* %this1, i32 0, i32 0 374 // CK2: [[TTT:%.+]] = load double*, double** [[DECL]], 375 // CK2: getelementptr inbounds double, double* [[TTT]], i32 1 376 a++; 377 378 // CK2: [[BP:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* %{{.+}}, i32 0, i32 2 379 // CK2: store i8* [[RVAL:%.+]], i8** [[BP]], 380 // CK2: call void @__tgt_target_data_begin{{.+}}[[MTYPE01]] 381 // CK2: [[CBP:%.+]] = bitcast i8** [[BP]] to double** 382 // CK2: [[VAL:%.+]] = load double*, double** [[CBP]], 383 // CK2: store double* [[VAL]], double** [[PVT:%.+]], 384 // CK2: store double** [[PVT]], double*** [[PVT2:%.+]], 385 // CK2: [[TT1:%.+]] = load double**, double*** [[PVT2]], 386 // CK2: [[TT2:%.+]] = load double*, double** [[TT1]], 387 // CK2: getelementptr inbounds double, double* [[TT2]], i32 1 388 #pragma omp target data map(b[:10]) use_device_ptr(b) 389 { 390 b++; 391 } 392 // CK2: call void @__tgt_target_data_end{{.+}}[[MTYPE01]] 393 // CK2: [[DECL:%.+]] = getelementptr inbounds [[ST]], [[ST]]* %{{.+}}, i32 0, i32 1 394 // CK2: [[TTT:%.+]] = load double**, double*** [[DECL]], 395 // CK2: [[TTTT:%.+]] = load double*, double** [[TTT]], 396 // CK2: getelementptr inbounds double, double* [[TTTT]], i32 1 397 b++; 398 399 // CK2: [[BP:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* %{{.+}}, i32 0, i32 0 400 // CK2: store i8* [[RVAL:%.+]], i8** [[BP]], 401 // CK2: call void @__tgt_target_data_begin{{.+}}[[MTYPE02]] 402 // CK2: [[CBP:%.+]] = bitcast i8** [[BP]] to double** 403 // CK2: [[VAL:%.+]] = load double*, double** [[CBP]], 404 // CK2: store double* [[VAL]], double** [[PVT:%.+]], 405 // CK2: store double** [[PVT]], double*** [[PVT2:%.+]], 406 // CK2: [[TT1:%.+]] = load double**, double*** [[PVT2]], 407 // CK2: [[TT2:%.+]] = load double*, double** [[TT1]], 408 // CK2: getelementptr inbounds double, double* [[TT2]], i32 1 409 #pragma omp target data map(la[:10]) use_device_ptr(a) 410 { 411 a++; 412 la++; 413 } 414 // CK2: call void @__tgt_target_data_end{{.+}}[[MTYPE02]] 415 // CK2: [[DECL:%.+]] = getelementptr inbounds [[ST]], [[ST]]* %this1, i32 0, i32 0 416 // CK2: [[TTT:%.+]] = load double*, double** [[DECL]], 417 // CK2: getelementptr inbounds double, double* [[TTT]], i32 1 418 a++; 419 la++; 420 421 // CK2: [[BP:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* %{{.+}}, i32 0, i32 0 422 // CK2: store i8* [[RVAL:%.+]], i8** [[BP]], 423 // CK2: [[_BP:%.+]] = getelementptr inbounds [4 x i8*], [4 x i8*]* %{{.+}}, i32 0, i32 3 424 // CK2: store i8* [[_RVAL:%.+]], i8** [[_BP]], 425 // CK2: call void @__tgt_target_data_begin{{.+}}[[MTYPE03]] 426 // CK2: [[CBP:%.+]] = bitcast i8** [[BP]] to double** 427 // CK2: [[VAL:%.+]] = load double*, double** [[CBP]], 428 // CK2: store double* [[VAL]], double** [[PVT:%.+]], 429 // CK2: store double** [[PVT]], double*** [[PVT2:%.+]], 430 // CK2: [[_CBP:%.+]] = bitcast i8** [[_BP]] to double** 431 // CK2: [[_VAL:%.+]] = load double*, double** [[_CBP]], 432 // CK2: store double* [[_VAL]], double** [[_PVT:%.+]], 433 // CK2: store double** [[_PVT]], double*** [[_PVT2:%.+]], 434 // CK2: [[TT1:%.+]] = load double**, double*** [[PVT2]], 435 // CK2: [[TT2:%.+]] = load double*, double** [[TT1]], 436 // CK2: getelementptr inbounds double, double* [[TT2]], i32 1 437 // CK2: [[_TT1:%.+]] = load double**, double*** [[_PVT2]], 438 // CK2: [[_TT2:%.+]] = load double*, double** [[_TT1]], 439 // CK2: getelementptr inbounds double, double* [[_TT2]], i32 1 440 #pragma omp target data map(b[:10]) use_device_ptr(a, b) 441 { 442 a++; 443 b++; 444 } 445 // CK2: call void @__tgt_target_data_end{{.+}}[[MTYPE03]] 446 // CK2: [[DECL:%.+]] = getelementptr inbounds [[ST]], [[ST]]* %this1, i32 0, i32 0 447 // CK2: [[TTT:%.+]] = load double*, double** [[DECL]], 448 // CK2: getelementptr inbounds double, double* [[TTT]], i32 1 449 // CK2: [[_DECL:%.+]] = getelementptr inbounds [[ST]], [[ST]]* %this1, i32 0, i32 1 450 // CK2: [[_TTT:%.+]] = load double**, double*** [[_DECL]], 451 // CK2: [[_TTTT:%.+]] = load double*, double** [[_TTT]], 452 // CK2: getelementptr inbounds double, double* [[_TTTT]], i32 1 453 a++; 454 b++; 455 } 456 }; 457 458 void bar(double *arg){ 459 ST<double> A(arg); 460 A.foo(arg); 461 ++arg; 462 } 463 #endif 464 #endif 465