1 // Test host codegen. 2 // RUN: %clang_cc1 -verify -fopenmp -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 --check-prefix OMP50 --check-prefix OMP50-64 3 // 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 --check-prefix OMP45 4 // RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s 5 // RUN: %clang_cc1 -fopenmp -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 --check-prefix OMP50 --check-prefix OMP50-64 6 // RUN: %clang_cc1 -verify -fopenmp -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 --check-prefix OMP50 --check-prefix OMP50-32 7 // RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s 8 // RUN: %clang_cc1 -fopenmp -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 --check-prefix OMP50 --check-prefix OMP50-32 9 10 11 // 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 12 // 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 --check-prefix OMP45 13 // 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 --check-prefix OMP45 14 // 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 15 // 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 --check-prefix OMP45 16 17 18 // RUN: %clang_cc1 -verify -fopenmp-simd -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm %s -o - | FileCheck --check-prefix SIMD-ONLY0 %s 19 // RUN: %clang_cc1 -fopenmp-simd -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-pch -o %t %s 20 // RUN: %clang_cc1 -fopenmp-simd -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck --check-prefix SIMD-ONLY0 %s 21 // RUN: %clang_cc1 -verify -fopenmp-simd -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck --check-prefix SIMD-ONLY0 %s 22 // RUN: %clang_cc1 -fopenmp-simd -x c++ -std=c++11 -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-pch -o %t %s 23 // RUN: %clang_cc1 -fopenmp-simd -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck --check-prefix SIMD-ONLY0 %s 24 // SIMD-ONLY0-NOT: {{__kmpc|__tgt}} 25 26 // Test target codegen - host bc file has to be created first. 27 // RUN: %clang_cc1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm-bc %s -o %t-ppc-host.bc 28 // RUN: %clang_cc1 -verify -fopenmp -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 29 // RUN: %clang_cc1 -fopenmp -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 30 // RUN: %clang_cc1 -fopenmp -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 31 // RUN: %clang_cc1 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm-bc %s -o %t-x86-host.bc 32 // RUN: %clang_cc1 -verify -fopenmp -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 33 // RUN: %clang_cc1 -fopenmp -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 34 // RUN: %clang_cc1 -fopenmp -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 35 36 // RUN: %clang_cc1 -verify -fopenmp-simd -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=powerpc64le-ibm-linux-gnu -emit-llvm-bc %s -o %t-ppc-host.bc 37 // RUN: %clang_cc1 -verify -fopenmp-simd -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 --check-prefix SIMD-ONLY1 %s 38 // RUN: %clang_cc1 -fopenmp-simd -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 39 // RUN: %clang_cc1 -fopenmp-simd -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 --check-prefix SIMD-ONLY1 %s 40 // RUN: %clang_cc1 -verify -fopenmp-simd -x c++ -triple i386-unknown-unknown -fopenmp-targets=i386-pc-linux-gnu -emit-llvm-bc %s -o %t-x86-host.bc 41 // RUN: %clang_cc1 -verify -fopenmp-simd -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 --check-prefix SIMD-ONLY1 %s 42 // RUN: %clang_cc1 -fopenmp-simd -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 43 // RUN: %clang_cc1 -fopenmp-simd -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 --check-prefix SIMD-ONLY1 %s 44 // SIMD-ONLY1-NOT: {{__kmpc|__tgt}} 45 46 // expected-no-diagnostics 47 #ifndef HEADER 48 #define HEADER 49 50 // CHECK-DAG: [[TT:%.+]] = type { i64, i8 } 51 // CHECK-DAG: [[ENTTY:%.+]] = type { i8*, i8*, i[[SZ:32|64]], i32, i32 } 52 53 // TCHECK: [[ENTTY:%.+]] = type { i8*, i8*, i{{32|64}}, i32, i32 } 54 55 // OMP45-DAG: [[SIZET:@.+]] = private unnamed_addr constant [2 x i64] [i64 0, i64 4] 56 // OMP45-DAG: [[MAPT:@.+]] = private unnamed_addr constant [2 x i64] [i64 544, i64 800] 57 // OMP45-DAG: @{{.*}} = weak constant i8 0 58 59 // OMP50-DAG: [[SIZET:@.+]] = private unnamed_addr constant [3 x i64] [i64 0, i64 4, i64 1] 60 // OMP50-DAG: [[MAPT:@.+]] = private unnamed_addr constant [3 x i64] [i64 544, i64 800, i64 800] 61 // OMP50-DAG: @{{.*}} = weak constant i8 0 62 63 64 // TCHECK: @{{.+}} = weak constant [[ENTTY]] 65 // TCHECK: @{{.+}} = {{.*}}constant [[ENTTY]] 66 // TCHECK-NOT: @{{.+}} = weak constant [[ENTTY]] 67 68 // Check target registration is registered as a Ctor. 69 // CHECK: appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 0, void ()* @.omp_offloading.requires_reg, i8* null }] 70 71 72 template<typename tx, typename ty> 73 struct TT{ 74 tx X; 75 ty Y; 76 }; 77 78 int global; 79 extern int global; 80 81 // CHECK: define {{.*}}[[FOO:@.+]]( 82 int foo(int n) { 83 int a = 0; 84 short aa = 0; 85 float b[10]; 86 float bn[n]; 87 double c[5][10]; 88 double cn[5][n]; 89 TT<long long, char> d; 90 static long *plocal; 91 92 // CHECK: [[ADD:%.+]] = add nsw i32 93 // CHECK: store i32 [[ADD]], i32* [[DEVICE_CAP:%.+]], 94 // CHECK: [[GEP:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i32 0, i32 0 95 // CHECK: [[DEV:%.+]] = load i32, i32* [[DEVICE_CAP]], 96 // CHECK: store i32 [[DEV]], i32* [[GEP]], 97 // CHECK: [[TASK:%.+]] = call i8* @__kmpc_omp_task_alloc(%struct.ident_t* [[ID:@.+]], i32 [[GTID:%.+]], i32 1, i[[SZ]] {{20|40}}, i[[SZ]] 4, i32 (i32, i8*)* bitcast (i32 (i32, %{{.+}}*)* [[TASK_ENTRY0:@.+]] to i32 (i32, i8*)*)) 98 // CHECK: [[BC_TASK:%.+]] = bitcast i8* [[TASK]] to [[TASK_TY0:%.+]]* 99 // CHECK: getelementptr %struct.kmp_depend_info, %struct.kmp_depend_info* %{{.+}}, i[[SZ]] 0 100 // CHECK: getelementptr %struct.kmp_depend_info, %struct.kmp_depend_info* %{{.+}}, i[[SZ]] 1 101 // CHECK: getelementptr %struct.kmp_depend_info, %struct.kmp_depend_info* %{{.+}}, i[[SZ]] 2 102 // CHECK: getelementptr %struct.kmp_depend_info, %struct.kmp_depend_info* %{{.+}}, i[[SZ]] 3 103 // CHECK: [[DEP:%.+]] = bitcast %struct.kmp_depend_info* %{{.+}} to i8* 104 // CHECK: call void @__kmpc_omp_wait_deps(%struct.ident_t* [[ID]], i32 [[GTID]], i32 4, i8* [[DEP]], i32 0, i8* null) 105 // CHECK: call void @__kmpc_omp_task_begin_if0(%struct.ident_t* [[ID]], i32 [[GTID]], i8* [[TASK]]) 106 // CHECK: call i32 [[TASK_ENTRY0]](i32 [[GTID]], [[TASK_TY0]]* [[BC_TASK]]) 107 // CHECK: call void @__kmpc_omp_task_complete_if0(%struct.ident_t* [[ID]], i32 [[GTID]], i8* [[TASK]]) 108 #pragma omp target teams distribute simd device(global + a) depend(in: global) depend(out: a, b, cn[4]) 109 for (int i = 0; i < 10; ++i) { 110 } 111 112 // CHECK: [[ADD:%.+]] = add nsw i32 113 // CHECK: store i32 [[ADD]], i32* [[DEVICE_CAP:%.+]], 114 115 // OMP45: [[BOOL:%.+]] = icmp ne i32 %{{.+}}, 0 116 // OMP45: br i1 [[BOOL]], label %[[THEN:.+]], label %[[ELSE:.+]] 117 // OMP50: br i1 {{.+}}, label %[[THEN:.+]], label %[[ELSE:.+]] 118 // CHECK: [[THEN]]: 119 // OMP45-DAG: [[BPADDR0:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[BP:%.+]], i32 0, i32 0 120 // OMP45-DAG: [[PADDR0:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[P:%.+]], i32 0, i32 0 121 // OMP50-DAG: [[BPADDR0:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[BP:%.+]], i32 0, i32 0 122 // OMP50-DAG: [[PADDR0:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[P:%.+]], i32 0, i32 0 123 // CHECK-DAG: [[CBPADDR0:%.+]] = bitcast i8** [[BPADDR0]] to i[[SZ]]** 124 // CHECK-DAG: [[CPADDR0:%.+]] = bitcast i8** [[PADDR0]] to i[[SZ]]** 125 // CHECK-DAG: store i[[SZ]]* [[BP0:%[^,]+]], i[[SZ]]** [[CBPADDR0]] 126 // CHECK-DAG: store i[[SZ]]* [[BP0]], i[[SZ]]** [[CPADDR0]] 127 128 // OMP45-DAG: [[BPADDR1:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[BP]], i32 0, i32 1 129 // OMP45-DAG: [[PADDR1:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[P]], i32 0, i32 1 130 131 // OMP50-DAG: [[BPADDR1:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[BP]], i32 0, i32 1 132 // OMP50-DAG: [[PADDR1:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[P]], i32 0, i32 1 133 // CHECK-DAG: [[CBPADDR1:%.+]] = bitcast i8** [[BPADDR1]] to i[[SZ]]* 134 // CHECK-DAG: [[CPADDR1:%.+]] = bitcast i8** [[PADDR1]] to i[[SZ]]* 135 // CHECK-DAG: store i[[SZ]] [[BP1:%[^,]+]], i[[SZ]]* [[CBPADDR1]] 136 // CHECK-DAG: store i[[SZ]] [[BP1]], i[[SZ]]* [[CPADDR1]] 137 138 // OMP50-DAG: [[BPADDR2:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[BP]], i32 0, i32 2 139 // OMP50-DAG: [[PADDR2:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[P]], i32 0, i32 2 140 // OMP50-DAG: [[CBPADDR2:%.+]] = bitcast i8** [[BPADDR2]] to i[[SZ]]* 141 // OMP50-DAG: [[CPADDR2:%.+]] = bitcast i8** [[PADDR2]] to i[[SZ]]* 142 // OMP50-DAG: store i[[SZ]] [[BP2:%[^,]+]], i[[SZ]]* [[CBPADDR2]] 143 // OMP50-DAG: store i[[SZ]] [[BP2]], i[[SZ]]* [[CPADDR2]] 144 145 146 // OMP45-DAG: getelementptr inbounds [2 x i8*], [2 x i8*]* [[BP]], i32 0, i32 0 147 // OMP45-DAG: getelementptr inbounds [2 x i8*], [2 x i8*]* [[P]], i32 0, i32 0 148 // OMP50-DAG: getelementptr inbounds [3 x i8*], [3 x i8*]* [[BP]], i32 0, i32 0 149 // OMP50-DAG: getelementptr inbounds [3 x i8*], [3 x i8*]* [[P]], i32 0, i32 0 150 151 // OMP45: [[GEP:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i32 0, i32 2 152 // OMP50-64: [[GEP:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i32 0, i32 4 153 // OMP50-32: [[GEP:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i32 0, i32 3 154 // CHECK: [[DEV:%.+]] = load i32, i32* [[DEVICE_CAP]], 155 // CHECK: store i32 [[DEV]], i32* [[GEP]], 156 // CHECK: [[DEV1:%.+]] = load i32, i32* [[DEVICE_CAP]], 157 // CHECK: [[DEV2:%.+]] = sext i32 [[DEV1]] to i64 158 159 // OMP45: [[TASK:%.+]] = call i8* @__kmpc_omp_target_task_alloc(%struct.ident_t* [[ID]], i32 [[GTID]], i32 1, i[[SZ]] {{104|60}}, i[[SZ]] {{16|12}}, i32 (i32, i8*)* bitcast (i32 (i32, %{{.+}}*)* [[TASK_ENTRY1_:@.+]] to i32 (i32, i8*)*), i64 [[DEV2]]) 160 // OMP50: [[TASK:%.+]] = call i8* @__kmpc_omp_target_task_alloc(%struct.ident_t* [[ID]], i32 [[GTID]], i32 1, i[[SZ]] {{28|128|76}}, i[[SZ]] {{16|12|24}}, i32 (i32, i8*)* bitcast (i32 (i32, %{{.+}}*)* [[TASK_ENTRY1_:@.+]] to i32 (i32, i8*)*), i64 [[DEV2]]) 161 // CHECK: [[BC_TASK:%.+]] = bitcast i8* [[TASK]] to [[TASK_TY1_:%.+]]* 162 // CHECK: getelementptr %struct.kmp_depend_info, %struct.kmp_depend_info* %{{.+}}, i[[SZ]] 0 163 // CHECK: getelementptr %struct.kmp_depend_info, %struct.kmp_depend_info* %{{.+}}, i[[SZ]] 1 164 // CHECK: getelementptr %struct.kmp_depend_info, %struct.kmp_depend_info* %{{.+}}, i[[SZ]] 2 165 // CHECK: [[DEP:%.+]] = bitcast %struct.kmp_depend_info* %{{.+}} to i8* 166 // CHECK: call i32 @__kmpc_omp_task_with_deps(%struct.ident_t* [[ID]], i32 [[GTID]], i8* [[TASK]], i32 3, i8* [[DEP]], i32 0, i8* null) 167 // CHECK: br label %[[EXIT:.+]] 168 169 // CHECK: [[ELSE]]: 170 // OMP45-NOT: getelementptr inbounds [2 x i8*], [2 x i8*]* 171 // OMP50-NOT: getelementptr inbounds [3 x i8*], [3 x i8*]* 172 // OMP45: [[GEP:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i32 0, i32 2 173 // OMP50-64: [[GEP:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i32 0, i32 4 174 // OMP50-32: [[GEP:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i32 0, i32 3 175 // CHECK: [[DEV:%.+]] = load i32, i32* [[DEVICE_CAP]], 176 // CHECK: store i32 [[DEV]], i32* [[GEP]], 177 // CHECK: [[DEV1:%.+]] = load i32, i32* [[DEVICE_CAP]], 178 // CHECK: [[DEV2:%.+]] = sext i32 [[DEV1]] to i64 179 180 // OMP45: [[TASK:%.+]] = call i8* @__kmpc_omp_target_task_alloc(%struct.ident_t* [[ID]], i32 [[GTID]], i32 1, i[[SZ]] {{56|28}}, i[[SZ]] {{16|12}}, i32 (i32, i8*)* bitcast (i32 (i32, %{{.+}}*)* [[TASK_ENTRY1__:@.+]] to i32 (i32, i8*)*), i64 [[DEV2]]) 181 // OMP50: [[TASK:%.+]] = call i8* @__kmpc_omp_target_task_alloc(%struct.ident_t* [[ID]], i32 [[GTID]], i32 1, i[[SZ]] {{56|28}}, i[[SZ]] {{16|12|24}}, i32 (i32, i8*)* bitcast (i32 (i32, %{{.+}}*)* [[TASK_ENTRY1__:@.+]] to i32 (i32, i8*)*), i64 [[DEV2]]) 182 // CHECK: [[BC_TASK:%.+]] = bitcast i8* [[TASK]] to [[TASK_TY1__:%.+]]* 183 // CHECK: getelementptr %struct.kmp_depend_info, %struct.kmp_depend_info* %{{.+}}, i[[SZ]] 0 184 // CHECK: getelementptr %struct.kmp_depend_info, %struct.kmp_depend_info* %{{.+}}, i[[SZ]] 1 185 // CHECK: getelementptr %struct.kmp_depend_info, %struct.kmp_depend_info* %{{.+}}, i[[SZ]] 2 186 // CHECK: [[DEP:%.+]] = bitcast %struct.kmp_depend_info* %{{.+}} to i8* 187 // CHECK: call i32 @__kmpc_omp_task_with_deps(%struct.ident_t* [[ID]], i32 [[GTID]], i8* [[TASK]], i32 3, i8* [[DEP]], i32 0, i8* null) 188 // CHECK: br label %[[EXIT:.+]] 189 // CHECK: [[EXIT]]: 190 191 #pragma omp target teams distribute simd device(global + a) nowait depend(inout: global, a, bn) if(a) 192 for (int i = 0; i < *plocal; ++i) { 193 static int local1; 194 *plocal = global; 195 local1 = global; 196 } 197 198 // CHECK: [[TASK:%.+]] = call i8* @__kmpc_omp_task_alloc(%struct.ident_t* [[ID]], i32 [[GTID]], i32 1, i[[SZ]] {{48|24}}, i[[SZ]] 4, i32 (i32, i8*)* bitcast (i32 (i32, %{{.+}}*)* [[TASK_ENTRY2:@.+]] to i32 (i32, i8*)*)) 199 // CHECK: [[BC_TASK:%.+]] = bitcast i8* [[TASK]] to [[TASK_TY2:%.+]]* 200 // CHECK: getelementptr %struct.kmp_depend_info, %struct.kmp_depend_info* %{{.+}}, i[[SZ]] 0 201 // CHECK: [[DEP:%.+]] = bitcast %struct.kmp_depend_info* %{{.+}} to i8* 202 // CHECK: call void @__kmpc_omp_wait_deps(%struct.ident_t* [[ID]], i32 [[GTID]], i32 1, i8* [[DEP]], i32 0, i8* null) 203 // CHECK: call void @__kmpc_omp_task_begin_if0(%struct.ident_t* [[ID]], i32 [[GTID]], i8* [[TASK]]) 204 // CHECK: call i32 [[TASK_ENTRY2]](i32 [[GTID]], [[TASK_TY2]]* [[BC_TASK]]) 205 // CHECK: call void @__kmpc_omp_task_complete_if0(%struct.ident_t* [[ID]], i32 [[GTID]], i8* [[TASK]]) 206 #pragma omp target teams distribute simd if(0) firstprivate(global) depend(out:global) 207 for (int i = 0; i < global; ++i) { 208 global += 1; 209 } 210 211 return a; 212 } 213 214 // Check that the offloading functions are emitted and that the arguments are 215 // correct and loaded correctly for the target regions in foo(). 216 217 // CHECK: define internal void [[HVT0:@.+]]() 218 219 // CHECK: define internal{{.*}} i32 [[TASK_ENTRY0]](i32{{.*}}, [[TASK_TY0]]* noalias noundef %1) 220 // CHECK: store void (i8*, ...)* null, void (i8*, ...)** % 221 // CHECK: [[DEVICE_CAP:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i32 0, i32 0 222 // CHECK: [[DEV:%.+]] = load i32, i32* [[DEVICE_CAP]], 223 // CHECK: [[DEVICE:%.+]] = sext i32 [[DEV]] to i64 224 // CHECK: [[RET:%.+]] = call i32 @__tgt_target_teams_mapper(%struct.ident_t* @{{.+}}, i64 [[DEVICE]], i8* @{{[^,]+}}, i32 0, i8** null, i8** null, i64* null, i64* null, i8** null, i8** null, i32 0, i32 1) 225 // CHECK-NEXT: [[ERROR:%.+]] = icmp ne i32 [[RET]], 0 226 // CHECK-NEXT: br i1 [[ERROR]], label %[[FAIL:[^,]+]], label %[[END:[^,]+]] 227 // CHECK: [[FAIL]] 228 // CHECK: call void [[HVT0]]() 229 // CHECK-NEXT: br label %[[END]] 230 // CHECK: [[END]] 231 // CHECK: ret i32 0 232 233 // CHECK: define internal void [[HVT1:@.+]](i[[SZ]]* noundef %{{.+}}, i[[SZ]] noundef %{{.+}}) 234 235 // CHECK: define internal{{.*}} i32 [[TASK_ENTRY1_]](i32{{.*}}, [[TASK_TY1_]]* noalias noundef %1) 236 // CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* {{%.*}} to void (i8*, 237 // CHECK: call void [[FN]]( 238 // OMP45: [[SZT:%.+]] = getelementptr inbounds [2 x i64], [2 x i64]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 0 239 // OMP50: [[SZT:%.+]] = getelementptr inbounds [3 x i64], [3 x i64]* %{{.+}}, i[[SZ]] 0, i[[SZ]] 0 240 // OMP45: [[DEVICE_CAP:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i32 0, i32 2 241 // OMP50-64: [[DEVICE_CAP:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i32 0, i32 4 242 // OMP50-32: [[DEVICE_CAP:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i32 0, i32 3 243 // CHECK: [[DEV:%.+]] = load i32, i32* [[DEVICE_CAP]], 244 // CHECK: [[DEVICE:%.+]] = sext i32 [[DEV]] to i64 245 // OMP45: [[RET:%.+]] = call i32 @__tgt_target_teams_nowait_mapper(%struct.ident_t* @{{.+}}, i64 [[DEVICE]], i8* @{{[^,]+}}, i32 2, i8** [[BPR:%[^,]+]], i8** [[PR:%[^,]+]], i64* [[SZT]], i64* getelementptr inbounds ([2 x i64], [2 x i64]* [[MAPT]], i32 0, i32 0), i8** null, i8** null, i32 0, i32 1, i32 0, i8* null, i32 0, i8* null) 246 // OMP50: [[RET:%.+]] = call i32 @__tgt_target_teams_nowait_mapper(%struct.ident_t* @{{.+}}, i64 [[DEVICE]], i8* @{{[^,]+}}, i32 3, i8** [[BPR:%[^,]+]], i8** [[PR:%[^,]+]], i64* [[SZT]], i64* getelementptr inbounds ([3 x i64], [3 x i64]* [[MAPT]], i32 0, i32 0), i8** null, i8** null, i32 0, i32 1, i32 0, i8* null, i32 0, i8* null) 247 248 // CHECK: [[ERROR:%.+]] = icmp ne i32 [[RET]], 0 249 // CHECK-NEXT: br i1 [[ERROR]], label %[[FAIL:[^,]+]], label %[[END:[^,]+]] 250 // CHECK: [[FAIL]] 251 // CHECK: [[BP0:%.+]] = load i[[SZ]]*, i[[SZ]]** % 252 // CHECK: [[BP1_I32:%.+]] = load i32, i32* @ 253 // CHECK-64: [[BP1_CAST:%.+]] = bitcast i[[SZ]]* [[BP1_PTR:%.+]] to i32* 254 // CHECK-64: store i32 [[BP1_I32]], i32* [[BP1_CAST]], 255 // CHECK-32: store i32 [[BP1_I32]], i32* [[BP1_PTR:%.+]], 256 // CHECK: [[BP1:%.+]] = load i[[SZ]], i[[SZ]]* [[BP1_PTR]], 257 // OMP45: call void [[HVT1]](i[[SZ]]* [[BP0]], i[[SZ]] [[BP1]]) 258 259 // OMP50: [[BP2:%.+]] = load i[[SZ]], i[[SZ]]* 260 // OMP50: call void [[HVT1]](i[[SZ]]* [[BP0]], i[[SZ]] [[BP1]], i[[SZ]] [[BP2]]) 261 // CHECK-NEXT: br label %[[END]] 262 // CHECK: [[END]] 263 // CHECK: ret i32 0 264 265 // CHECK: define internal{{.*}} i32 [[TASK_ENTRY1__]](i32{{.*}}, [[TASK_TY1__]]* noalias noundef %1) 266 // CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* {{%.*}} to void (i8*, 267 // CHECK: call void [[FN]]( 268 // CHECK: [[DEVICE_CAP:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i32 0, i32 2 269 // CHECK: [[BP0:%.+]] = load i[[SZ]]*, i[[SZ]]** % 270 // CHECK: [[BP1_I32:%.+]] = load i32, i32* @ 271 // CHECK-64: [[BP1_CAST:%.+]] = bitcast i[[SZ]]* [[BP1_PTR:%.+]] to i32* 272 // CHECK-64: store i32 [[BP1_I32]], i32* [[BP1_CAST]], 273 // CHECK-32: store i32 [[BP1_I32]], i32* [[BP1_PTR:%.+]], 274 // CHECK: [[BP1:%.+]] = load i[[SZ]], i[[SZ]]* [[BP1_PTR]], 275 // OMP50: [[BP2:%.+]] = load i[[SZ]], i[[SZ]]* 276 // OMP45: call void [[HVT1]](i[[SZ]]* [[BP0]], i[[SZ]] [[BP1]]) 277 // OMP50: call void [[HVT1]](i[[SZ]]* [[BP0]], i[[SZ]] [[BP1]], i[[SZ]] [[BP2]]) 278 279 // CHECK: ret i32 0 280 281 // CHECK: define internal void [[HVT2:@.+]](i[[SZ]] noundef %{{.+}}) 282 // Create stack storage and store argument in there. 283 // CHECK: [[AA_ADDR:%.+]] = alloca i[[SZ]], align 284 // CHECK: store i[[SZ]] %{{.+}}, i[[SZ]]* [[AA_ADDR]], align 285 // CHECK-64: [[AA_CADDR:%.+]] = bitcast i[[SZ]]* [[AA_ADDR]] to i32* 286 // CHECK-64: load i32, i32* [[AA_CADDR]], align 287 // CHECK-32: load i32, i32* [[AA_ADDR]], align 288 289 // CHECK: define internal{{.*}} i32 [[TASK_ENTRY2]](i32{{.*}}, [[TASK_TY2]]* noalias noundef %1) 290 // CHECK: [[FN:%.+]] = bitcast void (i8*, ...)* {{%.*}} to void (i8*, 291 // CHECK: call void [[FN]]( 292 // CHECK: [[BP1_I32:%.+]] = load i32, i32* % 293 // CHECK-64: [[BP1_CAST:%.+]] = bitcast i[[SZ]]* [[BP1_PTR:%.+]] to i32* 294 // CHECK-64: store i32 [[BP1_I32]], i32* [[BP1_CAST]], 295 // CHECK-32: store i32 [[BP1_I32]], i32* [[BP1_PTR:%.+]], 296 // CHECK: [[BP1:%.+]] = load i[[SZ]], i[[SZ]]* [[BP1_PTR]], 297 // CHECK: call void [[HVT2]](i[[SZ]] [[BP1]]) 298 // CHECK: ret i32 0 299 300 301 #endif 302