1 // RUN: %clang_cc1 -verify -fopenmp -x c++ -triple i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-32 2 // RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple i386-pc-linux-gnu -emit-pch -o %t %s 3 // RUN: %clang_cc1 -fopenmp -x c++ -triple i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-32 4 // RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -DLAMBDA -triple i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck -check-prefix=LAMBDA -check-prefix=LAMBDA-32 %s 5 // RUN: %clang_cc1 -verify -fopenmp -x c++ -fblocks -DBLOCKS -triple i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck -check-prefix=BLOCKS -check-prefix=BLOCKS-32 %s 6 7 // RUN: %clang_cc1 -verify -fopenmp-simd -x c++ -triple i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck --check-prefix SIMD-ONLY0 %s 8 // RUN: %clang_cc1 -fopenmp-simd -x c++ -std=c++11 -triple i386-pc-linux-gnu -emit-pch -o %t %s 9 // RUN: %clang_cc1 -fopenmp-simd -x c++ -triple i386-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck --check-prefix SIMD-ONLY0 %s 10 // RUN: %clang_cc1 -verify -fopenmp-simd -x c++ -std=c++11 -DLAMBDA -triple i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck --check-prefix SIMD-ONLY0 %s 11 // RUN: %clang_cc1 -verify -fopenmp-simd -x c++ -fblocks -DBLOCKS -triple i386-pc-linux-gnu -emit-llvm %s -o - | FileCheck --check-prefix SIMD-ONLY0 %s 12 // SIMD-ONLY0-NOT: {{__kmpc|__tgt}} 13 14 // RUN: %clang_cc1 -verify -fopenmp -x c++ -triple x86_64-pc-linux-gnu -emit-llvm %s -o - | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-64 15 // RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple x86_64-pc-linux-gnu -emit-pch -o %t %s 16 // RUN: %clang_cc1 -fopenmp -x c++ -triple x86_64-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-64 17 // RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -DLAMBDA -triple x86_64-pc-linux-gnu -emit-llvm %s -o - | FileCheck -check-prefix=LAMBDA -check-prefix=LAMBDA-64 %s 18 // RUN: %clang_cc1 -verify -fopenmp -x c++ -fblocks -DBLOCKS -triple x86_64-pc-linux-gnu -emit-llvm %s -o - | FileCheck -check-prefix=BLOCKS -check-prefix=BLOCKS-64 %s 19 20 // RUN: %clang_cc1 -verify -fopenmp-simd -x c++ -triple x86_64-pc-linux-gnu -emit-llvm %s -o - | FileCheck --check-prefix SIMD-ONLY1 %s 21 // RUN: %clang_cc1 -fopenmp-simd -x c++ -std=c++11 -triple x86_64-pc-linux-gnu -emit-pch -o %t %s 22 // RUN: %clang_cc1 -fopenmp-simd -x c++ -triple x86_64-pc-linux-gnu -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck --check-prefix SIMD-ONLY1 %s 23 // RUN: %clang_cc1 -verify -fopenmp-simd -x c++ -std=c++11 -DLAMBDA -triple x86_64-pc-linux-gnu -emit-llvm %s -o - | FileCheck --check-prefix SIMD-ONLY1 %s 24 // RUN: %clang_cc1 -verify -fopenmp-simd -x c++ -fblocks -DBLOCKS -triple x86_64-pc-linux-gnu -emit-llvm %s -o - | FileCheck --check-prefix SIMD-ONLY1 %s 25 // SIMD-ONLY1-NOT: {{__kmpc|__tgt}} 26 27 // RUN: %clang_cc1 -verify -fopenmp -x c++ -std=c++11 -DARRAY -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck -check-prefix=ARRAY %s 28 29 // RUN: %clang_cc1 -verify -fopenmp-simd -x c++ -std=c++11 -DARRAY -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck --check-prefix SIMD-ONLY2 %s 30 // SIMD-ONLY2-NOT: {{__kmpc|__tgt}} 31 // expected-no-diagnostics 32 #ifndef ARRAY 33 #ifndef HEADER 34 #define HEADER 35 36 enum omp_allocator_handle_t { 37 omp_null_allocator = 0, 38 omp_default_mem_alloc = 1, 39 omp_large_cap_mem_alloc = 2, 40 omp_const_mem_alloc = 3, 41 omp_high_bw_mem_alloc = 4, 42 omp_low_lat_mem_alloc = 5, 43 omp_cgroup_mem_alloc = 6, 44 omp_pteam_mem_alloc = 7, 45 omp_thread_mem_alloc = 8, 46 KMP_ALLOCATOR_MAX_HANDLE = __UINTPTR_MAX__ 47 }; 48 49 struct St { 50 int a, b; 51 St() : a(0), b(0) {} 52 St(const St &st) : a(st.a + st.b), b(0) {} 53 ~St() {} 54 }; 55 56 volatile int g __attribute__((aligned(128))) = 1212; 57 58 struct SS { 59 int a; 60 int b : 4; 61 int &c; 62 int e[4]; 63 SS(int &d) : a(0), b(0), c(d) { 64 #pragma omp parallel firstprivate(a, b, c, e) 65 #ifdef LAMBDA 66 [&]() { 67 ++this->a, --b, (this)->c /= 1; 68 #pragma omp parallel firstprivate(a, b, c) 69 ++(this)->a, --b, this->c /= 1; 70 }(); 71 #elif defined(BLOCKS) 72 ^{ 73 ++a; 74 --this->b; 75 (this)->c /= 1; 76 #pragma omp parallel firstprivate(a, b, c) 77 ++(this)->a, --b, this->c /= 1; 78 }(); 79 #else 80 ++this->a, --b, c /= 1, e[2] = 1111; 81 #endif 82 } 83 }; 84 85 template<typename T> 86 struct SST { 87 T a; 88 SST() : a(T()) { 89 #pragma omp parallel firstprivate(a) 90 #ifdef LAMBDA 91 [&]() { 92 [&]() { 93 ++this->a; 94 #pragma omp parallel firstprivate(a) 95 ++(this)->a; 96 }(); 97 }(); 98 #elif defined(BLOCKS) 99 ^{ 100 ^{ 101 ++a; 102 #pragma omp parallel firstprivate(a) 103 ++(this)->a; 104 }(); 105 }(); 106 #else 107 ++(this)->a; 108 #endif 109 } 110 }; 111 112 template <class T> 113 struct S { 114 T f; 115 S(T a) : f(a + g) {} 116 S() : f(g) {} 117 S(const S &s, St t = St()) : f(s.f + t.a) {} 118 operator T() { return T(); } 119 ~S() {} 120 }; 121 122 // CHECK: [[SS_TY:%.+]] = type { i{{[0-9]+}}, i8 123 // LAMBDA: [[SS_TY:%.+]] = type { i{{[0-9]+}}, i8 124 // BLOCKS: [[SS_TY:%.+]] = type { i{{[0-9]+}}, i8 125 // CHECK-DAG: [[S_FLOAT_TY:%.+]] = type { float } 126 // CHECK-DAG: [[S_INT_TY:%.+]] = type { i{{[0-9]+}} } 127 // CHECK-DAG: [[ST_TY:%.+]] = type { i{{[0-9]+}}, i{{[0-9]+}} } 128 129 template <typename T> 130 T tmain() { 131 S<T> test; 132 SST<T> sst; 133 T t_var __attribute__((aligned(128))) = T(); 134 T vec[] __attribute__((aligned(128))) = {1, 2}; 135 S<T> s_arr[] __attribute__((aligned(128))) = {1, 2}; 136 S<T> var __attribute__((aligned(128))) (3); 137 #pragma omp parallel firstprivate(t_var, vec, s_arr, var) 138 { 139 vec[0] = t_var; 140 s_arr[0] = var; 141 } 142 #pragma omp parallel firstprivate(t_var) 143 {} 144 return T(); 145 } 146 147 int main() { 148 static int sivar; 149 SS ss(sivar); 150 #ifdef LAMBDA 151 // LAMBDA: [[G:@.+]] = global i{{[0-9]+}} 1212, 152 // LAMBDA-LABEL: @main 153 // LAMBDA: alloca [[SS_TY]], 154 // LAMBDA: alloca [[CAP_TY:%.+]], 155 // LAMBDA: call{{.*}} void [[OUTER_LAMBDA:@[^(]+]]([[CAP_TY]]* 156 [&]() { 157 // LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]]( 158 // LAMBDA: call {{.*}}void {{.+}} @__kmpc_fork_call({{.+}}, i32 2, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i32* [[G]], {{.+}}) 159 #pragma omp parallel firstprivate(g, sivar) 160 { 161 // LAMBDA: define {{.+}} @{{.+}}([[SS_TY]]* 162 // LAMBDA: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 0 163 // LAMBDA: store i{{[0-9]+}} 0, i{{[0-9]+}}* % 164 // LAMBDA: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 1 165 // LAMBDA: store i8 166 // LAMBDA: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 2 167 // LAMBDA: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 0 168 // LAMBDA: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 1 169 // LAMBDA: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 2 170 // LAMBDA: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 5, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [[SS_TY]]*, [[iz:i64|i32]], {{i64|i32}}, {{i64|i32}}, [4 x i{{[0-9]+}}]*)* [[SS_MICROTASK:@.+]] to void 171 // LAMBDA: ret 172 173 // LAMBDA: define internal void [[SS_MICROTASK]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [[SS_TY]]* %{{.+}}, [[iz]] {{.+}}, [[iz]] {{.+}}, [[iz]] {{.+}}, [4 x i{{[0-9]+}}]* {{.+}}) 174 // LAMBDA-NOT: getelementptr {{.*}}[[SS_TY]], [[SS_TY]]* % 175 // LAMBDA: call{{.*}} void 176 // LAMBDA: ret void 177 178 // LAMBDA: define internal void @{{.+}}(i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [[SS_TY]]* %{{.+}}, [[iz]] {{.+}}, [[iz]] {{.+}}, [[iz]] {{.+}}) 179 // LAMBDA: [[A_PRIV:%.+]] = alloca i{{[0-9]+}}, 180 // LAMBDA: [[B_PRIV:%.+]] = alloca i{{[0-9]+}}, 181 // LAMBDA: [[C_PRIV:%.+]] = alloca i{{[0-9]+}}, 182 // LAMBDA-64: [[A_CONV:%.+]] = bitcast i64* [[A_PRIV]] to i32* 183 // LAMBDA-64: [[B_CONV:%.+]] = bitcast i64* [[B_PRIV]] to i32* 184 // LAMBDA-64: [[C_CONV:%.+]] = bitcast i64* [[C_PRIV]] to i32* 185 // LAMBDA-64: store i32* [[A_CONV]], i32** [[REFA:%.+]], 186 // LAMBDA-32: store i32* [[A_PRIV]], i32** [[REFA:%.+]], 187 // LAMBDA-64: store i32* [[C_CONV]], i32** [[REFC:%.+]], 188 // LAMBDA-32: store i32* [[C_PRIV]], i32** [[REFC:%.+]], 189 // LAMBDA-NEXT: [[A_PRIV:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[REFA]], 190 // LAMBDA-NEXT: [[A_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[A_PRIV]], 191 // LAMBDA-NEXT: [[INC:%.+]] = add nsw i{{[0-9]+}} [[A_VAL]], 1 192 // LAMBDA-NEXT: store i{{[0-9]+}} [[INC]], i{{[0-9]+}}* [[A_PRIV]], 193 // LAMBDA-64-NEXT: [[B_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[B_CONV]], 194 // LAMBDA-32-NEXT: [[B_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[B_PRIV]], 195 // LAMBDA-NEXT: [[DEC:%.+]] = add nsw i{{[0-9]+}} [[B_VAL]], -1 196 // LAMBDA-64-NEXT: store i{{[0-9]+}} [[DEC]], i{{[0-9]+}}* [[B_CONV]], 197 // LAMBDA-32-NEXT: store i{{[0-9]+}} [[DEC]], i{{[0-9]+}}* [[B_PRIV]], 198 // LAMBDA-NEXT: [[C_PRIV:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[REFC]], 199 // LAMBDA-NEXT: [[C_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[C_PRIV]], 200 // LAMBDA-NEXT: [[DIV:%.+]] = sdiv i{{[0-9]+}} [[C_VAL]], 1 201 // LAMBDA-NEXT: store i{{[0-9]+}} [[DIV]], i{{[0-9]+}}* [[C_PRIV]], 202 // LAMBDA-NEXT: ret void 203 204 // LAMBDA: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* noalias %{{.+}}, i32* noalias %{{.+}}, i32* dereferenceable(4) %{{.+}}, [[iz]] {{.*}}%{{.+}}) 205 // LAMBDA: [[SIVAR_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, 206 // LAMBDA: [[G_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, align 128 207 // LAMBDA: [[G_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[G_REF_ADDR:%.+]] 208 // LAMBDA-64: [[SIVAR_PRIVATE_CONV:%.+]] = bitcast i64* [[SIVAR_PRIVATE_ADDR]] to i32* 209 // LAMBDA: [[G_VAL:%.+]] = load volatile i{{[0-9]+}}, i{{[0-9]+}}* [[G_REF]], align 128 210 // LAMBDA: store i{{[0-9]+}} [[G_VAL]], i{{[0-9]+}}* [[G_PRIVATE_ADDR]], align 128 211 // LAMBDA-NOT: call {{.*}}void @__kmpc_barrier( 212 g = 1; 213 sivar = 2; 214 // LAMBDA: store i{{[0-9]+}} 1, i{{[0-9]+}}* [[G_PRIVATE_ADDR]], 215 // LAMBDA-64: store i{{[0-9]+}} 2, i{{[0-9]+}}* [[SIVAR_PRIVATE_CONV]], 216 // LAMBDA-32: store i{{[0-9]+}} 2, i{{[0-9]+}}* [[SIVAR_PRIVATE_ADDR]], 217 // LAMBDA: [[G_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 218 // LAMBDA: store i{{[0-9]+}}* [[G_PRIVATE_ADDR]], i{{[0-9]+}}** [[G_PRIVATE_ADDR_REF]] 219 // LAMBDA: [[SIVAR_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 1 220 // LAMBDA-64: store i{{[0-9]+}}* [[SIVAR_PRIVATE_CONV]], i{{[0-9]+}}** [[SIVAR_PRIVATE_ADDR_REF]] 221 // LAMBDA-32: store i{{[0-9]+}}* [[SIVAR_PRIVATE_ADDR]], i{{[0-9]+}}** [[SIVAR_PRIVATE_ADDR_REF]] 222 // LAMBDA: call{{.*}} void [[INNER_LAMBDA:@.+]](%{{.+}}* [[ARG]]) 223 [&]() { 224 // LAMBDA: define {{.+}} void [[INNER_LAMBDA]](%{{.+}}* [[ARG_PTR:%.+]]) 225 // LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}** [[ARG_PTR_REF:%.+]], 226 g = 2; 227 sivar = 4; 228 // LAMBDA: [[ARG_PTR:%.+]] = load %{{.+}}*, %{{.+}}** [[ARG_PTR_REF]] 229 // LAMBDA: [[G_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 230 // LAMBDA: [[G_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[G_PTR_REF]] 231 // LAMBDA: [[SIVAR_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 1 232 // LAMBDA: [[SIVAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[SIVAR_PTR_REF]] 233 // LAMBDA: store i{{[0-9]+}} 4, i{{[0-9]+}}* [[SIVAR_REF]] 234 }(); 235 } 236 }(); 237 return 0; 238 #elif defined(BLOCKS) 239 // BLOCKS: [[G:@.+]] = global i{{[0-9]+}} 1212, 240 // BLOCKS-LABEL: @main 241 // BLOCKS: call 242 // BLOCKS: call {{.*}}void {{%.+}}(i8 243 ^{ 244 // BLOCKS: define{{.*}} internal{{.*}} void {{.+}}(i8* 245 // BLOCKS: call {{.*}}void {{.+}} @__kmpc_fork_call({{.+}}, i32 2, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i32* [[G]], {{.+}}) 246 #pragma omp parallel firstprivate(g, sivar) 247 { 248 // BLOCKS: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* noalias %{{.+}}, i32* noalias %{{.+}}, i32* dereferenceable(4) %{{.+}}, [[iz:i64|i32]] {{.*}}%{{.+}}) 249 // BLOCKS: [[SIVAR_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, 250 // BLOCKS: [[G_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, align 128 251 // BLOCKS: [[G_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[G_REF_ADDR:%.+]] 252 // BLOCKS-64: [[SIVAR_PRIVATE_CONV:%.+]] = bitcast i64* [[SIVAR_PRIVATE_ADDR]] to i32* 253 // BLOCKS: [[G_VAL:%.+]] = load volatile i{{[0-9]+}}, i{{[0-9]+}}* [[G_REF]], align 128 254 // BLOCKS: store i{{[0-9]+}} [[G_VAL]], i{{[0-9]+}}* [[G_PRIVATE_ADDR]], align 128 255 // BLOCKS-NOT: call {{.*}}void @__kmpc_barrier( 256 g = 1; 257 sivar = 2; 258 // BLOCKS: store i{{[0-9]+}} 1, i{{[0-9]+}}* [[G_PRIVATE_ADDR]], 259 // BLOCKS-64: store i{{[0-9]+}} 2, i{{[0-9]+}}* [[SIVAR_PRIVATE_CONV]], 260 // BLOCKS-32: store i{{[0-9]+}} 2, i{{[0-9]+}}* [[SIVAR_PRIVATE_ADDR]], 261 // BLOCKS-NOT: [[G]]{{[[^:word:]]}} 262 // BLOCKS: i{{[0-9]+}}* [[G_PRIVATE_ADDR]] 263 // BLOCKS-NOT: [[G]]{{[[^:word:]]}} 264 // BLOCKS-NOT: [[SIVAR]]{{[[^:word:]]}} 265 // BLOCKS-64: i{{[0-9]+}}* [[SIVAR_PRIVATE_CONV]] 266 // BLOCKS-32: i{{[0-9]+}}* [[SIVAR_PRIVATE_ADDR]] 267 // BLOCKS-NOT: [[SIVAR]]{{[[^:word:]]}} 268 // BLOCKS: call {{.*}}void {{%.+}}(i8 269 ^{ 270 // BLOCKS: define {{.+}} void {{@.+}}(i8* 271 g = 2; 272 sivar = 4; 273 // BLOCKS-NOT: [[G]]{{[[^:word:]]}} 274 // BLOCKS: store i{{[0-9]+}} 2, i{{[0-9]+}}* 275 // BLOCKS-NOT: [[G]]{{[[^:word:]]}} 276 // BLOCKS-NOT: [[SIVAR]]{{[[^:word:]]}} 277 // BLOCKS: store i{{[0-9]+}} 4, i{{[0-9]+}}* 278 // BLOCKS-NOT: [[SIVAR]]{{[[^:word:]]}} 279 // BLOCKS: ret 280 }(); 281 } 282 }(); 283 return 0; 284 // BLOCKS: define {{.+}} @{{.+}}([[SS_TY]]* 285 // BLOCKS: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 0 286 // BLOCKS: store i{{[0-9]+}} 0, i{{[0-9]+}}* % 287 // BLOCKS: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 1 288 // BLOCKS: store i8 289 // BLOCKS: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 2 290 // BLOCKS: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 0 291 // BLOCKS: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 1 292 // BLOCKS: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 2 293 // BLOCKS: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 5, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [[SS_TY]]*, [[iz]], [[iz]], [[iz]], [4 x i{{[0-9]+}}]*)* [[SS_MICROTASK:@.+]] to void 294 // BLOCKS: ret 295 296 // BLOCKS: define internal void [[SS_MICROTASK]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [[SS_TY]]* %{{.+}}, [[iz]] {{.+}}, [[iz]] {{.+}}, [[iz]] {{.+}}, [4 x i{{[0-9]+}}]* {{.+}}) 297 // BLOCKS-NOT: getelementptr {{.*}}[[SS_TY]], [[SS_TY]]* % 298 // BLOCKS: call{{.*}} void 299 // BLOCKS: ret void 300 301 // BLOCKS: define internal void @{{.+}}(i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [[SS_TY]]* %{{.+}}, [[iz]] {{.+}}, [[iz]] {{.+}}, [[iz]] {{.+}}) 302 // BLOCKS: [[A_PRIV:%.+]] = alloca i{{[0-9]+}}, 303 // BLOCKS: [[B_PRIV:%.+]] = alloca i{{[0-9]+}}, 304 // BLOCKS: [[C_PRIV:%.+]] = alloca i{{[0-9]+}}, 305 // BLOCKS-64: [[A_CONV:%.+]] = bitcast i64* [[A_PRIV]] to i32* 306 // BLOCKS-64: [[B_CONV:%.+]] = bitcast i64* [[B_PRIV]] to i32* 307 // BLOCKS-64: [[C_CONV:%.+]] = bitcast i64* [[C_PRIV]] to i32* 308 // BLOCKS-64: store i32* [[A_CONV]], i32** [[REFA:%.+]], 309 // BLOCKS-32: store i32* [[A_PRIV]], i32** [[REFA:%.+]], 310 // BLOCKS-64: store i32* [[C_CONV]], i32** [[REFC:%.+]], 311 // BLOCKS-32: store i32* [[C_PRIV]], i32** [[REFC:%.+]], 312 // BLOCKS-NEXT: [[A_PRIV:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[REFA]], 313 // BLOCKS-NEXT: [[A_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[A_PRIV]], 314 // BLOCKS-NEXT: [[INC:%.+]] = add nsw i{{[0-9]+}} [[A_VAL]], 1 315 // BLOCKS-NEXT: store i{{[0-9]+}} [[INC]], i{{[0-9]+}}* [[A_PRIV]], 316 // BLOCKS-64-NEXT: [[B_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[B_CONV]], 317 // BLOCKS-32-NEXT: [[B_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[B_PRIV]], 318 // BLOCKS-NEXT: [[DEC:%.+]] = add nsw i{{[0-9]+}} [[B_VAL]], -1 319 // BLOCKS-64-NEXT: store i{{[0-9]+}} [[DEC]], i{{[0-9]+}}* [[B_CONV]], 320 // BLOCKS-32-NEXT: store i{{[0-9]+}} [[DEC]], i{{[0-9]+}}* [[B_PRIV]], 321 // BLOCKS-NEXT: [[C_PRIV:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[REFC]], 322 // BLOCKS-NEXT: [[C_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[C_PRIV]], 323 // BLOCKS-NEXT: [[DIV:%.+]] = sdiv i{{[0-9]+}} [[C_VAL]], 1 324 // BLOCKS-NEXT: store i{{[0-9]+}} [[DIV]], i{{[0-9]+}}* [[C_PRIV]], 325 // BLOCKS-NEXT: ret void 326 #else 327 S<float> test; 328 int t_var = 0; 329 int vec[] = {1, 2}; 330 S<float> s_arr[] = {1, 2}; 331 S<float> var(3); 332 #pragma omp parallel firstprivate(t_var, vec, s_arr, var, sivar) 333 { 334 vec[0] = t_var; 335 s_arr[0] = var; 336 sivar = 2; 337 } 338 const int a = 0; 339 #pragma omp parallel allocate(omp_default_mem_alloc: t_var) firstprivate(t_var, a) 340 { t_var = a; } 341 return tmain<int>(); 342 #endif 343 } 344 345 // CHECK: define {{.*}}i{{[0-9]+}} @main() 346 // CHECK: [[TEST:%.+]] = alloca [[S_FLOAT_TY]], 347 // CHECK: [[T_VAR:%.+]] = alloca i32, 348 // CHECK: [[T_VARCAST:%.+]] = alloca [[iz:i64|i32]], 349 // CHECK: [[SIVARCAST:%.+]] = alloca [[iz]], 350 // CHECK: [[A:%.+]] = alloca i32, 351 // CHECK: [[T_VARCAST1:%.+]] = alloca [[iz:i64|i32]], 352 // CHECK: call {{.*}} [[S_FLOAT_TY_DEF_CONSTR:@.+]]([[S_FLOAT_TY]]* [[TEST]]) 353 // CHECK: [[T_VARVAL:%.+]] = load i32, i32* [[T_VAR]], 354 // CHECK-64: [[T_VARCONV:%.+]] = bitcast i64* [[T_VARCAST]] to i32* 355 // CHECK-64: store i32 [[T_VARVAL]], i32* [[T_VARCONV]], 356 // CHECK-32: store i32 [[T_VARVAL]], i32* [[T_VARCAST]], 357 // CHECK: [[T_VARPVT:%.+]] = load [[iz]], [[iz]]* [[T_VARCAST]], 358 // CHECK: [[SIVARVAL:%.+]] = load i32, i32* @{{.+}}, 359 // CHECK-64: [[SIVARCONV:%.+]] = bitcast i64* [[SIVARCAST]] to i32* 360 // CHECK-64: store i32 [[SIVARVAL]], i32* [[SIVARCONV]], 361 // CHECK-32: store i32 [[SIVARVAL]], i32* [[SIVARCAST]], 362 // CHECK: [[SIVARPVT:%.+]] = load [[iz]], [[iz]]* [[SIVARCAST]], 363 // CHECK: call {{.*}}void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 5, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [2 x i32]*, [[iz]], [2 x [[S_FLOAT_TY]]]*, [[S_FLOAT_TY]]*, i{{[0-9]+}})* [[MAIN_MICROTASK:@.+]] to void {{.*}}[[iz]] [[T_VARPVT]],{{.*}}[[iz]] [[SIVARPVT]] 364 // CHECK: [[T_VARVAL:%.+]] = load i32, i32* [[T_VAR]], 365 // CHECK-64: [[T_VARCONV:%.+]] = bitcast i64* [[T_VARCAST1]] to i32* 366 // CHECK-64: store i32 [[T_VARVAL]], i32* [[T_VARCONV]], 367 // CHECK-32: store i32 [[T_VARVAL]], i32* [[T_VARCAST1]], 368 // CHECK: [[T_VARPVT:%.+]] = load [[iz]], [[iz]]* [[T_VARCAST1]], 369 // CHECK: call {{.*}}void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [[iz]])* [[MAIN_MICROTASK1:@.+]] to void {{.*}}[[iz]] [[T_VARPVT]]) 370 // CHECK: = call {{.*}}i{{.+}} [[TMAIN_INT:@.+]]() 371 // CHECK: call {{.*}} [[S_FLOAT_TY_DESTR:@.+]]([[S_FLOAT_TY]]* 372 // CHECK: ret 373 // 374 // CHECK: define internal {{.*}}void [[MAIN_MICROTASK]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [2 x i32]* dereferenceable(8) %{{.+}}, [[iz]] {{.*}}%{{.+}}, [2 x [[S_FLOAT_TY]]]* dereferenceable(8) %{{.+}}, [[S_FLOAT_TY]]* dereferenceable(4) %{{.+}}, [[iz]] {{.*}}[[SIVAR:%.+]]) 375 // CHECK: [[T_VAR_PRIV:%.+]] = alloca i{{[0-9]+}}, 376 // CHECK: [[SIVAR7_PRIV:%.+]] = alloca i{{[0-9]+}}, 377 // CHECK: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}], 378 // CHECK: [[S_ARR_PRIV:%.+]] = alloca [2 x [[S_FLOAT_TY]]], 379 // CHECK: [[VAR_PRIV:%.+]] = alloca [[S_FLOAT_TY]], 380 // CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_ADDR:%.+]], 381 382 // CHECK: [[VEC_REF:%.+]] = load [2 x i{{[0-9]+}}]*, [2 x i{{[0-9]+}}]** % 383 // CHECK-NOT: load i{{[0-9]+}}*, i{{[0-9]+}}** % 384 // CHECK-64: [[T_VAR_CONV:%.+]] = bitcast i64* [[T_VAR_PRIV]] to i32* 385 // CHECK: [[S_ARR_REF:%.+]] = load [2 x [[S_FLOAT_TY]]]*, [2 x [[S_FLOAT_TY]]]** % 386 // CHECK: [[VAR_REF:%.+]] = load [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** % 387 // CHECK-NOT: load i{{[0-9]+}}*, i{{[0-9]+}}** % 388 // CHECK-64: [[SIVAR7_CONV:%.+]] = bitcast i64* [[SIVAR7_PRIV]] to i32* 389 // CHECK: [[VEC_DEST:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_PRIV]] to i8* 390 // CHECK: [[VEC_SRC:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_REF]] to i8* 391 // CHECK: call void @llvm.memcpy.{{.+}}(i8* align {{[0-9]+}} [[VEC_DEST]], i8* align {{[0-9]+}} [[VEC_SRC]], 392 // CHECK: [[S_ARR_PRIV_BEGIN:%.+]] = getelementptr inbounds [2 x [[S_FLOAT_TY]]], [2 x [[S_FLOAT_TY]]]* [[S_ARR_PRIV]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 393 // CHECK: [[S_ARR_BEGIN:%.+]] = bitcast [2 x [[S_FLOAT_TY]]]* [[S_ARR_REF]] to [[S_FLOAT_TY]]* 394 // CHECK: [[S_ARR_PRIV_END:%.+]] = getelementptr [[S_FLOAT_TY]], [[S_FLOAT_TY]]* [[S_ARR_PRIV_BEGIN]], i{{[0-9]+}} 2 395 // CHECK: [[IS_EMPTY:%.+]] = icmp eq [[S_FLOAT_TY]]* [[S_ARR_PRIV_BEGIN]], [[S_ARR_PRIV_END]] 396 // CHECK: br i1 [[IS_EMPTY]], label %[[S_ARR_BODY_DONE:.+]], label %[[S_ARR_BODY:.+]] 397 // CHECK: [[S_ARR_BODY]] 398 // CHECK: call {{.*}} [[ST_TY_DEFAULT_CONSTR:@.+]]([[ST_TY]]* [[ST_TY_TEMP:%.+]]) 399 // CHECK: call {{.*}} [[S_FLOAT_TY_COPY_CONSTR:@.+]]([[S_FLOAT_TY]]* {{.+}}, [[S_FLOAT_TY]]* {{.+}}, [[ST_TY]]* [[ST_TY_TEMP]]) 400 // CHECK: call {{.*}} [[ST_TY_DESTR:@.+]]([[ST_TY]]* [[ST_TY_TEMP]]) 401 // CHECK: br i1 {{.+}}, label %{{.+}}, label %[[S_ARR_BODY]] 402 // CHECK: call {{.*}} [[ST_TY_DEFAULT_CONSTR]]([[ST_TY]]* [[ST_TY_TEMP:%.+]]) 403 // CHECK: call {{.*}} [[S_FLOAT_TY_COPY_CONSTR]]([[S_FLOAT_TY]]* [[VAR_PRIV]], [[S_FLOAT_TY]]* {{.*}} [[VAR_REF]], [[ST_TY]]* [[ST_TY_TEMP]]) 404 // CHECK: call {{.*}} [[ST_TY_DESTR]]([[ST_TY]]* [[ST_TY_TEMP]]) 405 406 // CHECK-64: store i{{[0-9]+}} 2, i{{[0-9]+}}* [[SIVAR7_CONV]], 407 // CHECK-32: store i{{[0-9]+}} 2, i{{[0-9]+}}* [[SIVAR7_PRIV]], 408 409 // CHECK-DAG: call {{.*}} [[S_FLOAT_TY_DESTR]]([[S_FLOAT_TY]]* [[VAR_PRIV]]) 410 // CHECK-DAG: call {{.*}} [[S_FLOAT_TY_DESTR]]([[S_FLOAT_TY]]* 411 // CHECK: ret void 412 413 414 // CHECK: define internal void [[MAIN_MICROTASK1]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [[iz]] [[T_VAR:%.+]]) 415 // CHECK: [[GTID_ADDR:%.+]] = alloca i32*, 416 // CHECK: store [[iz]] [[T_VAR]], [[iz]]* [[T_VAR_ADDR:%.+]], 417 // CHECK-64: [[BC:%.+]] = bitcast [[iz]]* [[T_VAR_ADDR]] to i32* 418 // CHECK: [[GTID_PTR:%.+]] = load i32*, i32** [[GTID_ADDR]], 419 // CHECK: [[GTID:%.+]] = load i32, i32* [[GTID_PTR]], 420 // CHECK: [[T_VAR_VOID_PTR:%.+]] = call i8* @__kmpc_alloc(i32 [[GTID]], [[iz]] 4, i8* inttoptr ([[iz]] 1 to i8*)) 421 // CHECK: [[T_VAR_PRIV:%.+]] = bitcast i8* [[T_VAR_VOID_PTR]] to i32* 422 // CHECK-32: [[T_VAR_VAL:%.+]] = load i32, i32* [[T_VAR_ADDR]], 423 // CHECK-64: [[T_VAR_VAL:%.+]] = load i32, i32* [[BC]], 424 // CHECK: store i32 [[T_VAR_VAL]], i32* [[T_VAR_PRIV]], 425 // CHECK: store i32 0, i32* [[T_VAR_PRIV]], 426 // CHECK: call void @__kmpc_free(i32 [[GTID]], i8* [[T_VAR_VOID_PTR]], i8* inttoptr ([[iz]] 1 to i8*)) 427 // CHECK: ret void 428 429 430 // CHECK: define {{.*}} i{{[0-9]+}} [[TMAIN_INT]]() 431 // CHECK: [[TEST:%.+]] = alloca [[S_INT_TY]], 432 // CHECK: call {{.*}} [[S_INT_TY_DEF_CONSTR:@.+]]([[S_INT_TY]]* [[TEST]]) 433 // CHECK: call {{.*}}void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 4, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [2 x i32]*, i32*, [2 x [[S_INT_TY]]]*, [[S_INT_TY]]*)* [[TMAIN_MICROTASK:@.+]] to void 434 // CHECK: call {{.*}} [[S_INT_TY_DESTR:@.+]]([[S_INT_TY]]* 435 // CHECK: ret 436 // 437 // CHECK: define {{.+}} @{{.+}}([[SS_TY]]* 438 // CHECK: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 0 439 // CHECK: store i{{[0-9]+}} 0, i{{[0-9]+}}* % 440 // CHECK: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 1 441 // CHECK: store i8 442 // CHECK: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 2 443 // CHECK: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 0 444 // CHECK: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 1 445 // CHECK: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 2 446 // CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 5, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [[SS_TY]]*, [[iz]], [[iz]], [[iz]], [4 x i32]*)* [[SS_MICROTASK:@.+]] to void 447 // CHECK: ret 448 449 // CHECK: define internal void [[SS_MICROTASK]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [[SS_TY]]* %{{.+}}, [[iz]] {{.+}}, [[iz]] {{.+}}, [[iz]] {{.+}}, [4 x i{{[0-9]+}}]* {{.+}}) 450 // CHECK: [[A_PRIV:%.+]] = alloca i{{[0-9]+}}, 451 // CHECK: [[B_PRIV:%.+]] = alloca i{{[0-9]+}}, 452 // CHECK: [[C_PRIV:%.+]] = alloca i{{[0-9]+}}, 453 // CHECK: [[E_PRIV:%.+]] = alloca [4 x i{{[0-9]+}}], 454 // CHECK: store i{{[0-9]+}} {{.+}}, i{{[0-9]+}}* [[A_PRIV]] 455 // CHECK: store i{{[0-9]+}} {{.+}}, i{{[0-9]+}}* [[B_PRIV]] 456 // CHECK: store i{{[0-9]+}} {{.+}}, i{{[0-9]+}}* [[C_PRIV]] 457 // CHECK-64: [[A_CONV:%.+]] = bitcast i64* [[A_PRIV:%.+]] to i32* 458 // CHECK-64: [[B_CONV:%.+]] = bitcast i64* [[B_PRIV:%.+]] to i32* 459 // CHECK-64: [[C_CONV:%.+]] = bitcast i64* [[C_PRIV:%.+]] to i32* 460 // CHECK-64: store i32* [[A_CONV]], i32** [[REFA:%.+]], 461 // CHECK-32: store i32* [[A_PRIV]], i32** [[REFA:%.+]], 462 // CHECK-64: store i32* [[C_CONV]], i32** [[REFC:%.+]], 463 // CHECK-32: store i32* [[C_PRIV]], i32** [[REFC:%.+]], 464 // CHECK: bitcast [4 x i{{[0-9]+}}]* [[E_PRIV]] to i8* 465 // CHECK: bitcast [4 x i{{[0-9]+}}]* %{{.+}} to i8* 466 // CHECK: call void @llvm.memcpy 467 // CHECK: store [4 x i{{[0-9]+}}]* [[E_PRIV]], [4 x i{{[0-9]+}}]** [[REFE:%.+]], 468 // CHECK-NEXT: [[A_PRIV:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[REFA]], 469 // CHECK-NEXT: [[A_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[A_PRIV]], 470 // CHECK-NEXT: [[INC:%.+]] = add nsw i{{[0-9]+}} [[A_VAL]], 1 471 // CHECK-NEXT: store i{{[0-9]+}} [[INC]], i{{[0-9]+}}* [[A_PRIV]], 472 // CHECK-64-NEXT: [[B_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[B_CONV]], 473 // CHECK-32-NEXT: [[B_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[B_PRIV]], 474 // CHECK-NEXT: [[DEC:%.+]] = add nsw i{{[0-9]+}} [[B_VAL]], -1 475 // CHECK-64-NEXT: store i{{[0-9]+}} [[DEC]], i{{[0-9]+}}* [[B_CONV]], 476 // CHECK-32-NEXT: store i{{[0-9]+}} [[DEC]], i{{[0-9]+}}* [[B_PRIV]], 477 // CHECK-NEXT: [[C_PRIV:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[REFC]], 478 // CHECK-NEXT: [[C_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[C_PRIV]], 479 // CHECK-NEXT: [[DIV:%.+]] = sdiv i{{[0-9]+}} [[C_VAL]], 1 480 // CHECK-NEXT: store i{{[0-9]+}} [[DIV]], i{{[0-9]+}}* [[C_PRIV]], 481 // CHECK-NEXT: [[E_PRIV:%.+]] = load [4 x i{{[0-9]+}}]*, [4 x i{{[0-9]+}}]** [[REFE]], 482 // CHECK-NEXT: [[E_PRIV_2:%.+]] = getelementptr inbounds [4 x i{{[0-9]+}}], [4 x i{{[0-9]+}}]* [[E_PRIV]], i{{[0-9]+}} 0, i{{[0-9]+}} 2 483 // CHECK-NEXT: store i32 1111, i32* [[E_PRIV_2]], 484 // CHECK-NEXT: ret void 485 486 // CHECK: define internal {{.*}}void [[TMAIN_MICROTASK]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [2 x i32]* dereferenceable(8) %{{.+}}, i32* dereferenceable(4) %{{.+}}, [2 x [[S_INT_TY]]]* dereferenceable(8) %{{.+}}, [[S_INT_TY]]* dereferenceable(4) %{{.+}}) 487 // CHECK: [[T_VAR_PRIV:%.+]] = alloca i{{[0-9]+}}, align 128 488 // CHECK: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}], align 128 489 // CHECK: [[S_ARR_PRIV:%.+]] = alloca [2 x [[S_INT_TY]]], align 128 490 // CHECK: [[VAR_PRIV:%.+]] = alloca [[S_INT_TY]], align 128 491 // CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_ADDR:%.+]], 492 493 // CHECK: [[VEC_REF:%.+]] = load [2 x i{{[0-9]+}}]*, [2 x i{{[0-9]+}}]** % 494 // CHECK: [[T_VAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** % 495 // CHECK: [[S_ARR_REF:%.+]] = load [2 x [[S_INT_TY]]]*, [2 x [[S_INT_TY]]]** % 496 // CHECK: [[VAR_REF:%.+]] = load [[S_INT_TY]]*, [[S_INT_TY]]** % 497 498 // CHECK: [[T_VAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR_REF]], align 128 499 // CHECK: store i{{[0-9]+}} [[T_VAR_VAL]], i{{[0-9]+}}* [[T_VAR_PRIV]], align 128 500 // CHECK: [[VEC_DEST:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_PRIV]] to i8* 501 // CHECK: [[VEC_SRC:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_REF]] to i8* 502 // CHECK: call void @llvm.memcpy.{{.+}}(i8* align 128 [[VEC_DEST]], i8* align 128 [[VEC_SRC]], i{{[0-9]+}} {{[0-9]+}}, i1 503 // CHECK: [[S_ARR_PRIV_BEGIN:%.+]] = getelementptr inbounds [2 x [[S_INT_TY]]], [2 x [[S_INT_TY]]]* [[S_ARR_PRIV]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 504 // CHECK: [[S_ARR_BEGIN:%.+]] = bitcast [2 x [[S_INT_TY]]]* [[S_ARR_REF]] to [[S_INT_TY]]* 505 // CHECK: [[S_ARR_PRIV_END:%.+]] = getelementptr [[S_INT_TY]], [[S_INT_TY]]* [[S_ARR_PRIV_BEGIN]], i{{[0-9]+}} 2 506 // CHECK: [[IS_EMPTY:%.+]] = icmp eq [[S_INT_TY]]* [[S_ARR_PRIV_BEGIN]], [[S_ARR_PRIV_END]] 507 // CHECK: br i1 [[IS_EMPTY]], label %[[S_ARR_BODY_DONE:.+]], label %[[S_ARR_BODY:.+]] 508 // CHECK: [[S_ARR_BODY]] 509 // CHECK: call {{.*}} [[ST_TY_DEFAULT_CONSTR]]([[ST_TY]]* [[ST_TY_TEMP:%.+]]) 510 // CHECK: call {{.*}} [[S_INT_TY_COPY_CONSTR:@.+]]([[S_INT_TY]]* {{.+}}, [[S_INT_TY]]* {{.+}}, [[ST_TY]]* [[ST_TY_TEMP]]) 511 // CHECK: call {{.*}} [[ST_TY_DESTR]]([[ST_TY]]* [[ST_TY_TEMP]]) 512 // CHECK: br i1 {{.+}}, label %{{.+}}, label %[[S_ARR_BODY]] 513 // CHECK: call {{.*}} [[ST_TY_DEFAULT_CONSTR]]([[ST_TY]]* [[ST_TY_TEMP:%.+]]) 514 // CHECK: call {{.*}} [[S_INT_TY_COPY_CONSTR]]([[S_INT_TY]]* [[VAR_PRIV]], [[S_INT_TY]]* {{.*}} [[VAR_REF]], [[ST_TY]]* [[ST_TY_TEMP]]) 515 // CHECK: call {{.*}} [[ST_TY_DESTR]]([[ST_TY]]* [[ST_TY_TEMP]]) 516 // CHECK-NOT: call {{.*}}void @__kmpc_barrier( 517 // CHECK-DAG: call {{.*}} [[S_INT_TY_DESTR]]([[S_INT_TY]]* [[VAR_PRIV]]) 518 // CHECK-DAG: call {{.*}} [[S_INT_TY_DESTR]]([[S_INT_TY]]* 519 // CHECK: ret void 520 521 #endif 522 #else 523 524 enum omp_allocator_handle_t { 525 omp_null_allocator = 0, 526 omp_default_mem_alloc = 1, 527 omp_large_cap_mem_alloc = 2, 528 omp_const_mem_alloc = 3, 529 omp_high_bw_mem_alloc = 4, 530 omp_low_lat_mem_alloc = 5, 531 omp_cgroup_mem_alloc = 6, 532 omp_pteam_mem_alloc = 7, 533 omp_thread_mem_alloc = 8, 534 KMP_ALLOCATOR_MAX_HANDLE = __UINTPTR_MAX__ 535 }; 536 537 struct St { 538 int a, b; 539 St() : a(0), b(0) {} 540 St(const St &) { } 541 ~St() {} 542 void St_func(St s[2], int n, long double vla1[n]) { 543 double vla2[n][n] __attribute__((aligned(128))); 544 a = b; 545 #pragma omp parallel allocate(omp_thread_mem_alloc:vla2) firstprivate(s, vla1, vla2) 546 vla1[b] = vla2[1][n - 1] = a = b; 547 } 548 }; 549 550 // ARRAY-LABEL: array_func 551 void array_func(float a[3], St s[2], int n, long double vla1[n]) { 552 double vla2[n][n] __attribute__((aligned(128))); 553 // ARRAY: @__kmpc_fork_call( 554 // ARRAY-DAG: [[PRIV_S:%.+]] = alloca %struct.St*, 555 // ARRAY-DAG: [[PRIV_VLA1:%.+]] = alloca x86_fp80*, 556 // ARRAY-DAG: [[PRIV_A:%.+]] = alloca float*, 557 // ARRAY-DAG: [[PRIV_VLA2:%.+]] = alloca double*, 558 // ARRAY-DAG: store %struct.St* %{{.+}}, %struct.St** [[PRIV_S]], 559 // ARRAY-DAG: store x86_fp80* %{{.+}}, x86_fp80** [[PRIV_VLA1]], 560 // ARRAY-DAG: store float* %{{.+}}, float** [[PRIV_A]], 561 // ARRAY-DAG: store double* %{{.+}}, double** [[PRIV_VLA2]], 562 // ARRAY: call i8* @llvm.stacksave() 563 // ARRAY: [[SIZE:%.+]] = mul nuw i64 %{{.+}}, 8 564 // ARRAY: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 128 %{{.+}}, i8* align 128 %{{.+}}, i64 [[SIZE]], i1 false) 565 #pragma omp parallel firstprivate(a, s, vla1, vla2) 566 s[0].St_func(s, n, vla1); 567 ; 568 } 569 570 // ARRAY-LABEL: St_func 571 // ARRAY: @__kmpc_fork_call( 572 // ARRAY-DAG: [[PRIV_VLA1:%.+]] = alloca x86_fp80*, 573 // ARRAY-DAG: [[PRIV_S:%.+]] = alloca %struct.St*, 574 // ARRAY-DAG: [[PRIV_VLA2:%.+]] = alloca double*, 575 // ARRAY-DAG: store %struct.St* %{{.+}}, %struct.St** [[PRIV_S]], 576 // ARRAY-DAG: store x86_fp80* %{{.+}}, x86_fp80** [[PRIV_VLA1]], 577 // ARRAY-DAG: store double* %{{.+}}, double** [[PRIV_VLA2]], 578 // ARRAY: [[SIZE:%.+]] = mul nuw i64 %{{.+}}, 8 579 // ARRAY: [[SZ1:%.+]] = add nuw i64 [[SIZE]], 127 580 // ARRAY: [[SZ2:%.+]] = udiv i64 [[SZ1]], 128 581 // ARRAY: [[SIZE:%.+]] = mul nuw i64 [[SZ2]], 128 582 // ARRAY: [[VLA2_VOID_PTR:%.+]] = call i8* @__kmpc_alloc(i32 [[GTID:%.+]], i64 [[SIZE]], i8* inttoptr (i64 8 to i8*)) 583 // ARRAY: [[VLA2_PTR:%.+]] = bitcast i8* [[VLA2_VOID_PTR]] to double* 584 // ARRAY: [[SIZE:%.+]] = mul nuw i64 %{{.+}}, 8 585 // ARRAY: [[BC:%.+]] = bitcast double* [[VLA2_PTR]] to i8* 586 // ARRAY: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 128 [[BC]], i8* align 128 %{{.+}}, i64 [[SIZE]], i1 false) 587 // ARRAY: call void @__kmpc_free(i32 [[GTID]], i8* [[VLA2_VOID_PTR]], i8* inttoptr (i64 8 to i8*)) 588 // ARRAY-NEXT: ret void 589 #endif 590 591 592