1 // Test host codegen. 2 // RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64 3 // RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s 4 // RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64 5 // RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32 6 // RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s 7 // RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32 8 9 // Test target codegen - host bc file has to be created first. 10 // RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm-bc %s -o %t-ppc-host.bc 11 // RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s --check-prefix TCHECK --check-prefix TCHECK-64 12 // RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o %t %s 13 // RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix TCHECK --check-prefix TCHECK-64 14 // RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm-bc %s -o %t-x86-host.bc 15 // RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s --check-prefix TCHECK --check-prefix TCHECK-32 16 // RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o %t %s 17 // RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix TCHECK --check-prefix TCHECK-32 18 19 // expected-no-diagnostics 20 #ifndef HEADER 21 #define HEADER 22 23 // CHECK-DAG: %ident_t = type { i32, i32, i32, i32, i8* } 24 // CHECK-DAG: [[STR:@.+]] = private unnamed_addr constant [23 x i8] c";unknown;unknown;0;0;;\00" 25 // CHECK-DAG: [[DEF_LOC:@.+]] = private unnamed_addr constant %ident_t { i32 0, i32 2, i32 0, i32 0, i8* getelementptr inbounds ([23 x i8], [23 x i8]* [[STR]], i32 0, i32 0) } 26 27 // CHECK-DAG: [[S1:%.+]] = type { double } 28 // CHECK-DAG: [[ENTTY:%.+]] = type { i8*, i8*, i[[SZ:32|64]], i32, i32 } 29 // CHECK-DAG: [[DEVTY:%.+]] = type { i8*, i8*, [[ENTTY]]*, [[ENTTY]]* } 30 // CHECK-DAG: [[DSCTY:%.+]] = type { i32, [[DEVTY]]*, [[ENTTY]]*, [[ENTTY]]* } 31 32 // TCHECK: [[ENTTY:%.+]] = type { i8*, i8*, i{{32|64}}, i32, i32 } 33 34 // We have 6 target regions 35 36 // CHECK-DAG: @{{.*}} = private constant i8 0 37 // CHECK-DAG: @{{.*}} = private constant i8 0 38 // CHECK-DAG: @{{.*}} = private constant i8 0 39 // CHECK-DAG: @{{.*}} = private constant i8 0 40 // CHECK-DAG: @{{.*}} = private constant i8 0 41 // CHECK-DAG: @{{.*}} = private constant i8 0 42 43 // TCHECK: @{{.+}} = constant [[ENTTY]] 44 // TCHECK: @{{.+}} = constant [[ENTTY]] 45 // TCHECK: @{{.+}} = constant [[ENTTY]] 46 // TCHECK: @{{.+}} = constant [[ENTTY]] 47 // TCHECK: @{{.+}} = constant [[ENTTY]] 48 // TCHECK: @{{.+}} = constant [[ENTTY]] 49 50 // Check if offloading descriptor is created. 51 // CHECK: [[ENTBEGIN:@.+]] = external constant [[ENTTY]] 52 // CHECK: [[ENTEND:@.+]] = external constant [[ENTTY]] 53 // CHECK: [[DEVBEGIN:@.+]] = external constant i8 54 // CHECK: [[DEVEND:@.+]] = external constant i8 55 // CHECK: [[IMAGES:@.+]] = internal unnamed_addr constant [1 x [[DEVTY]]] [{{.+}} { i8* [[DEVBEGIN]], i8* [[DEVEND]], [[ENTTY]]* [[ENTBEGIN]], [[ENTTY]]* [[ENTEND]] }] 56 // CHECK: [[DESC:@.+]] = internal constant [[DSCTY]] { i32 1, [[DEVTY]]* getelementptr inbounds ([1 x [[DEVTY]]], [1 x [[DEVTY]]]* [[IMAGES]], i32 0, i32 0), [[ENTTY]]* [[ENTBEGIN]], [[ENTTY]]* [[ENTEND]] } 57 58 // Check target registration is registered as a Ctor. 59 // CHECK: appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 0, void ()* bitcast (void (i8*)* [[REGFN:@.+]] to void ()*), i8* null }] 60 61 62 template<typename tx> 63 tx ftemplate(int n) { 64 tx a = 0; 65 66 #pragma omp target parallel if(parallel: 0) 67 { 68 a += 1; 69 } 70 71 short b = 1; 72 #pragma omp target parallel if(parallel: 1) 73 { 74 a += b; 75 } 76 77 return a; 78 } 79 80 static 81 int fstatic(int n) { 82 83 #pragma omp target parallel if(n>1) 84 { 85 } 86 87 #pragma omp target parallel if(target: n-2>2) 88 { 89 } 90 91 return n+1; 92 } 93 94 struct S1 { 95 double a; 96 97 int r1(int n){ 98 int b = 1; 99 100 #pragma omp target parallel if(parallel: n>3) 101 { 102 this->a = (double)b + 1.5; 103 } 104 105 #pragma omp target parallel if(target: n>4) if(parallel: n>5) 106 { 107 this->a = 2.5; 108 } 109 110 return (int)a; 111 } 112 }; 113 114 // CHECK: define {{.*}}@{{.*}}bar{{.*}} 115 int bar(int n){ 116 int a = 0; 117 118 S1 S; 119 // CHECK: call {{.*}}i32 [[FS1:@.+]]([[S1]]* {{.*}}, i32 {{.*}}) 120 a += S.r1(n); 121 122 // CHECK: call {{.*}}i32 [[FSTATIC:@.+]](i32 {{.*}}) 123 a += fstatic(n); 124 125 // CHECK: call {{.*}}i32 [[FTEMPLATE:@.+]](i32 {{.*}}) 126 a += ftemplate<int>(n); 127 128 return a; 129 } 130 131 132 133 // 134 // CHECK: define {{.*}}[[FS1]]([[S1]]* {{%.+}}, i32 {{[^%]*}}[[PARM:%.+]]) 135 // 136 // CHECK-DAG: store i32 [[PARM]], i32* [[N_ADDR:%.+]], align 137 // CHECK: [[NV:%.+]] = load i32, i32* [[N_ADDR]], align 138 // CHECK: [[CMP:%.+]] = icmp sgt i32 [[NV]], 3 139 // CHECK: [[FB:%.+]] = zext i1 [[CMP]] to i8 140 // CHECK: store i8 [[FB]], i8* [[CAPE_ADDR:%.+]], align 141 // CHECK: [[CAPE:%.+]] = load i8, i8* [[CAPE_ADDR]], align 142 // CHECK: [[TB:%.+]] = trunc i8 [[CAPE]] to i1 143 // CHECK: [[CONV:%.+]] = bitcast i[[SZ]]* [[CAPEC_ADDR:%.+]] to i8* 144 // CHECK: [[FB:%.+]] = zext i1 [[TB]] to i8 145 // CHECK: store i8 [[FB]], i8* [[CONV]], align 146 // CHECK: [[ARG:%.+]] = load i[[SZ]], i[[SZ]]* [[CAPEC_ADDR]], align 147 // 148 // CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 3, {{.*}}, i32 1, i32 0) 149 // CHECK: store i32 [[RET]], i32* [[RHV:%.+]], align 150 // CHECK: [[RET2:%.+]] = load i32, i32* [[RHV]], align 151 // CHECK: [[ERROR:%.+]] = icmp ne i32 [[RET2]], 0 152 // CHECK: br i1 [[ERROR]], label %[[FAIL:.+]], label %[[END:[^,]+]] 153 // 154 // CHECK: [[FAIL]] 155 // CHECK: call void [[HVT1:@.+]]([[S1]]* {{%.+}}, i[[SZ]] {{%.+}}, i[[SZ]] [[ARG]]) 156 // CHECK: br label {{%?}}[[END]] 157 // CHECK: [[END]] 158 // 159 // 160 // 161 // CHECK: [[NV:%.+]] = load i32, i32* [[N_ADDR]], align 162 // CHECK: [[CMP:%.+]] = icmp sgt i32 [[NV]], 5 163 // CHECK: [[FB:%.+]] = zext i1 [[CMP]] to i8 164 // CHECK: store i8 [[FB]], i8* [[CAPE_ADDR:%.+]], align 165 // CHECK: [[CAPE:%.+]] = load i8, i8* [[CAPE_ADDR]], align 166 // CHECK: [[TB:%.+]] = trunc i8 [[CAPE]] to i1 167 // CHECK: [[CONV:%.+]] = bitcast i[[SZ]]* [[CAPEC_ADDR:%.+]] to i8* 168 // CHECK: [[FB:%.+]] = zext i1 [[TB]] to i8 169 // CHECK: store i8 [[FB]], i8* [[CONV]], align 170 // CHECK: [[ARG:%.+]] = load i[[SZ]], i[[SZ]]* [[CAPEC_ADDR]], align 171 // CHECK: [[NV:%.+]] = load i32, i32* [[N_ADDR]], align 172 // CHECK: [[CMP:%.+]] = icmp sgt i32 [[NV]], 4 173 // CHECK: br i1 [[CMP]], label {{%?}}[[IF_THEN:.+]], label {{%?}}[[IF_ELSE:.+]] 174 // 175 // CHECK: [[IF_THEN]] 176 // CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 2, {{.*}}, i32 1, i32 0) 177 // CHECK: store i32 [[RET]], i32* [[RHV:%.+]], align 178 // CHECK: br label {{%?}}[[END:.+]] 179 // 180 // CHECK: [[IF_ELSE]] 181 // CHECK: store i32 -1, i32* [[RHV]], align 182 // CHECK: br label {{%?}}[[END]] 183 // 184 // CHECK: [[END]] 185 // CHECK: [[RET2:%.+]] = load i32, i32* [[RHV]], align 186 // CHECK: [[ERROR:%.+]] = icmp ne i32 [[RET2]], 0 187 // CHECK: br i1 [[ERROR]], label %[[FAIL:.+]], label %[[END:[^,]+]] 188 // 189 // CHECK: [[FAIL]] 190 // CHECK: call void [[HVT2:@.+]]([[S1]]* {{%.+}}, i[[SZ]] [[ARG]]) 191 // CHECK: br label {{%?}}[[END]] 192 // CHECK: [[END]] 193 194 195 196 197 198 199 // 200 // CHECK: define {{.*}}[[FSTATIC]](i32 {{[^%]*}}[[PARM:%.+]]) 201 // 202 // CHECK-DAG: store i32 [[PARM]], i32* [[N_ADDR:%.+]], align 203 // CHECK: [[NV:%.+]] = load i32, i32* [[N_ADDR]], align 204 // CHECK: [[CMP:%.+]] = icmp sgt i32 [[NV]], 1 205 // CHECK: [[FB:%.+]] = zext i1 [[CMP]] to i8 206 // CHECK: store i8 [[FB]], i8* [[CAPE_ADDR:%.+]], align 207 // CHECK: [[CAPE:%.+]] = load i8, i8* [[CAPE_ADDR]], align 208 // CHECK: [[TB:%.+]] = trunc i8 [[CAPE]] to i1 209 // CHECK: [[CONV:%.+]] = bitcast i[[SZ]]* [[CAPEC_ADDR:%.+]] to i8* 210 // CHECK: [[FB:%.+]] = zext i1 [[TB]] to i8 211 // CHECK: store i8 [[FB]], i8* [[CONV]], align 212 // CHECK: [[ARG:%.+]] = load i[[SZ]], i[[SZ]]* [[CAPEC_ADDR]], align 213 // CHECK: [[CAPE2:%.+]] = load i8, i8* [[CAPE_ADDR]], align 214 // CHECK: [[TB:%.+]] = trunc i8 [[CAPE2]] to i1 215 // CHECK: br i1 [[TB]], label {{%?}}[[IF_THEN:.+]], label {{%?}}[[IF_ELSE:.+]] 216 // 217 // CHECK: [[IF_THEN]] 218 // CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 1, {{.*}}, i32 1, i32 0) 219 // CHECK: store i32 [[RET]], i32* [[RHV:%.+]], align 220 // CHECK: br label {{%?}}[[END:.+]] 221 // 222 // CHECK: [[IF_ELSE]] 223 // CHECK: store i32 -1, i32* [[RHV]], align 224 // CHECK: br label {{%?}}[[END]] 225 // 226 // CHECK: [[END]] 227 // CHECK: [[RET2:%.+]] = load i32, i32* [[RHV]], align 228 // CHECK: [[ERROR:%.+]] = icmp ne i32 [[RET2]], 0 229 // CHECK: br i1 [[ERROR]], label %[[FAIL:.+]], label %[[END:[^,]+]] 230 // 231 // CHECK: [[FAIL]] 232 // CHECK: call void [[HVT3:@.+]](i[[SZ]] [[ARG]]) 233 // CHECK: br label {{%?}}[[END]] 234 // CHECK: [[END]] 235 // 236 // 237 // 238 // CHECK-DAG: [[NV:%.+]] = load i32, i32* [[N_ADDR]], align 239 // CHECK: [[SUB:%.+]] = sub nsw i32 [[NV]], 2 240 // CHECK: [[CMP:%.+]] = icmp sgt i32 [[SUB]], 2 241 // CHECK: br i1 [[CMP]], label {{%?}}[[IF_THEN:.+]], label {{%?}}[[IF_ELSE:.+]] 242 // 243 // CHECK: [[IF_THEN]] 244 // CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 0, {{.*}}, i32 1, i32 0) 245 // CHECK: store i32 [[RET]], i32* [[RHV:%.+]], align 246 // CHECK: br label {{%?}}[[END:.+]] 247 // 248 // CHECK: [[IF_ELSE]] 249 // CHECK: store i32 -1, i32* [[RHV]], align 250 // CHECK: br label {{%?}}[[END]] 251 // 252 // CHECK: [[END]] 253 // CHECK: [[RET2:%.+]] = load i32, i32* [[RHV]], align 254 // CHECK: [[ERROR:%.+]] = icmp ne i32 [[RET2]], 0 255 // CHECK: br i1 [[ERROR]], label %[[FAIL:.+]], label %[[END:[^,]+]] 256 // 257 // CHECK: [[FAIL]] 258 // CHECK: call void [[HVT4:@.+]]() 259 // CHECK: br label {{%?}}[[END]] 260 // CHECK: [[END]] 261 262 263 264 265 266 267 // 268 // CHECK: define {{.*}}[[FTEMPLATE]] 269 // 270 // CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 1, {{.*}}, i32 1, i32 0) 271 // CHECK-NEXT: store i32 [[RET]], i32* [[RHV:%.+]], align 272 // CHECK-NEXT: [[RET2:%.+]] = load i32, i32* [[RHV]], align 273 // CHECK-NEXT: [[ERROR:%.+]] = icmp ne i32 [[RET2]], 0 274 // CHECK-NEXT: br i1 [[ERROR]], label %[[FAIL:.+]], label %[[END:[^,]+]] 275 // 276 // CHECK: [[FAIL]] 277 // CHECK: call void [[HVT5:@.+]]({{[^,]+}}) 278 // CHECK: br label {{%?}}[[END]] 279 // 280 // CHECK: [[END]] 281 // 282 // 283 // 284 // CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target_teams(i32 -1, i8* @{{[^,]+}}, i32 2, {{.*}}, i32 1, i32 0) 285 // CHECK-NEXT: store i32 [[RET]], i32* [[RHV:%.+]], align 286 // CHECK-NEXT: [[RET2:%.+]] = load i32, i32* [[RHV]], align 287 // CHECK-NEXT: [[ERROR:%.+]] = icmp ne i32 [[RET2]], 0 288 // CHECK-NEXT: br i1 [[ERROR]], label %[[FAIL:.+]], label %[[END:[^,]+]] 289 // 290 // CHECK: [[FAIL]] 291 // CHECK: call void [[HVT6:@.+]]({{[^,]+}}, {{[^,]+}}) 292 // CHECK: br label {{%?}}[[END]] 293 // CHECK: [[END]] 294 295 296 297 298 299 300 // Check that the offloading functions are emitted and that the parallel function 301 // is appropriately guarded. 302 303 // CHECK: define internal void [[HVT1]]([[S1]]* {{%.+}}, i[[SZ]] [[PARM1:%.+]], i[[SZ]] [[PARM2:%.+]]) 304 // CHECK-DAG: store i[[SZ]] [[PARM1]], i[[SZ]]* [[B_ADDR:%.+]], align 305 // CHECK-DAG: store i[[SZ]] [[PARM2]], i[[SZ]]* [[CAPE_ADDR:%.+]], align 306 // CHECK-64: [[CONVB:%.+]] = bitcast i[[SZ]]* [[B_ADDR]] to i32* 307 // CHECK: [[CONV:%.+]] = bitcast i[[SZ]]* [[CAPE_ADDR]] to i8* 308 // CHECK-64: [[BV:%.+]] = load i32, i32* [[CONVB]], align 309 // CHECK-32: [[BV:%.+]] = load i32, i32* [[B_ADDR]], align 310 // CHECK-64: [[BC:%.+]] = bitcast i64* [[ARGA:%.+]] to i32* 311 // CHECK-64: store i32 [[BV]], i32* [[BC]], align 312 // CHECK-64: [[ARG:%.+]] = load i[[SZ]], i[[SZ]]* [[ARGA]], align 313 // CHECK-32: store i32 [[BV]], i32* [[ARGA:%.+]], align 314 // CHECK-32: [[ARG:%.+]] = load i[[SZ]], i[[SZ]]* [[ARGA]], align 315 // CHECK: [[IFC:%.+]] = load i8, i8* [[CONV]], align 316 // CHECK: [[TB:%.+]] = trunc i8 [[IFC]] to i1 317 // CHECK: br i1 [[TB]], label {{%?}}[[IF_THEN:.+]], label {{%?}}[[IF_ELSE:.+]] 318 // 319 // CHECK: [[IF_THEN]] 320 // CHECK: call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%ident_t* [[DEF_LOC]], i32 2, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, [[S1]]*, i[[SZ]])* [[OMP_OUTLINED3:@.+]] to void (i32*, i32*, ...)*), [[S1]]* {{.+}}, i[[SZ]] [[ARG]]) 321 // CHECK: br label {{%?}}[[END:.+]] 322 // 323 // CHECK: [[IF_ELSE]] 324 // CHECK: call void @__kmpc_serialized_parallel( 325 // CHECK: call void [[OMP_OUTLINED3]](i32* {{%.+}}, i32* {{%.+}}, [[S1]]* {{.+}}, i[[SZ]] [[ARG]]) 326 // CHECK: call void @__kmpc_end_serialized_parallel( 327 // CHECK: br label {{%?}}[[END]] 328 // 329 // CHECK: [[END]] 330 // 331 // 332 333 334 // CHECK: define internal void [[HVT2]]([[S1]]* {{%.+}}, i[[SZ]] [[PARM:%.+]]) 335 // CHECK-DAG: store i[[SZ]] [[PARM]], i[[SZ]]* [[CAPE_ADDR:%.+]], align 336 // CHECK: [[CONV:%.+]] = bitcast i[[SZ]]* [[CAPE_ADDR]] to i8* 337 // CHECK: [[IFC:%.+]] = load i8, i8* [[CONV]], align 338 // CHECK: [[TB:%.+]] = trunc i8 [[IFC]] to i1 339 // CHECK: br i1 [[TB]], label {{%?}}[[IF_THEN:.+]], label {{%?}}[[IF_ELSE:.+]] 340 // 341 // CHECK: [[IF_THEN]] 342 // CHECK: call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%ident_t* [[DEF_LOC]], i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, [[S1]]*)* [[OMP_OUTLINED4:@.+]] to void (i32*, i32*, ...)*), [[S1]]* {{.+}}) 343 // CHECK: br label {{%?}}[[END:.+]] 344 // 345 // CHECK: [[IF_ELSE]] 346 // CHECK: call void @__kmpc_serialized_parallel( 347 // CHECK: call void [[OMP_OUTLINED4]](i32* {{%.+}}, i32* {{%.+}}, [[S1]]* {{.+}}) 348 // CHECK: call void @__kmpc_end_serialized_parallel( 349 // CHECK: br label {{%?}}[[END]] 350 // 351 // CHECK: [[END]] 352 // 353 // 354 355 356 357 358 359 360 361 362 // CHECK: define internal void [[HVT3]](i[[SZ]] [[PARM:%.+]]) 363 // CHECK-DAG: store i[[SZ]] [[PARM]], i[[SZ]]* [[CAPE_ADDR:%.+]], align 364 // CHECK: [[CONV:%.+]] = bitcast i[[SZ]]* [[CAPE_ADDR]] to i8* 365 // CHECK: [[IFC:%.+]] = load i8, i8* [[CONV]], align 366 // CHECK: [[TB:%.+]] = trunc i8 [[IFC]] to i1 367 // CHECK: br i1 [[TB]], label {{%?}}[[IF_THEN:.+]], label {{%?}}[[IF_ELSE:.+]] 368 // 369 // CHECK: [[IF_THEN]] 370 // CHECK: call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%ident_t* [[DEF_LOC]], i32 0, void (i32*, i32*, ...)* bitcast (void (i32*, i32*)* [[OMP_OUTLINED1:@.+]] to void (i32*, i32*, ...)*)) 371 // CHECK: br label {{%?}}[[END:.+]] 372 // 373 // CHECK: [[IF_ELSE]] 374 // CHECK: call void @__kmpc_serialized_parallel( 375 // CHECK: call void [[OMP_OUTLINED1]](i32* {{%.+}}, i32* {{%.+}}) 376 // CHECK: call void @__kmpc_end_serialized_parallel( 377 // CHECK: br label {{%?}}[[END]] 378 // 379 // CHECK: [[END]] 380 // 381 // 382 // CHECK: define internal void [[HVT4]]() 383 // CHECK: call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%ident_t* [[DEF_LOC]], i32 0, void (i32*, i32*, ...)* bitcast (void (i32*, i32*)* [[OMP_OUTLINED2:@.+]] to void (i32*, i32*, ...)*)) 384 // CHECK-NEXT: ret 385 // 386 // 387 388 389 390 391 392 // CHECK: define internal void [[HVT5]]( 393 // CHECK-NOT: @__kmpc_fork_call 394 // CHECK: call void @__kmpc_serialized_parallel( 395 // CHECK: call void [[OMP_OUTLINED5:@.+]](i32* {{%.+}}, i32* {{%.+}}, i[[SZ]] {{.+}}) 396 // CHECK: call void @__kmpc_end_serialized_parallel( 397 // CHECK: ret 398 // 399 // 400 401 402 // CHECK: define internal void [[HVT6]]( 403 // CHECK-NOT: call void @__kmpc_serialized_parallel( 404 // CHECK-NOT: call void [[OMP_OUTLINED5:@.+]](i32* {{%.+}}, i32* {{%.+}}, i[[SZ]] {{.+}}) 405 // CHECK-NOT: call void @__kmpc_end_serialized_parallel( 406 // CHECK: call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%ident_t* [[DEF_LOC]], i32 2, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i[[SZ]], i[[SZ]])* [[OMP_OUTLINED5:@.+]] to void (i32*, i32*, ...)*), 407 // CHECK: ret 408 // 409 // 410 411 412 413 #endif 414