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