Index: lib/Sema/SemaOpenMP.cpp =================================================================== --- lib/Sema/SemaOpenMP.cpp +++ lib/Sema/SemaOpenMP.cpp @@ -522,7 +522,7 @@ // in a Construct, C/C++, predetermined, p.7] // Variables with static storage duration that are declared in a scope // inside the construct are shared. - if (D->isStaticDataMember() || D->isStaticLocal()) { + if (D->isStaticDataMember()) { DSAVarData DVarTemp = hasDSA(D, isOpenMPPrivate, MatchesAlways(), FromParent); if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr) Index: test/OpenMP/for_firstprivate_codegen.cpp =================================================================== --- test/OpenMP/for_firstprivate_codegen.cpp +++ test/OpenMP/for_firstprivate_codegen.cpp @@ -58,11 +58,13 @@ S s_arr[] = {1, 2}; // CHECK-DAG: [[VAR:@.+]] = global [[S_FLOAT_TY]] zeroinitializer, S var(3); +// CHECK: [[SIVAR:@.+]] = internal global i{{[0-9]+}} 0, // CHECK-DAG: [[IMPLICIT_BARRIER_LOC:@.+]] = private unnamed_addr constant %{{.+}} { i32 0, i32 66, i32 0, i32 0, i8* // CHECK: call {{.*}} [[S_FLOAT_TY_DEF_CONSTR:@.+]]([[S_FLOAT_TY]]* [[TEST]]) // CHECK: ([[S_FLOAT_TY]]*)* [[S_FLOAT_TY_DESTR:@[^ ]+]] {{[^,]+}}, {{.+}}([[S_FLOAT_TY]]* [[TEST]] int main() { + static int sivar; #ifdef LAMBDA // LAMBDA: [[G:@.+]] = global i{{[0-9]+}} 1212, // LAMBDA-LABEL: @main @@ -71,7 +73,7 @@ // LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]]( // LAMBDA: call void {{.+}} @__kmpc_fork_call({{.+}}, i32 1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i8* %{{.+}}) #pragma omp parallel -#pragma omp for firstprivate(g) +#pragma omp for firstprivate(g, sivar) for (int i = 0; i < 2; ++i) { // LAMBDA: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* %{{.+}}, i32* %{{.+}}, %{{.+}}* [[ARG:%.+]]) // Skip temp vars for loop @@ -81,14 +83,26 @@ // LAMBDA: alloca i{{[0-9]+}}, // LAMBDA: alloca i{{[0-9]+}}, // LAMBDA: [[G_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, + // LAMBDA: [[SIVAR_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, // LAMBDA: [[G_VAL:%.+]] = load volatile i{{[0-9]+}}, i{{[0-9]+}}* [[G]] // LAMBDA: store i{{[0-9]+}} [[G_VAL]], i{{[0-9]+}}* [[G_PRIVATE_ADDR]] + + // LAMBDA: [[SIVAR_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 + // LAMBDA: load i{{[0-9]+}}*, i{{[0-9]+}}** [[SIVAR_PRIVATE_ADDR_REF]] + // LAMBDA: load i{{[0-9]+}}, i{{[0-9]+}}* %{{.+}} + // LAMBDA: store i{{[0-9]+}} %{{.+}}, i{{[0-9]+}}* [[SIVAR_PRIVATE_ADDR]] + // LAMBDA: call void @__kmpc_barrier( g = 1; + sivar = 2; // LAMBDA: call void @__kmpc_for_static_init_4( + // LAMBDA: store i{{[0-9]+}} 1, i{{[0-9]+}}* [[G_PRIVATE_ADDR]], + // LAMBDA: store i{{[0-9]+}} 2, i{{[0-9]+}}* [[SIVAR_PRIVATE_ADDR]], // LAMBDA: [[G_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 // LAMBDA: store i{{[0-9]+}}* [[G_PRIVATE_ADDR]], i{{[0-9]+}}** [[G_PRIVATE_ADDR_REF]] + // LAMBDA: [[SIVAR_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 1 + // LAMBDA: store i{{[0-9]+}}* [[SIVAR_PRIVATE_ADDR]], i{{[0-9]+}}** [[SIVAR_PRIVATE_ADDR_REF]] // LAMBDA: call void [[INNER_LAMBDA:@.+]](%{{.+}}* [[ARG]]) // LAMBDA: call void @__kmpc_for_static_fini( // LAMBDA: call i32 @__kmpc_cancel_barrier( @@ -96,10 +110,15 @@ // LAMBDA: define {{.+}} void [[INNER_LAMBDA]](%{{.+}}* [[ARG_PTR:%.+]]) // LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}** [[ARG_PTR_REF:%.+]], g = 2; + sivar = 4; // LAMBDA: [[ARG_PTR:%.+]] = load %{{.+}}*, %{{.+}}** [[ARG_PTR_REF]] + // LAMBDA: [[G_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 // LAMBDA: [[G_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[G_PTR_REF]] // LAMBDA: store i{{[0-9]+}} 2, i{{[0-9]+}}* [[G_REF]] + // LAMBDA: [[SIVAR_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 1 + // LAMBDA: [[SIVAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[SIVAR_PTR_REF]] + // LAMBDA: store i{{[0-9]+}} 4, i{{[0-9]+}}* [[SIVAR_REF]] }(); } }(); @@ -112,7 +131,7 @@ // BLOCKS: define{{.*}} internal{{.*}} void {{.+}}(i8* // BLOCKS: call void {{.+}} @__kmpc_fork_call({{.+}}, i32 1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i8* %{{.+}}) #pragma omp parallel -#pragma omp for firstprivate(g) +#pragma omp for firstprivate(g, sivar) for (int i = 0; i < 2; ++i) { // BLOCKS: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* %{{.+}}, i32* %{{.+}}, %{{.+}}* [[ARG:%.+]]) // Skip temp vars for loop @@ -122,34 +141,47 @@ // BLOCKS: alloca i{{[0-9]+}}, // BLOCKS: alloca i{{[0-9]+}}, // BLOCKS: [[G_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, + // BLOCKS: [[SIVAR_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, // BLOCKS: [[G_VAL:%.+]] = load volatile i{{[0-9]+}}, i{{[0-9]+}}* [[G]] // BLOCKS: store i{{[0-9]+}} [[G_VAL]], i{{[0-9]+}}* [[G_PRIVATE_ADDR]] + // BLOCKS: [[SIVAR_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 + // BLOCKS: store i{{[0-9]+}} {{.+}}, i{{[0-9]+}}* [[SIVAR_PRIVATE_ADDR]] // BLOCKS: call void @__kmpc_barrier( g = 1; + sivar = 2; // BLOCKS: call void @__kmpc_for_static_init_4( // BLOCKS: store i{{[0-9]+}} 1, i{{[0-9]+}}* [[G_PRIVATE_ADDR]], // BLOCKS-NOT: [[G]]{{[[^:word:]]}} + // BLOCKS: store i{{[0-9]+}} 2, i{{[0-9]+}}* [[SIVAR_PRIVATE_ADDR]], + // BLOCKS-NOT: [[SIVAR]]{{[[^:word:]]}} // BLOCKS: i{{[0-9]+}}* [[G_PRIVATE_ADDR]] // BLOCKS-NOT: [[G]]{{[[^:word:]]}} + // BLOCKS: i{{[0-9]+}}* [[SIVAR_PRIVATE_ADDR]] + // BLOCKS-NOT: [[SIVAR]]{{[[^:word:]]}} // BLOCKS: call void {{%.+}}(i8 // BLOCKS: call void @__kmpc_for_static_fini( // BLOCKS: call i32 @__kmpc_cancel_barrier( ^{ // BLOCKS: define {{.+}} void {{@.+}}(i8* g = 2; + sivar = 4; // BLOCKS-NOT: [[G]]{{[[^:word:]]}} // BLOCKS: store i{{[0-9]+}} 2, i{{[0-9]+}}* // BLOCKS-NOT: [[G]]{{[[^:word:]]}} + // BLOCKS-NOT: [[SIVAR]]{{[[^:word:]]}} + // BLOCKS: store i{{[0-9]+}} 4, i{{[0-9]+}}* + // BLOCKS-NOT: [[SIVAR]]{{[[^:word:]]}} // BLOCKS: ret }(); } }(); return 0; #else -#pragma omp for firstprivate(t_var, vec, s_arr, var) +#pragma omp for firstprivate(t_var, vec, s_arr, var, sivar) for (int i = 0; i < 2; ++i) { vec[i] = t_var; s_arr[i] = var; + sivar += i; } return tmain(); #endif @@ -167,6 +199,7 @@ // CHECK: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}], // CHECK: [[S_ARR_PRIV:%.+]] = alloca [2 x [[S_FLOAT_TY]]], // CHECK: [[VAR_PRIV:%.+]] = alloca [[S_FLOAT_TY]], +// CHECK: [[SIVAR_PRIV:%.+]] = alloca i{{[0-9]+}}, // CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num( // firstprivate t_var(t_var) @@ -194,6 +227,10 @@ // CHECK: call {{.*}} [[S_FLOAT_TY_COPY_CONSTR]]([[S_FLOAT_TY]]* [[VAR_PRIV]], [[S_FLOAT_TY]]* {{.*}} [[VAR]], [[ST_TY]]* [[ST_TY_TEMP]]) // CHECK: call {{.*}} [[ST_TY_DESTR]]([[ST_TY]]* [[ST_TY_TEMP]]) +// firstprivate (sivar) +// CHECK: [[SIVAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SIVAR]] +// CHECK: store i{{[0-9]+}} [[SIVAR_VAL]], i{{[0-9]+}}* [[SIVAR_PRIV]] + // Synchronization for initialization. // CHECK: call void @__kmpc_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]]) Index: test/OpenMP/for_firstprivate_messages.cpp =================================================================== --- test/OpenMP/for_firstprivate_messages.cpp +++ test/OpenMP/for_firstprivate_messages.cpp @@ -303,6 +303,10 @@ #pragma omp for firstprivate(B::x) // expected-error {{threadprivate or thread local variable cannot be firstprivate}} for (i = 0; i < argc; ++i) foo(); + static int si; +#pragma omp for firstprivate(si) // OK + for (i = 0; i < argc; ++i) + si = i + 1; return foomain(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain' requested here}} } Index: test/OpenMP/for_lastprivate_codegen.cpp =================================================================== --- test/OpenMP/for_lastprivate_codegen.cpp +++ test/OpenMP/for_lastprivate_codegen.cpp @@ -23,7 +23,7 @@ char cnt; // CHECK: [[S_FLOAT_TY:%.+]] = type { float } -// CHECK: [[CAP_MAIN_TY:%.+]] = type { i{{[0-9]+}}*, [2 x i{{[0-9]+}}]*, [2 x [[S_FLOAT_TY]]]*, [[S_FLOAT_TY]]* } +// CHECK: [[CAP_MAIN_TY:%.+]] = type { i{{[0-9]+}}*, [2 x i{{[0-9]+}}]*, [2 x [[S_FLOAT_TY]]]*, [[S_FLOAT_TY]]*, i{{[0-9]+}}* } // CHECK: [[S_INT_TY:%.+]] = type { i32 } // CHECK: [[CAP_TMAIN_TY:%.+]] = type { i{{[0-9]+}}*, [2 x i{{[0-9]+}}]*, [2 x [[S_INT_TY]]]*, [[S_INT_TY]]* } // CHECK-DAG: [[IMPLICIT_BARRIER_LOC:@.+]] = private unnamed_addr constant %{{.+}} { i32 0, i32 66, i32 0, i32 0, i8* @@ -54,15 +54,17 @@ } int main() { + static int sivar; #ifdef LAMBDA // LAMBDA: [[G:@.+]] = global i{{[0-9]+}} 1212, + // LAMBDA: [[SIVAR:@.+]] = internal global i{{[0-9]+}} 0, // LAMBDA-LABEL: @main // LAMBDA: call void [[OUTER_LAMBDA:@.+]]( [&]() { // LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]]( // LAMBDA: call void {{.+}} @__kmpc_fork_call({{.+}}, i32 1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i8* %{{.+}}) #pragma omp parallel -#pragma omp for lastprivate(g) +#pragma omp for lastprivate(g, sivar) for (int i = 0; i < 2; ++i) { // LAMBDA: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* %{{.+}}, i32* %{{.+}}, %{{.+}}* [[ARG:%.+]]) // LAMBDA: alloca i{{[0-9]+}}, @@ -71,16 +73,25 @@ // LAMBDA: alloca i{{[0-9]+}}, // LAMBDA: alloca i{{[0-9]+}}, // LAMBDA: [[G_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, + // LAMBDA: [[SIVAR_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, + + // LAMBDA: store i{{[0-9]+}}* %.global_tid., i{{[0-9]+}}** [[GTID_ADDR:%.+]] // LAMBDA: store %{{.+}}* [[ARG]], %{{.+}}** [[ARG_REF:%.+]], - // LAMBDA: [[GTID_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** %{{.+}} + + // LAMBDA: [[GTID_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[GTID_ADDR]] // LAMBDA: [[GTID:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[GTID_REF]] + // LAMBDA: call {{.+}} @__kmpc_for_static_init_4(%{{.+}}* @{{.+}}, i32 [[GTID]], i32 34, i32* [[IS_LAST_ADDR:%.+]], i32* %{{.+}}, i32* %{{.+}}, i32* %{{.+}}, i32 1, i32 1) // LAMBDA: store i{{[0-9]+}} 1, i{{[0-9]+}}* [[G_PRIVATE_ADDR]], + // LAMBDA: store i{{[0-9]+}} 2, i{{[0-9]+}}* [[SIVAR_PRIVATE_ADDR]], // LAMBDA: [[G_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 // LAMBDA: store i{{[0-9]+}}* [[G_PRIVATE_ADDR]], i{{[0-9]+}}** [[G_PRIVATE_ADDR_REF]] + // LAMBDA: [[SIVAR_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 1 + // LAMBDA: store i{{[0-9]+}}* [[SIVAR_PRIVATE_ADDR]], i{{[0-9]+}}** [[SIVAR_PRIVATE_ADDR_REF]] // LAMBDA: call void [[INNER_LAMBDA:@.+]](%{{.+}}* [[ARG]]) // LAMBDA: call void @__kmpc_for_static_fini(%{{.+}}* @{{.+}}, i32 [[GTID]]) g = 1; + sivar = 2; // Check for final copying of private values back to original vars. // LAMBDA: [[IS_LAST_VAL:%.+]] = load i32, i32* [[IS_LAST_ADDR]], // LAMBDA: [[IS_LAST_ITER:%.+]] = icmp ne i32 [[IS_LAST_VAL]], 0 @@ -90,7 +101,11 @@ // original g=private_g; // LAMBDA: [[G_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[G_PRIVATE_ADDR]], - // LAMBDA: store volatile i{{[0-9]+}} [[G_VAL]], i{{[0-9]+}}* [[G]], + // LAMBDA: store volatile i{{[0-9]+}} [[G_VAL]], i{{[0-9]+}}* @{{.+}}, + + // original sivar=private_sivar; + // LAMBDA: [[SIVAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SIVAR_PRIVATE_ADDR]], + // LAMBDA: store i{{[0-9]+}} [[SIVAR_VAL]], i{{[0-9]+}}* %{{.+}}, // LAMBDA: br label %[[LAST_DONE]] // LAMBDA: [[LAST_DONE]] // LAMBDA: call i32 @__kmpc_cancel_barrier(%{{.+}}* @{{.+}}, i{{[0-9]+}} [[GTID]]) @@ -98,10 +113,14 @@ // LAMBDA: define {{.+}} void [[INNER_LAMBDA]](%{{.+}}* [[ARG_PTR:%.+]]) // LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}** [[ARG_PTR_REF:%.+]], g = 2; + sivar = 4; // LAMBDA: [[ARG_PTR:%.+]] = load %{{.+}}*, %{{.+}}** [[ARG_PTR_REF]] // LAMBDA: [[G_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 // LAMBDA: [[G_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[G_PTR_REF]] // LAMBDA: store i{{[0-9]+}} 2, i{{[0-9]+}}* [[G_REF]] + // LAMBDA: [[SIVAR_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 1 + // LAMBDA: [[SIVAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[SIVAR_PTR_REF]] + // LAMBDA: store i{{[0-9]+}} 4, i{{[0-9]+}}* [[SIVAR_REF]] }(); } }(); @@ -114,17 +133,19 @@ // BLOCKS: define{{.*}} internal{{.*}} void {{.+}}(i8* // BLOCKS: call void {{.+}} @__kmpc_fork_call({{.+}}, i32 1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i8* %{{.+}}) #pragma omp parallel -#pragma omp for lastprivate(g) +#pragma omp for lastprivate(g, sivar) for (int i = 0; i < 2; ++i) { - // BLOCKS: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* %{{.+}}, i32* %{{.+}}, %{{.+}}* [[ARG:%.+]]) + // BLOCKS: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* [[GLOBAL_TID:%.+]], i32* %{{.+}}, %{{.+}}* [[ARG:%.+]]) // BLOCKS: alloca i{{[0-9]+}}, // BLOCKS: alloca i{{[0-9]+}}, // BLOCKS: alloca i{{[0-9]+}}, // BLOCKS: alloca i{{[0-9]+}}, // BLOCKS: alloca i{{[0-9]+}}, // BLOCKS: [[G_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, + // BLOCKS: [[SIVAR_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, + // BLOCKS: store i{{[0-9]+}}* [[GLOBAL_TID]], i{{[0-9]+}}** [[GLOBAL_TID_ADDR:%.+]] // BLOCKS: store %{{.+}}* [[ARG]], %{{.+}}** [[ARG_REF:%.+]], - // BLOCKS: [[GTID_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** %{{.+}} + // BLOCKS: [[GTID_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[GLOBAL_TID_ADDR]] // BLOCKS: [[GTID:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[GTID_REF]] // BLOCKS: call {{.+}} @__kmpc_for_static_init_4(%{{.+}}* @{{.+}}, i32 [[GTID]], i32 34, i32* [[IS_LAST_ADDR:%.+]], i32* %{{.+}}, i32* %{{.+}}, i32* %{{.+}}, i32 1, i32 1) // BLOCKS: store i{{[0-9]+}} 1, i{{[0-9]+}}* [[G_PRIVATE_ADDR]], @@ -134,6 +155,7 @@ // BLOCKS: call void {{%.+}}(i8 // BLOCKS: call void @__kmpc_for_static_fini(%{{.+}}* @{{.+}}, i32 [[GTID]]) g = 1; + sivar = 2; // Check for final copying of private values back to original vars. // BLOCKS: [[IS_LAST_VAL:%.+]] = load i32, i32* [[IS_LAST_ADDR]], // BLOCKS: [[IS_LAST_ITER:%.+]] = icmp ne i32 [[IS_LAST_VAL]], 0 @@ -144,6 +166,8 @@ // original g=private_g; // BLOCKS: [[G_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[G_PRIVATE_ADDR]], // BLOCKS: store volatile i{{[0-9]+}} [[G_VAL]], i{{[0-9]+}}* [[G]], + // BLOCKS: [[SIVAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SIVAR_PRIVATE_ADDR]], + // BLOCKS: store i{{[0-9]+}} [[SIVAR_VAL]], i{{[0-9]+}}* %{{.+}}, // BLOCKS: br label %[[LAST_DONE]] // BLOCKS: [[LAST_DONE]] // BLOCKS: call i32 @__kmpc_cancel_barrier(%{{.+}}* @{{.+}}, i{{[0-9]+}} [[GTID]]) @@ -151,9 +175,13 @@ ^{ // BLOCKS: define {{.+}} void {{@.+}}(i8* g = 2; + sivar = 4; // BLOCKS-NOT: [[G]]{{[[^:word:]]}} // BLOCKS: store i{{[0-9]+}} 2, i{{[0-9]+}}* // BLOCKS-NOT: [[G]]{{[[^:word:]]}} + // BLOCKS-NOT: [[SIVAR]]{{[[^:word:]]}} + // BLOCKS: store i{{[0-9]+}} 4, i{{[0-9]+}}* + // BLOCKS-NOT: [[SIVAR]]{{[[^:word:]]}} // BLOCKS: ret }(); } @@ -166,10 +194,11 @@ S s_arr[] = {1, 2}; S var(3); #pragma omp parallel -#pragma omp for lastprivate(t_var, vec, s_arr, var) +#pragma omp for lastprivate(t_var, vec, s_arr, var, sivar) for (int i = 0; i < 2; ++i) { vec[i] = t_var; s_arr[i] = var; + sivar += i; } #pragma omp parallel #pragma omp for lastprivate(A::x, B::x) firstprivate(f) lastprivate(f) @@ -212,6 +241,7 @@ // CHECK: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}], // CHECK: [[S_ARR_PRIV:%.+]] = alloca [2 x [[S_FLOAT_TY]]], // CHECK: [[VAR_PRIV:%.+]] = alloca [[S_FLOAT_TY]], +// CHECK: [[SIVAR_PRIV:%.+]] = alloca i{{[0-9]+}}, // CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_REF:%.+]] // Check for default initialization. @@ -261,6 +291,7 @@ // original var=private_var; // CHECK: call {{.*}} [[S_FLOAT_TY_COPY_ASSIGN:@.+]]([[S_FLOAT_TY]]* [[VAR_REF]], [[S_FLOAT_TY]]* {{.*}} [[VAR_PRIV]]) +// CHECK: [[SIVAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SIVAR_PRIV]], // CHECK: br label %[[LAST_DONE]] // CHECK: [[LAST_DONE]] // CHECK-DAG: call void [[S_FLOAT_TY_DESTR]]([[S_FLOAT_TY]]* [[VAR_PRIV]]) Index: test/OpenMP/for_lastprivate_messages.cpp =================================================================== --- test/OpenMP/for_lastprivate_messages.cpp +++ test/OpenMP/for_lastprivate_messages.cpp @@ -279,5 +279,9 @@ #pragma omp for lastprivate(n) firstprivate(n) // OK for (i = 0; i < argc; ++i) foo(); + static int si; +#pragma omp for lastprivate(si) // OK + for (i = 0; i < argc; ++i) + si = i + 1; return foomain(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain' requested here}} } Index: test/OpenMP/for_private_codegen.cpp =================================================================== --- test/OpenMP/for_private_codegen.cpp +++ test/OpenMP/for_private_codegen.cpp @@ -41,34 +41,54 @@ } int main() { + static int svar; #ifdef LAMBDA // LAMBDA: [[G:@.+]] = global double // LAMBDA-LABEL: @main // LAMBDA: call{{.*}} void [[OUTER_LAMBDA:@.+]]( [&]() { + static float sfvar; // LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]]( // LAMBDA: call {{.*}}void {{.+}} @__kmpc_fork_call({{.+}}, i32 1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i8* %{{.+}}) #pragma omp parallel -#pragma omp for private(g) +#pragma omp for private(g, svar, sfvar) for (int i = 0; i < 2; ++i) { // LAMBDA: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* %{{.+}}, i32* %{{.+}}, %{{.+}}* [[ARG:%.+]]) // LAMBDA: [[G_PRIVATE_ADDR:%.+]] = alloca double, + // LAMBDA: [[SVAR_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, + // LAMBDA: [[SFVAR_PRIVATE_ADDR:%.+]] = alloca float, // LAMBDA: store %{{.+}}* [[ARG]], %{{.+}}** [[ARG_REF:%.+]], g = 1; + svar = 3; + sfvar = 4.0; // LAMBDA: call {{.*}}void @__kmpc_for_static_init_4( // LAMBDA: store double 1.0{{.+}}, double* [[G_PRIVATE_ADDR]], + // LAMBDA: store i{{[0-9]+}} 3, i{{[0-9]+}}* [[SVAR_PRIVATE_ADDR]], + // LAMBDA: store float 4.0{{.+}}, float* [[SFVAR_PRIVATE_ADDR]], // LAMBDA: [[G_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 // LAMBDA: store double* [[G_PRIVATE_ADDR]], double** [[G_PRIVATE_ADDR_REF]] + // LAMBDA: [[SVAR_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 1 + // LAMBDA: store i{{[0-9]+}}* [[SVAR_PRIVATE_ADDR]], i{{[0-9]+}}** [[SVAR_PRIVATE_ADDR_REF]] + // LAMBDA: [[SFVAR_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 2 + // LAMBDA: store float* [[SFVAR_PRIVATE_ADDR]], float** [[SFVAR_PRIVATE_ADDR_REF]] // LAMBDA: call{{.*}} void [[INNER_LAMBDA:@.+]](%{{.+}}* [[ARG]]) // LAMBDA: call {{.*}}void @__kmpc_for_static_fini( [&]() { // LAMBDA: define {{.+}} void [[INNER_LAMBDA]](%{{.+}}* [[ARG_PTR:%.+]]) // LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}** [[ARG_PTR_REF:%.+]], g = 2; + svar = 4; + sfvar = 8.0; // LAMBDA: [[ARG_PTR:%.+]] = load %{{.+}}*, %{{.+}}** [[ARG_PTR_REF]] // LAMBDA: [[G_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 // LAMBDA: [[G_REF:%.+]] = load double*, double** [[G_PTR_REF]] // LAMBDA: store double 2.0{{.+}}, double* [[G_REF]] + // LAMBDA: [[SVAR_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 1 + // LAMBDA: [[SVAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[SVAR_PTR_REF]] + // LAMBDA: store i{{[0-9]+}} 4, i{{[0-9]+}}* [[SVAR_REF]] + // LAMBDA: [[SFVAR_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 2 + // LAMBDA: [[SFVAR_REF:%.+]] = load float*, float** [[SFVAR_PTR_REF]] + // LAMBDA: store float 8.0{{.+}}, float* [[SFVAR_REF]] }(); } }(); @@ -78,28 +98,49 @@ // BLOCKS-LABEL: @main // BLOCKS: call {{.*}}void {{%.+}}(i8 ^{ + static float sfvar; // BLOCKS: define{{.*}} internal{{.*}} void {{.+}}(i8* // BLOCKS: call {{.*}}void {{.+}} @__kmpc_fork_call({{.+}}, i32 1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i8* {{.+}}) #pragma omp parallel -#pragma omp for private(g) +#pragma omp for private(g, svar, sfvar) for (int i = 0; i < 2; ++i) { // BLOCKS: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* %{{.+}}, i32* %{{.+}}, %{{.+}}* [[ARG:%.+]]) // BLOCKS: [[G_PRIVATE_ADDR:%.+]] = alloca double, + // BLOCKS: [[SVAR_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, + // BLOCKS: [[SFVAR_PRIVATE_ADDR:%.+]] = alloca float, // BLOCKS: store %{{.+}}* [[ARG]], %{{.+}}** [[ARG_REF:%.+]], g = 1; + svar = 2; + sfvar = 3.0; // BLOCKS: call {{.*}}void @__kmpc_for_static_init_4( // BLOCKS: store double 1.0{{.+}}, double* [[G_PRIVATE_ADDR]], // BLOCKS-NOT: [[G]]{{[[^:word:]]}} + // BLOCKS: store i{{[0-9]+}} 2, i{{[0-9]+}}* [[SVAR_PRIVATE_ADDR]], + // BLOCKS-NOT: [[SVAR]]{{[[^:word:]]}} + // BLOCKS: store float 3.0{{.+}}, float* [[SFVAR_PRIVATE_ADDR]], + // BLOCKS-NOT: [[SFVAR]]{{[[^:word:]]}} // BLOCKS: double* [[G_PRIVATE_ADDR]] // BLOCKS-NOT: [[G]]{{[[^:word:]]}} + // BLOCKS: i{{[0-9]+}}* [[SVAR_PRIVATE_ADDR]] + // BLOCKS-NOT: [[SVAR]]{{[[^:word:]]}} + // BLOCKS: float* [[SFVAR_PRIVATE_ADDR]] + // BLOCKS-NOT: [[SFVAR]]{{[[^:word:]]}} // BLOCKS: call {{.*}}void {{%.+}}(i8 // BLOCKS: call {{.*}}void @__kmpc_for_static_fini( ^{ // BLOCKS: define {{.+}} void {{@.+}}(i8* g = 2; + svar = 4; + sfvar = 9.0; // BLOCKS-NOT: [[G]]{{[[^:word:]]}} // BLOCKS: store double 2.0{{.+}}, double* // BLOCKS-NOT: [[G]]{{[[^:word:]]}} + // BLOCKS-NOT: [[SVAR]]{{[[^:word:]]}} + // BLOCKS: store i{{[0-9]+}} 4, i{{[0-9]+}}* + // BLOCKS-NOT: [[SVAR]]{{[[^:word:]]}} + // BLOCKS-NOT: [[SFVAR]]{{[[^:word:]]}} + // BLOCKS: store float 9.0{{.+}}, float* + // BLOCKS-NOT: [[SFVAR]]{{[[^:word:]]}} // BLOCKS: ret }(); } @@ -112,7 +153,7 @@ S s_arr[] = {1, 2}; S var(3); #pragma omp parallel -#pragma omp for private(t_var, vec, s_arr, s_arr, var, var) +#pragma omp for private(t_var, vec, s_arr, s_arr, var, var, svar) for (int i = 0; i < 2; ++i) { vec[i] = t_var; s_arr[i] = var; @@ -143,6 +184,7 @@ // CHECK-NOT: alloca [2 x [[S_FLOAT_TY]]], // CHECK: [[VAR_PRIV:%.+]] = alloca [[S_FLOAT_TY]], // CHECK-NOT: alloca [[S_FLOAT_TY]], +// CHECK: [[S_VAR_PRIV:%.+]] = alloca i{{[0-9]+}}, // CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_REF:%.+]] // CHECK-NOT: [[T_VAR_PRIV]] // CHECK-NOT: [[VEC_PRIV]] Index: test/OpenMP/for_private_messages.cpp =================================================================== --- test/OpenMP/for_private_messages.cpp +++ test/OpenMP/for_private_messages.cpp @@ -185,6 +185,10 @@ #pragma omp for private(i) for (int k = 0; k < argc; ++k) ++k; + static int si; +#pragma omp for private(si) // OK + for(int k = 0; k < argc; ++k) + si = k + 1; return 0; } Index: test/OpenMP/for_reduction_messages.cpp =================================================================== --- test/OpenMP/for_reduction_messages.cpp +++ test/OpenMP/for_reduction_messages.cpp @@ -357,6 +357,10 @@ #pragma omp for reduction(+ : fl) // expected-error {{reduction variable must be shared}} for (int i = 0; i < 10; ++i) foo(); + static int m=0; +#pragma omp for reduction(+:m) + for (int i = 0; i < 10; ++i) + m++; return tmain(argc) + tmain(fl); // expected-note {{in instantiation of function template specialization 'tmain' requested here}} expected-note {{in instantiation of function template specialization 'tmain' requested here}} } Index: test/OpenMP/for_simd_firstprivate_messages.cpp =================================================================== --- test/OpenMP/for_simd_firstprivate_messages.cpp +++ test/OpenMP/for_simd_firstprivate_messages.cpp @@ -300,6 +300,10 @@ #pragma omp for simd firstprivate(i) // expected-error {{firstprivate variable must be shared}} for (i = 0; i < argc; ++i) foo(); + static int si; +#pragma omp for simd firstprivate(si) + for (i = 0; i < argc; ++i) + si = i + 1; return foomain(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain' requested here}} } Index: test/OpenMP/for_simd_lastprivate_messages.cpp =================================================================== --- test/OpenMP/for_simd_lastprivate_messages.cpp +++ test/OpenMP/for_simd_lastprivate_messages.cpp @@ -272,5 +272,9 @@ #pragma omp for simd lastprivate(n) firstprivate(n) // OK for (i = 0; i < argc; ++i) foo(); + static int si; +#pragma omp for simd lastprivate(si) // OK + for (i = 0; i < argc; ++i) + si = i + 1; return foomain(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain' requested here}} } Index: test/OpenMP/for_simd_private_messages.cpp =================================================================== --- test/OpenMP/for_simd_private_messages.cpp +++ test/OpenMP/for_simd_private_messages.cpp @@ -175,6 +175,10 @@ #pragma omp for simd private(i) for (int k = 0; k < argc; ++k) ++k; + static int m; +#pragma omp for simd private(m) + for (int k = 0; k < argc; ++k) + m = k + 2; return 0; } Index: test/OpenMP/for_simd_reduction_messages.cpp =================================================================== --- test/OpenMP/for_simd_reduction_messages.cpp +++ test/OpenMP/for_simd_reduction_messages.cpp @@ -353,6 +353,10 @@ #pragma omp for simd reduction(+ : fl) // expected-error {{reduction variable must be shared}} for (int i = 0; i < 10; ++i) foo(); + static int m; +#pragma omp for simd reduction(+ : m) + for (int i = 0; i < 10; ++i) + m++; return tmain(argc) + tmain(fl); // expected-note {{in instantiation of function template specialization 'tmain' requested here}} expected-note {{in instantiation of function template specialization 'tmain' requested here}} } Index: test/OpenMP/parallel_firstprivate_codegen.cpp =================================================================== --- test/OpenMP/parallel_firstprivate_codegen.cpp +++ test/OpenMP/parallel_firstprivate_codegen.cpp @@ -31,7 +31,7 @@ // CHECK-DAG: [[S_FLOAT_TY:%.+]] = type { float } // CHECK-DAG: [[S_INT_TY:%.+]] = type { i{{[0-9]+}} } // CHECK-DAG: [[ST_TY:%.+]] = type { i{{[0-9]+}}, i{{[0-9]+}} } -// CHECK-DAG: [[CAP_MAIN_TY:%.+]] = type { [2 x i{{[0-9]+}}]*, i{{[0-9]+}}*, [2 x [[S_FLOAT_TY]]]*, [[S_FLOAT_TY]]* } +// CHECK-DAG: [[CAP_MAIN_TY:%.+]] = type { [2 x i{{[0-9]+}}]*, i{{[0-9]+}}*, [2 x [[S_FLOAT_TY]]]*, [[S_FLOAT_TY]]*, i{{[0-9]+}}* } // CHECK-DAG: [[CAP_TMAIN_TY:%.+]] = type { [2 x i{{[0-9]+}}]*, i{{[0-9]+}}*, [2 x [[S_INT_TY]]]*, [[S_INT_TY]]* } // CHECK-DAG: [[IMPLICIT_BARRIER_LOC:@.+]] = private unnamed_addr constant %{{.+}} { i32 0, i32 66, i32 0, i32 0, i8* @@ -53,6 +53,7 @@ } int main() { + static int sivar; #ifdef LAMBDA // LAMBDA: [[G:@.+]] = global i{{[0-9]+}} 1212, // LAMBDA-LABEL: @main @@ -63,30 +64,44 @@ // LAMBDA: store i{{[0-9]+}}* [[G]], i{{[0-9]+}}** [[G_LOCAL_REF]] // LAMBDA: [[ARG:%.+]] = bitcast %{{.+}}* [[AGG_CAPTURED]] to i8* // LAMBDA: call {{.*}}void {{.+}} @__kmpc_fork_call({{.+}}, i32 1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i8* [[ARG]]) -#pragma omp parallel firstprivate(g) +#pragma omp parallel firstprivate(g, sivar) { // LAMBDA: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* %{{.+}}, i32* %{{.+}}, %{{.+}}* [[ARG:%.+]]) // LAMBDA: [[G_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, + // LAMBDA: [[SIVAR_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, // LAMBDA: store %{{.+}}* [[ARG]], %{{.+}}** [[ARG_REF:%.+]], // LAMBDA: [[ARG:%.+]] = load %{{.+}}*, %{{.+}}** [[ARG_REF]] // LAMBDA: [[G_REF_ADDR:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 // LAMBDA: [[G_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[G_REF_ADDR]] // LAMBDA: [[G_VAL:%.+]] = load volatile i{{[0-9]+}}, i{{[0-9]+}}* [[G_REF]] // LAMBDA: store i{{[0-9]+}} [[G_VAL]], i{{[0-9]+}}* [[G_PRIVATE_ADDR]] + + // LAMBDA: [[SIVAR_REF_ADDR:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG]], i{{[0-9]+}} 0, i{{[0-9]+}} 1 + // LAMBDA: [[SIVAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[SIVAR_REF_ADDR]] + // LAMBDA: [[SIVAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SIVAR_REF]] + // LAMBDA: store i{{[0-9]+}} [[SIVAR_VAL]], i{{[0-9]+}}* [[SIVAR_PRIVATE_ADDR]] + // LAMBDA: call {{.*}}i32 @__kmpc_cancel_barrier( g = 1; + sivar = 2; // LAMBDA: store i{{[0-9]+}} 1, i{{[0-9]+}}* [[G_PRIVATE_ADDR]], + // LAMBDA: store i{{[0-9]+}} 2, i{{[0-9]+}}* [[SIVAR_PRIVATE_ADDR]], // LAMBDA: [[G_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 // LAMBDA: store i{{[0-9]+}}* [[G_PRIVATE_ADDR]], i{{[0-9]+}}** [[G_PRIVATE_ADDR_REF]] + // LAMBDA: [[SIVAR_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 1 + // LAMBDA: store i{{[0-9]+}}* [[SIVAR_PRIVATE_ADDR]], i{{[0-9]+}}** [[SIVAR_PRIVATE_ADDR_REF]] // LAMBDA: call{{.*}} void [[INNER_LAMBDA:@.+]](%{{.+}}* [[ARG]]) [&]() { // LAMBDA: define {{.+}} void [[INNER_LAMBDA]](%{{.+}}* [[ARG_PTR:%.+]]) // LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}** [[ARG_PTR_REF:%.+]], g = 2; + sivar = 4; // LAMBDA: [[ARG_PTR:%.+]] = load %{{.+}}*, %{{.+}}** [[ARG_PTR_REF]] // LAMBDA: [[G_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 // LAMBDA: [[G_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[G_PTR_REF]] - // LAMBDA: store i{{[0-9]+}} 2, i{{[0-9]+}}* [[G_REF]] + // LAMBDA: [[SIVAR_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 1 + // LAMBDA: [[SIVAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[SIVAR_PTR_REF]] + // LAMBDA: store i{{[0-9]+}} 4, i{{[0-9]+}}* [[SIVAR_REF]] }(); } }(); @@ -99,31 +114,48 @@ // BLOCKS: define{{.*}} internal{{.*}} void {{.+}}(i8* // BLOCKS: [[G_LOCAL_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[AGG_CAPTURED:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 // BLOCKS: store i{{[0-9]+}}* [[G]], i{{[0-9]+}}** [[G_LOCAL_REF]] + // BLOCKS: [[SIVAR_LOCAL_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[AGG_CAPTURED:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 1 + // BLOCKS: [[BLK_CAPTURED_ADDR:%.+]] = getelementptr inbounds <{{.+}}>, <{{.+}}>* %block, i{{[0-9]+}} 0, i{{[0-9]+}} 5 + // BLOCKS: i{{[0-9]+}}* [[BLK_CAPTURED_ADDR]], i{{[0-9]+}}** [[SIVAR_LOCAL_REF]], // BLOCKS: [[ARG:%.+]] = bitcast %{{.+}}* [[AGG_CAPTURED]] to i8* // BLOCKS: call {{.*}}void {{.+}} @__kmpc_fork_call({{.+}}, i32 1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i8* [[ARG]]) -#pragma omp parallel firstprivate(g) +#pragma omp parallel firstprivate(g, sivar) { // BLOCKS: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* %{{.+}}, i32* %{{.+}}, %{{.+}}* [[ARG:%.+]]) // BLOCKS: [[G_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, + // BLOCKS: [[SIVAR_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, // BLOCKS: store %{{.+}}* [[ARG]], %{{.+}}** [[ARG_REF:%.+]], // BLOCKS: [[ARG:%.+]] = load %{{.+}}*, %{{.+}}** [[ARG_REF]] // BLOCKS: [[G_REF_ADDR:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 // BLOCKS: [[G_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[G_REF_ADDR]] // BLOCKS: [[G_VAL:%.+]] = load volatile i{{[0-9]+}}, i{{[0-9]+}}* [[G_REF]] // BLOCKS: store i{{[0-9]+}} [[G_VAL]], i{{[0-9]+}}* [[G_PRIVATE_ADDR]] + // BLOCKS: [[SIVAR_REF_ADDR:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG]], i{{[0-9]+}} 0, i{{[0-9]+}} 1 + // BLOCKS: [[SIVAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[SIVAR_REF_ADDR]] + // BLOCKS: [[SIVAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SIVAR_REF]] + // BLOCKS: store i{{[0-9]+}} [[SIVAR_VAL]], i{{[0-9]+}}* [[SIVAR_PRIVATE_ADDR]] // BLOCKS: call {{.*}}i32 @__kmpc_cancel_barrier( g = 1; + sivar = 2; // BLOCKS: store i{{[0-9]+}} 1, i{{[0-9]+}}* [[G_PRIVATE_ADDR]], + // BLOCKS: store i{{[0-9]+}} 2, i{{[0-9]+}}* [[SIVAR_PRIVATE_ADDR]], // BLOCKS-NOT: [[G]]{{[[^:word:]]}} // BLOCKS: i{{[0-9]+}}* [[G_PRIVATE_ADDR]] // BLOCKS-NOT: [[G]]{{[[^:word:]]}} + // BLOCKS-NOT: [[SIVAR]]{{[[^:word:]]}} + // BLOCKS: i{{[0-9]+}}* [[SIVAR_PRIVATE_ADDR]] + // BLOCKS-NOT: [[SIVAR]]{{[[^:word:]]}} // BLOCKS: call {{.*}}void {{%.+}}(i8 ^{ // BLOCKS: define {{.+}} void {{@.+}}(i8* g = 2; + sivar = 4; // BLOCKS-NOT: [[G]]{{[[^:word:]]}} // BLOCKS: store i{{[0-9]+}} 2, i{{[0-9]+}}* // BLOCKS-NOT: [[G]]{{[[^:word:]]}} + // BLOCKS-NOT: [[SIVAR]]{{[[^:word:]]}} + // BLOCKS: store i{{[0-9]+}} 4, i{{[0-9]+}}* + // BLOCKS-NOT: [[SIVAR]]{{[[^:word:]]}} // BLOCKS: ret }(); } @@ -135,10 +167,11 @@ int vec[] = {1, 2}; S s_arr[] = {1, 2}; S var(3); -#pragma omp parallel firstprivate(t_var, vec, s_arr, var) +#pragma omp parallel firstprivate(t_var, vec, s_arr, var, sivar) { vec[0] = t_var; s_arr[0] = var; + sivar = 2; } #pragma omp parallel firstprivate(t_var) {} @@ -160,6 +193,7 @@ // CHECK: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}], // CHECK: [[S_ARR_PRIV:%.+]] = alloca [2 x [[S_FLOAT_TY]]], // CHECK: [[VAR_PRIV:%.+]] = alloca [[S_FLOAT_TY]], +// CHECK: [[SIVAR_PRIV:%.+]] = alloca i{{[0-9]+}}, // CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_ADDR:%.+]], // CHECK: [[T_VAR_PTR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 1 // CHECK: [[T_VAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[T_VAR_PTR_REF]], @@ -187,13 +221,16 @@ // CHECK: call {{.*}} [[ST_TY_DEFAULT_CONSTR]]([[ST_TY]]* [[ST_TY_TEMP:%.+]]) // CHECK: call {{.*}} [[S_FLOAT_TY_COPY_CONSTR]]([[S_FLOAT_TY]]* [[VAR_PRIV]], [[S_FLOAT_TY]]* {{.*}} [[VAR_REF]], [[ST_TY]]* [[ST_TY_TEMP]]) // CHECK: call {{.*}} [[ST_TY_DESTR]]([[ST_TY]]* [[ST_TY_TEMP]]) +// CHECK: [[SIVAR_REF_ADDR:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 4 +// CHECK: [[SIVAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[SIVAR_REF_ADDR]] +// CHECK: [[SIVAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SIVAR_REF]] +// CHECK: store i{{[0-9]+}} [[SIVAR_VAL]], i{{[0-9]+}}* [[SIVAR_PRIV]] // CHECK: [[GTID_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[GTID_ADDR_ADDR]] // CHECK: [[GTID:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[GTID_REF]] // CHECK: call {{.*}}i32 @__kmpc_cancel_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]]) // CHECK-DAG: call {{.*}} [[S_FLOAT_TY_DESTR]]([[S_FLOAT_TY]]* [[VAR_PRIV]]) // CHECK-DAG: call {{.*}} [[S_FLOAT_TY_DESTR]]([[S_FLOAT_TY]]* // CHECK: ret void - // CHECK: define {{.*}} i{{[0-9]+}} [[TMAIN_INT]]() // CHECK: [[TEST:%.+]] = alloca [[S_INT_TY]], // CHECK: call {{.*}} [[S_INT_TY_DEF_CONSTR:@.+]]([[S_INT_TY]]* [[TEST]]) Index: test/OpenMP/parallel_firstprivate_messages.cpp =================================================================== --- test/OpenMP/parallel_firstprivate_messages.cpp +++ test/OpenMP/parallel_firstprivate_messages.cpp @@ -62,6 +62,7 @@ S5 g(5); int i; int &j = i; + static int m; #pragma omp parallel firstprivate // expected-error {{expected '(' after 'firstprivate'}} #pragma omp parallel firstprivate ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} #pragma omp parallel firstprivate () // expected-error {{expected expression}} @@ -84,6 +85,7 @@ #pragma omp parallel shared(i) #pragma omp parallel firstprivate(i) #pragma omp parallel firstprivate(j) + #pragma omp parallel firstprivate(m) foo(); return 0; Index: test/OpenMP/parallel_for_firstprivate_messages.cpp =================================================================== --- test/OpenMP/parallel_for_firstprivate_messages.cpp +++ test/OpenMP/parallel_for_firstprivate_messages.cpp @@ -252,6 +252,10 @@ #pragma omp parallel for firstprivate(i) // expected-note {{defined as firstprivate}} for (i = 0; i < argc; ++i) // expected-error {{loop iteration variable in the associated loop of 'omp parallel for' directive may not be firstprivate, predetermined as private}} foo(); + static int si; +#pragma omp parallel for firstprivate(si) // OK + for (i = 0; i < argc; ++i) + si = i + 1; return foomain(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain' requested here}} } Index: test/OpenMP/parallel_for_lastprivate_messages.cpp =================================================================== --- test/OpenMP/parallel_for_lastprivate_messages.cpp +++ test/OpenMP/parallel_for_lastprivate_messages.cpp @@ -229,5 +229,10 @@ #pragma omp parallel for lastprivate(n) firstprivate(n) // OK for (i = 0; i < argc; ++i) foo(); + static int si; +#pragma omp parallel for lastprivate(si) // OK + for (i = 0; i < argc; ++i) + si = i + 2; + return foomain(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain' requested here}} } Index: test/OpenMP/parallel_for_private_messages.cpp =================================================================== --- test/OpenMP/parallel_for_private_messages.cpp +++ test/OpenMP/parallel_for_private_messages.cpp @@ -175,6 +175,10 @@ #pragma omp parallel for private(i) for (int k = 0; k < argc; ++k) ++k; + static int m; +#pragma omp parallel for private(m) + for (int k = 0; k < argc; ++k) + m = k + 2; return 0; } Index: test/OpenMP/parallel_for_reduction_messages.cpp =================================================================== --- test/OpenMP/parallel_for_reduction_messages.cpp +++ test/OpenMP/parallel_for_reduction_messages.cpp @@ -298,6 +298,10 @@ #pragma omp parallel for reduction(+ : fl) for (int i = 0; i < 10; ++i) foo(); + static int m; +#pragma omp parallel for reduction(+ : m) // OK + for (int i = 0; i < 10; ++i) + m++; return tmain(argc) + tmain(fl); // expected-note {{in instantiation of function template specialization 'tmain' requested here}} expected-note {{in instantiation of function template specialization 'tmain' requested here}} } Index: test/OpenMP/parallel_for_simd_firstprivate_messages.cpp =================================================================== --- test/OpenMP/parallel_for_simd_firstprivate_messages.cpp +++ test/OpenMP/parallel_for_simd_firstprivate_messages.cpp @@ -253,6 +253,10 @@ #pragma omp parallel for simd firstprivate(i) // expected-note {{defined as firstprivate}} for (i = 0; i < argc; ++i) // expected-error {{loop iteration variable in the associated loop of 'omp parallel for simd' directive may not be firstprivate, predetermined as linear}} foo(); + static int si; +#pragma omp parallel for simd firstprivate(si) // OK + for (i = 0; i < argc; ++i) + si = i + 2; return foomain(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain' requested here}} } Index: test/OpenMP/parallel_for_simd_lastprivate_messages.cpp =================================================================== --- test/OpenMP/parallel_for_simd_lastprivate_messages.cpp +++ test/OpenMP/parallel_for_simd_lastprivate_messages.cpp @@ -231,5 +231,9 @@ #pragma omp parallel for simd lastprivate(n) firstprivate(n) // OK for (i = 0; i < argc; ++i) foo(); + static int si; +#pragma omp parallel for simd lastprivate(si) // OK + for (i = 0; i < argc; ++i) + si = i + 3; return foomain(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain' requested here}} } Index: test/OpenMP/parallel_for_simd_private_messages.cpp =================================================================== --- test/OpenMP/parallel_for_simd_private_messages.cpp +++ test/OpenMP/parallel_for_simd_private_messages.cpp @@ -175,6 +175,10 @@ #pragma omp parallel for simd private(i) for (int k = 0; k < argc; ++k) ++k; + static int m; +#pragma omp parallel for simd private(m) // OK + for (int k = 0; k < argc; ++k) + m = k + 3; return 0; } Index: test/OpenMP/parallel_for_simd_reduction_messages.cpp =================================================================== --- test/OpenMP/parallel_for_simd_reduction_messages.cpp +++ test/OpenMP/parallel_for_simd_reduction_messages.cpp @@ -298,6 +298,10 @@ #pragma omp parallel for simd reduction(+ : fl) for (int i = 0; i < 10; ++i) foo(); + static int m; +#pragma omp parallel for simd reduction(+ : m) // OK + for (int i = 0; i < 10; ++i) + m++; return tmain(argc) + tmain(fl); // expected-note {{in instantiation of function template specialization 'tmain' requested here}} expected-note {{in instantiation of function template specialization 'tmain' requested here}} } Index: test/OpenMP/parallel_private_codegen.cpp =================================================================== --- test/OpenMP/parallel_private_codegen.cpp +++ test/OpenMP/parallel_private_codegen.cpp @@ -38,6 +38,7 @@ } int main() { + static int sivar; #ifdef LAMBDA // LAMBDA: [[G:@.+]] = global i{{[0-9]+}} 1212, // LAMBDA-LABEL: @main @@ -47,24 +48,35 @@ // LAMBDA-NOT: = getelementptr inbounds %{{.+}}, // LAMBDA: [[ARG:%.+]] = bitcast %{{.+}}* %{{.+}} to i8* // LAMBDA: call{{.*}} void {{.+}} @__kmpc_fork_call({{.+}}, i32 1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i8* [[ARG]]) -#pragma omp parallel private(g) +#pragma omp parallel private(g, sivar) { // LAMBDA: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* %{{.+}}, i32* %{{.+}}, %{{.+}}* [[ARG:%.+]]) // LAMBDA: [[G_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, + // LAMBDA: [[SIVAR_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, // LAMBDA: store %{{.+}}* [[ARG]], %{{.+}}** [[ARG_REF:%.+]], g = 1; + sivar = 2; // LAMBDA: store i{{[0-9]+}} 1, i{{[0-9]+}}* [[G_PRIVATE_ADDR]], + // LAMBDA: store i{{[0-9]+}} 2, i{{[0-9]+}}* [[SIVAR_PRIVATE_ADDR]], // LAMBDA: [[G_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 // LAMBDA: store i{{[0-9]+}}* [[G_PRIVATE_ADDR]], i{{[0-9]+}}** [[G_PRIVATE_ADDR_REF]] + + // LAMBDA: [[SIVAR_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 1 + // LAMBDA: store i{{[0-9]+}}* [[SIVAR_PRIVATE_ADDR]], i{{[0-9]+}}** [[SIVAR_PRIVATE_ADDR_REF]] + // LAMBDA: call{{.*}} void [[INNER_LAMBDA:@.+]](%{{.+}}* [[ARG]]) [&]() { // LAMBDA: define {{.+}} void [[INNER_LAMBDA]](%{{.+}}* [[ARG_PTR:%.+]]) // LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}** [[ARG_PTR_REF:%.+]], g = 2; + sivar = 4; // LAMBDA: [[ARG_PTR:%.+]] = load %{{.+}}*, %{{.+}}** [[ARG_PTR_REF]] // LAMBDA: [[G_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 // LAMBDA: [[G_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[G_PTR_REF]] // LAMBDA: store i{{[0-9]+}} 2, i{{[0-9]+}}* [[G_REF]] + // LAMBDA: [[SIVAR_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 1 + // LAMBDA: [[SIVAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[SIVAR_PTR_REF]] + // LAMBDA: store i{{[0-9]+}} 4, i{{[0-9]+}}* [[SIVAR_REF]] }(); } }(); @@ -78,23 +90,33 @@ // BLOCKS-NOT: = getelementptr inbounds %{{.+}}, // BLOCKS: [[ARG:%.+]] = bitcast %{{.+}}* %{{.+}} to i8* // BLOCKS: call{{.*}} void {{.+}} @__kmpc_fork_call({{.+}}, i32 1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i8* [[ARG]]) -#pragma omp parallel private(g) +#pragma omp parallel private(g, sivar) { // BLOCKS: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* %{{.+}}, i32* %{{.+}}, %{{.+}}* [[ARG:%.+]]) // BLOCKS: [[G_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, + // BLOCKS: [[SIVAR_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, // BLOCKS: store %{{.+}}* [[ARG]], %{{.+}}** [[ARG_REF:%.+]], g = 1; + sivar = 20; // BLOCKS: store i{{[0-9]+}} 1, i{{[0-9]+}}* [[G_PRIVATE_ADDR]], + // BLOCKS: store i{{[0-9]+}} 20, i{{[0-9]+}}* [[SIVAR_PRIVATE_ADDR]], // BLOCKS-NOT: [[G]]{{[[^:word:]]}} // BLOCKS: i{{[0-9]+}}* [[G_PRIVATE_ADDR]] // BLOCKS-NOT: [[G]]{{[[^:word:]]}} + // BLOCKS-NOT: [[SIVAR]]{{[[^:word:]]}} + // BLOCKS: i{{[0-9]+}}* [[SIVAR_PRIVATE_ADDR]] + // BLOCKS-NOT: [[SIVAR]]{{[[^:word:]]}} // BLOCKS: call{{.*}} void {{%.+}}(i8 ^{ // BLOCKS: define {{.+}} void {{@.+}}(i8* g = 2; + sivar = 40; // BLOCKS-NOT: [[G]]{{[[^:word:]]}} // BLOCKS: store i{{[0-9]+}} 2, i{{[0-9]+}}* // BLOCKS-NOT: [[G]]{{[[^:word:]]}} + // BLOCKS-NOT: [[SIVAR]]{{[[^:word:]]}} + // BLOCKS: store i{{[0-9]+}} 40, i{{[0-9]+}}* + // BLOCKS-NOT: [[SIVAR]]{{[[^:word:]]}} // BLOCKS: ret }(); } @@ -106,10 +128,11 @@ int vec[] = {1, 2}; S s_arr[] = {1, 2}; S var(3); -#pragma omp parallel private(t_var, vec, s_arr, var) +#pragma omp parallel private(t_var, vec, s_arr, var, sivar) { vec[0] = t_var; s_arr[0] = var; + sivar = 3; } return tmain(); #endif @@ -129,6 +152,7 @@ // CHECK: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}], // CHECK: [[S_ARR_PRIV:%.+]] = alloca [2 x [[S_FLOAT_TY]]], // CHECK: [[VAR_PRIV:%.+]] = alloca [[S_FLOAT_TY]], +// CHECK: [[SIVAR_PRIV:%.+]] = alloca i{{[0-9]+}}, // CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_REF:%.+]] // CHECK-NOT: [[T_VAR_PRIV]] // CHECK-NOT: [[VEC_PRIV]] @@ -157,6 +181,7 @@ // CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_REF:%.+]] // CHECK-NOT: [[T_VAR_PRIV]] // CHECK-NOT: [[VEC_PRIV]] +// CHECK-NOT: [[SIVAR_PRIV]] // CHECK: {{.+}}: // CHECK: [[S_ARR_PRIV_ITEM:%.+]] = phi [[S_INT_TY]]* // CHECK: call {{.*}} [[S_INT_TY_DEF_CONSTR]]([[S_INT_TY]]* [[S_ARR_PRIV_ITEM]]) Index: test/OpenMP/parallel_private_messages.cpp =================================================================== --- test/OpenMP/parallel_private_messages.cpp +++ test/OpenMP/parallel_private_messages.cpp @@ -84,6 +84,9 @@ #pragma omp parallel private(i) foo(); } + static int m; + #pragma omp parallel private(m) // OK + foo(); return 0; } Index: test/OpenMP/parallel_reduction_messages.cpp =================================================================== --- test/OpenMP/parallel_reduction_messages.cpp +++ test/OpenMP/parallel_reduction_messages.cpp @@ -243,6 +243,9 @@ for (int i = 0; i < 10; ++i) #pragma omp parallel reduction(+ : fl) foo(); + static int m; +#pragma omp parallel reduction(+ : m) // OK + m++; return tmain(argc) + tmain(fl); // expected-note {{in instantiation of function template specialization 'tmain' requested here}} expected-note {{in instantiation of function template specialization 'tmain' requested here}} } Index: test/OpenMP/parallel_sections_firstprivate_messages.cpp =================================================================== --- test/OpenMP/parallel_sections_firstprivate_messages.cpp +++ test/OpenMP/parallel_sections_firstprivate_messages.cpp @@ -298,6 +298,11 @@ { foo(); } + static int r; +#pragma omp parallel sections firstprivate(r) // OK + { + foo(); + } return foomain(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain' requested here}} } Index: test/OpenMP/parallel_sections_lastprivate_messages.cpp =================================================================== --- test/OpenMP/parallel_sections_lastprivate_messages.cpp +++ test/OpenMP/parallel_sections_lastprivate_messages.cpp @@ -274,5 +274,10 @@ { foo(); } + static int r; +#pragma omp parallel sections lastprivate(r) // OK + { + foo(); + } return foomain(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain' requested here}} } Index: test/OpenMP/parallel_sections_private_messages.cpp =================================================================== --- test/OpenMP/parallel_sections_private_messages.cpp +++ test/OpenMP/parallel_sections_private_messages.cpp @@ -206,6 +206,11 @@ { foo(); } + static int m; +#pragma omp parallel sections private(m) + { + foo(); + } return 0; } Index: test/OpenMP/parallel_sections_reduction_messages.cpp =================================================================== --- test/OpenMP/parallel_sections_reduction_messages.cpp +++ test/OpenMP/parallel_sections_reduction_messages.cpp @@ -361,6 +361,11 @@ { foo(); } + static int m; +#pragma omp parallel sections reduction(+ : m) // OK + { + foo(); + } return tmain(argc) + tmain(fl); // expected-note {{in instantiation of function template specialization 'tmain' requested here}} expected-note {{in instantiation of function template specialization 'tmain' requested here}} } Index: test/OpenMP/sections_firstprivate_codegen.cpp =================================================================== --- test/OpenMP/sections_firstprivate_codegen.cpp +++ test/OpenMP/sections_firstprivate_codegen.cpp @@ -59,12 +59,14 @@ S s_arr[] = {1, 2}; // CHECK-DAG: [[VAR:@.+]] = global [[S_FLOAT_TY]] zeroinitializer, S var(3); +// CHECK-DAG: [[SIVAR:@.+]] = internal global i{{[0-9]+}} 0, // CHECK-DAG: [[IMPLICIT_BARRIER_LOC:@.+]] = private unnamed_addr constant %{{.+}} { i32 0, i32 66, i32 0, i32 0, i8* // CHECK-DAG: [[SECTIONS_BARRIER_LOC:@.+]] = private unnamed_addr constant %{{.+}} { i32 0, i32 194, i32 0, i32 0, i8* // CHECK: call {{.*}} [[S_FLOAT_TY_DEF_CONSTR:@.+]]([[S_FLOAT_TY]]* [[TEST]]) // CHECK: ([[S_FLOAT_TY]]*)* [[S_FLOAT_TY_DESTR:@[^ ]+]] {{[^,]+}}, {{.+}}([[S_FLOAT_TY]]* [[TEST]] int main() { + static int sivar; #ifdef LAMBDA // LAMBDA: [[G:@.+]] = global i{{[0-9]+}} 1212, // LAMBDA-LABEL: @main @@ -73,7 +75,7 @@ // LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]]( // LAMBDA: call void {{.+}} @__kmpc_fork_call({{.+}}, i32 1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i8* %{{.+}}) #pragma omp parallel -#pragma omp sections firstprivate(g) +#pragma omp sections firstprivate(g, sivar) { // LAMBDA: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* %{{.+}}, i32* %{{.+}}, %{{.+}}* [[ARG:%.+]]) // Skip temp vars for loop @@ -83,14 +85,25 @@ // LAMBDA: alloca i{{[0-9]+}}, // LAMBDA: alloca i{{[0-9]+}}, // LAMBDA: [[G_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, + // LAMBDA: [[SIVAR_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, // LAMBDA: [[G_VAL:%.+]] = load volatile i{{[0-9]+}}, i{{[0-9]+}}* [[G]] // LAMBDA: store i{{[0-9]+}} [[G_VAL]], i{{[0-9]+}}* [[G_PRIVATE_ADDR]] + // LAMBDA: [[SIVAR_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 + // LAMBDA: [[SIVAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[SIVAR_PRIVATE_ADDR_REF]], + // LAMBDA: [[SIVAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SIVAR_REF]] + // LAMBDA: store i{{[0-9]+}} [[SIVAR_VAL]], i{{[0-9]+}}* [[SIVAR_PRIVATE_ADDR]] // LAMBDA: call void @__kmpc_barrier( - g = 1; + { + g = 1; + sivar = 10; + } // LAMBDA: call void @__kmpc_for_static_init_4( // LAMBDA: store i{{[0-9]+}} 1, i{{[0-9]+}}* [[G_PRIVATE_ADDR]], + // LAMBDA: store i{{[0-9]+}} 10, i{{[0-9]+}}* [[SIVAR_PRIVATE_ADDR]], // LAMBDA: [[G_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 // LAMBDA: store i{{[0-9]+}}* [[G_PRIVATE_ADDR]], i{{[0-9]+}}** [[G_PRIVATE_ADDR_REF]] + // LAMBDA: [[SIVAR_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 1 + // LAMBDA: store i{{[0-9]+}}* [[SIVAR_PRIVATE_ADDR]], i{{[0-9]+}}** [[SIVAR_PRIVATE_ADDR_REF]] // LAMBDA: call void [[INNER_LAMBDA:@.+]](%{{.+}}* [[ARG]]) // LAMBDA: call void @__kmpc_for_static_fini( // LAMBDA: call i32 @__kmpc_cancel_barrier( @@ -99,10 +112,14 @@ // LAMBDA: define {{.+}} void [[INNER_LAMBDA]](%{{.+}}* [[ARG_PTR:%.+]]) // LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}** [[ARG_PTR_REF:%.+]], g = 2; + sivar = 20; // LAMBDA: [[ARG_PTR:%.+]] = load %{{.+}}*, %{{.+}}** [[ARG_PTR_REF]] // LAMBDA: [[G_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 // LAMBDA: [[G_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[G_PTR_REF]] // LAMBDA: store i{{[0-9]+}} 2, i{{[0-9]+}}* [[G_REF]] + // LAMBDA: [[SIVAR_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 1 + // LAMBDA: [[SIVAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[SIVAR_PTR_REF]] + // LAMBDA: store i{{[0-9]+}} 20, i{{[0-9]+}}* [[SIVAR_REF]] }(); } }(); @@ -115,7 +132,7 @@ // BLOCKS: define{{.*}} internal{{.*}} void {{.+}}(i8* // BLOCKS: call void {{.+}} @__kmpc_fork_call({{.+}}, i32 1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i8* %{{.+}}) #pragma omp parallel -#pragma omp sections firstprivate(g) +#pragma omp sections firstprivate(g, sivar) { // BLOCKS: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* %{{.+}}, i32* %{{.+}}, %{{.+}}* [[ARG:%.+]]) // Skip temp vars for loop @@ -125,15 +142,27 @@ // BLOCKS: alloca i{{[0-9]+}}, // BLOCKS: alloca i{{[0-9]+}}, // BLOCKS: [[G_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, + // BLOCKS: [[SIVAR_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, // BLOCKS: [[G_VAL:%.+]] = load volatile i{{[0-9]+}}, i{{[0-9]+}}* [[G]] // BLOCKS: store i{{[0-9]+}} [[G_VAL]], i{{[0-9]+}}* [[G_PRIVATE_ADDR]] + // BLOCKS: [[SIVAR_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 0 + // BLOCKS: [[SIVAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[SIVAR_PTR_REF]], + // BLOCKS: [[SIVAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SIVAR_REF]], + // BLOCKS: store i{{[0-9]+}} [[SIVAR_VAL]], i{{[0-9]+}}* [[SIVAR_PRIVATE_ADDR]], // BLOCKS: call void @__kmpc_barrier( - g = 1; + { + g = 1; + sivar = 10; + } // BLOCKS: call void @__kmpc_for_static_init_4( // BLOCKS: store i{{[0-9]+}} 1, i{{[0-9]+}}* [[G_PRIVATE_ADDR]], + // BLOCKS: store i{{[0-9]+}} 10, i{{[0-9]+}}* [[SIVAR_PRIVATE_ADDR]], // BLOCKS-NOT: [[G]]{{[[^:word:]]}} // BLOCKS: i{{[0-9]+}}* [[G_PRIVATE_ADDR]] // BLOCKS-NOT: [[G]]{{[[^:word:]]}} + // BLOCKS-NOT: [[SIVAR]]{{[[^:word:]]}} + // BLOCKS: i{{[0-9]+}}* [[SIVAR_PRIVATE_ADDR]] + // BLOCKS-NOT: [[SIVAR]]{{[[^:word:]]}} // BLOCKS: call void {{%.+}}(i8 // BLOCKS: call void @__kmpc_for_static_fini( // BLOCKS: call i32 @__kmpc_cancel_barrier( @@ -141,20 +170,25 @@ ^{ // BLOCKS: define {{.+}} void {{@.+}}(i8* g = 2; + sivar = 20; // BLOCKS-NOT: [[G]]{{[[^:word:]]}} // BLOCKS: store i{{[0-9]+}} 2, i{{[0-9]+}}* // BLOCKS-NOT: [[G]]{{[[^:word:]]}} + // BLOCKS-NOT: [[SIVAR]]{{[[^:word:]]}} + // BLOCKS: store i{{[0-9]+}} 20, i{{[0-9]+}}* + // BLOCKS-NOT: [[SIVAR]]{{[[^:word:]]}} // BLOCKS: ret }(); } }(); return 0; #else -#pragma omp sections firstprivate(t_var, vec, s_arr, var) nowait +#pragma omp sections firstprivate(t_var, vec, s_arr, var, sivar) nowait { { vec[0] = t_var; s_arr[0] = var; + sivar = 31; } } return tmain(); @@ -168,12 +202,12 @@ // CHECK: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}], // CHECK: [[S_ARR_PRIV:%.+]] = alloca [2 x [[S_FLOAT_TY]]], // CHECK: [[VAR_PRIV:%.+]] = alloca [[S_FLOAT_TY]], +// CHECK: [[SIVAR_PRIV:%.+]] = alloca i{{[0-9]+}}, // CHECK: call i32 @__kmpc_single( // firstprivate t_var(t_var) // CHECK: [[T_VAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[T_VAR]], // CHECK: store i{{[0-9]+}} [[T_VAR_VAL]], i{{[0-9]+}}* [[T_VAR_PRIV]], - // firstprivate vec(vec) // CHECK: [[VEC_DEST:%.+]] = bitcast [2 x i{{[0-9]+}}]* [[VEC_PRIV]] to i8* // CHECK: call void @llvm.memcpy.{{.+}}(i8* [[VEC_DEST]], i8* bitcast ([2 x i{{[0-9]+}}]* [[VEC]] to i8*), @@ -195,6 +229,10 @@ // CHECK: call {{.*}} [[S_FLOAT_TY_COPY_CONSTR]]([[S_FLOAT_TY]]* [[VAR_PRIV]], [[S_FLOAT_TY]]* {{.*}} [[VAR]], [[ST_TY]]* [[ST_TY_TEMP]]) // CHECK: call {{.*}} [[ST_TY_DESTR]]([[ST_TY]]* [[ST_TY_TEMP]]) +// firstprivate isvar +// CHEC: [[SIVAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SIVAR]], +// CHEC: store i{{[0-9]+}} [[SIVAR_VAL]], i{{[0-9]+}}* [[SIVAR_PRIV]], + // ~(firstprivate var), ~(firstprivate s_arr) // CHECK-DAG: call {{.*}} [[S_FLOAT_TY_DESTR]]([[S_FLOAT_TY]]* [[VAR_PRIV]]) // CHECK-DAG: call {{.*}} [[S_FLOAT_TY_DESTR]]([[S_FLOAT_TY]]* Index: test/OpenMP/sections_firstprivate_messages.cpp =================================================================== --- test/OpenMP/sections_firstprivate_messages.cpp +++ test/OpenMP/sections_firstprivate_messages.cpp @@ -338,6 +338,11 @@ { foo(); } + static int r; +#pragma omp sections firstprivate(r) // OK + { + foo(); + } return foomain(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain' requested here}} } Index: test/OpenMP/sections_lastprivate_codegen.cpp =================================================================== --- test/OpenMP/sections_lastprivate_codegen.cpp +++ test/OpenMP/sections_lastprivate_codegen.cpp @@ -21,7 +21,7 @@ volatile int g = 1212; // CHECK: [[S_FLOAT_TY:%.+]] = type { float } -// CHECK: [[CAP_MAIN_TY:%.+]] = type { i{{[0-9]+}}*, [2 x i{{[0-9]+}}]*, [2 x [[S_FLOAT_TY]]]*, [[S_FLOAT_TY]]* } +// CHECK: [[CAP_MAIN_TY:%.+]] = type { i{{[0-9]+}}*, [2 x i{{[0-9]+}}]*, [2 x [[S_FLOAT_TY]]]*, [[S_FLOAT_TY]]*, i{{[0-9]+}}* } // CHECK: [[S_INT_TY:%.+]] = type { i32 } // CHECK: [[CAP_TMAIN_TY:%.+]] = type { i{{[0-9]+}}*, [2 x i{{[0-9]+}}]*, [2 x [[S_INT_TY]]]*, [[S_INT_TY]]* } // CHECK-DAG: [[IMPLICIT_BARRIER_LOC:@.+]] = private unnamed_addr constant %{{.+}} { i32 0, i32 66, i32 0, i32 0, i8* @@ -53,6 +53,7 @@ } int main() { + static int sivar; #ifdef LAMBDA // LAMBDA: [[G:@.+]] = global i{{[0-9]+}} 1212, // LAMBDA-LABEL: @main @@ -61,25 +62,36 @@ // LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]]( // LAMBDA: call void {{.+}} @__kmpc_fork_call({{.+}}, i32 1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i8* %{{.+}}) #pragma omp parallel -#pragma omp sections lastprivate(g) +#pragma omp sections lastprivate(g, sivar) { - // LAMBDA: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* %{{.+}}, i32* %{{.+}}, %{{.+}}* [[ARG:%.+]]) + // LAMBDA: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* %{{.+}}, i32* %{{.+}}, [[STRUCT_ADDR:%.+]]* [[ARG:%.+]]) // LAMBDA: alloca i{{[0-9]+}}, // LAMBDA: alloca i{{[0-9]+}}, // LAMBDA: alloca i{{[0-9]+}}, // LAMBDA: alloca i{{[0-9]+}}, // LAMBDA: alloca i{{[0-9]+}}, // LAMBDA: [[G_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, + // LAMBDA: [[SIVAR_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, // LAMBDA: store %{{.+}}* [[ARG]], %{{.+}}** [[ARG_REF:%.+]], + + // LAMBDA: [[STRUCT_ADDR_REF:%.+]] = getelementptr inbounds [[STRUCT_ADDR]], [[STRUCT_ADDR]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 0 + // LAMBDA: [[REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[STRUCT_ADDR_REF]], + // LAMBDA: [[GTID_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** %{{.+}} // LAMBDA: [[GTID:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[GTID_REF]] // LAMBDA: call {{.+}} @__kmpc_for_static_init_4(%{{.+}}* @{{.+}}, i32 [[GTID]], i32 34, i32* [[IS_LAST_ADDR:%.+]], i32* %{{.+}}, i32* %{{.+}}, i32* %{{.+}}, i32 1, i32 1) // LAMBDA: store i{{[0-9]+}} 1, i{{[0-9]+}}* [[G_PRIVATE_ADDR]], + // LAMBDA: store i{{[0-9]+}} 13, i{{[0-9]+}}* [[SIVAR_PRIVATE_ADDR]], // LAMBDA: [[G_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 // LAMBDA: store i{{[0-9]+}}* [[G_PRIVATE_ADDR]], i{{[0-9]+}}** [[G_PRIVATE_ADDR_REF]] + // LAMBDA: [[SIVAR_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 1 + // LAMBDA: store i{{[0-9]+}}* [[SIVAR_PRIVATE_ADDR]], i{{[0-9]+}}** [[SIVAR_PRIVATE_ADDR_REF]] // LAMBDA: call void [[INNER_LAMBDA:@.+]](%{{.+}}* [[ARG]]) // LAMBDA: call void @__kmpc_for_static_fini(%{{.+}}* @{{.+}}, i32 [[GTID]]) - g = 1; + { + g = 1; + sivar = 13; + } // Check for final copying of private values back to original vars. // LAMBDA: [[IS_LAST_VAL:%.+]] = load i32, i32* [[IS_LAST_ADDR]], // LAMBDA: [[IS_LAST_ITER:%.+]] = icmp ne i32 [[IS_LAST_VAL]], 0 @@ -90,6 +102,10 @@ // original g=private_g; // LAMBDA: [[G_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[G_PRIVATE_ADDR]], // LAMBDA: store volatile i{{[0-9]+}} [[G_VAL]], i{{[0-9]+}}* [[G]], + + // original sivar = private sivar; + // LAMBDA: [[SIVAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SIVAR_PRIVATE_ADDR]], + // LAMBDA: store i{{[0-9]+}} [[SIVAR_VAL]], i{{[0-9]+}}* [[REF]], // LAMBDA: br label %[[LAST_DONE]] // LAMBDA: [[LAST_DONE]] // LAMBDA: call i32 @__kmpc_cancel_barrier(%{{.+}}* @{{.+}}, i{{[0-9]+}} [[GTID]]) @@ -98,10 +114,14 @@ // LAMBDA: define {{.+}} void [[INNER_LAMBDA]](%{{.+}}* [[ARG_PTR:%.+]]) // LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}** [[ARG_PTR_REF:%.+]], g = 2; + sivar = 23; // LAMBDA: [[ARG_PTR:%.+]] = load %{{.+}}*, %{{.+}}** [[ARG_PTR_REF]] // LAMBDA: [[G_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 // LAMBDA: [[G_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[G_PTR_REF]] // LAMBDA: store i{{[0-9]+}} 2, i{{[0-9]+}}* [[G_REF]] + // LAMBDA: [[SIVAR_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 1 + // LAMBDA: [[SIVAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[SIVAR_PTR_REF]] + // LAMBDA: store i{{[0-9]+}} 23, i{{[0-9]+}}* [[SIVAR_REF]] }(); } }(); @@ -114,26 +134,38 @@ // BLOCKS: define{{.*}} internal{{.*}} void {{.+}}(i8* // BLOCKS: call void {{.+}} @__kmpc_fork_call({{.+}}, i32 1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i8* %{{.+}}) #pragma omp parallel -#pragma omp sections lastprivate(g) +#pragma omp sections lastprivate(g, sivar) { - // BLOCKS: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* %{{.+}}, i32* %{{.+}}, %{{.+}}* [[ARG:%.+]]) + // BLOCKS: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* %{{.+}}, i32* %{{.+}}, [[STRUCT_ADDR:%.+]]* [[ARG:%.+]]) // BLOCKS: alloca i{{[0-9]+}}, // BLOCKS: alloca i{{[0-9]+}}, // BLOCKS: alloca i{{[0-9]+}}, // BLOCKS: alloca i{{[0-9]+}}, // BLOCKS: alloca i{{[0-9]+}}, // BLOCKS: [[G_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, + // BLOCKS: [[SIVAR_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, // BLOCKS: store %{{.+}}* [[ARG]], %{{.+}}** [[ARG_REF:%.+]], + + // BLOCKS: [[STRUCT_ADDR_REF:%.+]] = getelementptr inbounds [[STRUCT_ADDR]], [[STRUCT_ADDR]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 0 + // BLOCKS: [[REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[STRUCT_ADDR_REF]] + // BLOCKS: [[GTID_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** %{{.+}} // BLOCKS: [[GTID:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[GTID_REF]] // BLOCKS: call {{.+}} @__kmpc_for_static_init_4(%{{.+}}* @{{.+}}, i32 [[GTID]], i32 34, i32* [[IS_LAST_ADDR:%.+]], i32* %{{.+}}, i32* %{{.+}}, i32* %{{.+}}, i32 1, i32 1) // BLOCKS: store i{{[0-9]+}} 1, i{{[0-9]+}}* [[G_PRIVATE_ADDR]], + // BLOCKS: store i{{[0-9]+}} 17, i{{[0-9]+}}* [[SIVAR_PRIVATE_ADDR]], // BLOCKS-NOT: [[G]]{{[[^:word:]]}} // BLOCKS: i{{[0-9]+}}* [[G_PRIVATE_ADDR]] // BLOCKS-NOT: [[G]]{{[[^:word:]]}} + // BLOCKS-NOT: [[SIVAR]]{{[[^:word:]]}} + // BLOCKS: i{{[0-9]+}}* [[SIVAR_PRIVATE_ADDR]] + // BLOCKS-NOT: [[SIVAR]]{{[[^:word:]]}} // BLOCKS: call void {{%.+}}(i8 // BLOCKS: call void @__kmpc_for_static_fini(%{{.+}}* @{{.+}}, i32 [[GTID]]) - g = 1; + { + g = 1; + sivar = 17; + } // Check for final copying of private values back to original vars. // BLOCKS: [[IS_LAST_VAL:%.+]] = load i32, i32* [[IS_LAST_ADDR]], // BLOCKS: [[IS_LAST_ITER:%.+]] = icmp ne i32 [[IS_LAST_VAL]], 0 @@ -144,6 +176,10 @@ // original g=private_g; // BLOCKS: [[G_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[G_PRIVATE_ADDR]], // BLOCKS: store volatile i{{[0-9]+}} [[G_VAL]], i{{[0-9]+}}* [[G]], + + // original sivar = private sivar; + // BLOCKS: [[SIVAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SIVAR_PRIVATE_ADDR]], + // BLOCKS: store i{{[0-9]+}} [[SIVAR_VAL]], i{{[0-9]+}}* [[REF]], // BLOCKS: br label %[[LAST_DONE]] // BLOCKS: [[LAST_DONE]] // BLOCKS: call i32 @__kmpc_cancel_barrier(%{{.+}}* @{{.+}}, i{{[0-9]+}} [[GTID]]) @@ -151,9 +187,13 @@ ^{ // BLOCKS: define {{.+}} void {{@.+}}(i8* g = 2; + sivar = 29; // BLOCKS-NOT: [[G]]{{[[^:word:]]}} // BLOCKS: store i{{[0-9]+}} 2, i{{[0-9]+}}* // BLOCKS-NOT: [[G]]{{[[^:word:]]}} + // BLOCKS-NOT: [[SIVAR]]{{[[^:word:]]}} + // BLOCKS: store i{{[0-9]+}} 29, i{{[0-9]+}}* + // BLOCKS-NOT: [[SIVAR]]{{[[^:word:]]}} // BLOCKS: ret }(); } @@ -166,11 +206,12 @@ S s_arr[] = {1, 2}; S var(3); #pragma omp parallel -#pragma omp sections lastprivate(t_var, vec, s_arr, var) +#pragma omp sections lastprivate(t_var, vec, s_arr, var, sivar) { { vec[0] = t_var; s_arr[0] = var; + sivar = 31; } } #pragma omp parallel @@ -209,6 +250,7 @@ // CHECK-DAG: getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 1 // CHECK-DAG: getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 2 // CHECK-DAG: getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 3 +// CHECK-DAG: getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 4 // @@ -309,6 +351,10 @@ // CHECK: [[S_ARR_BEGIN:%.+]] = getelementptr inbounds [2 x [[S_INT_TY]]], [2 x [[S_INT_TY]]]* [[S_ARR_REF]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 // CHECK: [[S_ARR_PRIV_BEGIN:%.+]] = bitcast [2 x [[S_INT_TY]]]* [[S_ARR_PRIV]] to [[S_INT_TY]]* // CHECK: [[S_ARR_END:%.+]] = getelementptr [[S_INT_TY]], [[S_INT_TY]]* [[S_ARR_BEGIN]], i{{[0-9]+}} 2 + +// CHK: [[SIVAR_REF:%.+]] = getelementptr [[S_INT_TY]], [[S_INT_TY]]* [[S_ARR_BEGIN]], i{{[0-9]+}} 4 +// CHK: store i{{[0-9]+}}* [[SIVAR]], i{{[0-9]+}} [[SIVAR_REF]] + // CHECK: [[IS_EMPTY:%.+]] = icmp eq [[S_INT_TY]]* [[S_ARR_BEGIN]], [[S_ARR_END]] // CHECK: br i1 [[IS_EMPTY]], label %[[S_ARR_BODY_DONE:.+]], label %[[S_ARR_BODY:.+]] // CHECK: [[S_ARR_BODY]] Index: test/OpenMP/sections_lastprivate_messages.cpp =================================================================== --- test/OpenMP/sections_lastprivate_messages.cpp +++ test/OpenMP/sections_lastprivate_messages.cpp @@ -314,5 +314,10 @@ { foo(); } + static int r; +#pragma omp sections lastprivate(r) // OK + { + foo(); + } return foomain(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain' requested here}} } Index: test/OpenMP/sections_private_codegen.cpp =================================================================== --- test/OpenMP/sections_private_codegen.cpp +++ test/OpenMP/sections_private_codegen.cpp @@ -41,6 +41,7 @@ } int main() { + static int sivar; #ifdef LAMBDA // LAMBDA: [[G:@.+]] = global double // LAMBDA-LABEL: @main @@ -49,16 +50,23 @@ // LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]]( // LAMBDA: call {{.*}}void {{.+}} @__kmpc_fork_call({{.+}}, i32 1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i8* %{{.+}}) #pragma omp parallel -#pragma omp sections private(g) +#pragma omp sections private(g, sivar) { // LAMBDA: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* %{{.+}}, i32* %{{.+}}, %{{.+}}* [[ARG:%.+]]) // LAMBDA: [[G_PRIVATE_ADDR:%.+]] = alloca double, + // LAMBDA: [[SIVAR_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, // LAMBDA: store %{{.+}}* [[ARG]], %{{.+}}** [[ARG_REF:%.+]], - g = 1; + { + g = 1; + sivar = 11; + } // LAMBDA: call {{.*}}void @__kmpc_for_static_init_4( // LAMBDA: store double 1.0{{.+}}, double* [[G_PRIVATE_ADDR]], + // LAMBDA: store i{{[0-9]+}} 11, i{{[0-9]+}}* [[SIVAR_PRIVATE_ADDR]], // LAMBDA: [[G_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 // LAMBDA: store double* [[G_PRIVATE_ADDR]], double** [[G_PRIVATE_ADDR_REF]] + // LAMBDA: [[SIVAR_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 1 + // LAMBDA: store i{{[0-9]+}}* [[SIVAR_PRIVATE_ADDR]], i{{[0-9]+}}** [[SIVAR_PRIVATE_ADDR_REF]] // LAMBDA: call{{.*}} void [[INNER_LAMBDA:@.+]](%{{.+}}* [[ARG]]) // LAMBDA: call {{.*}}void @__kmpc_for_static_fini( #pragma omp section @@ -66,10 +74,16 @@ // LAMBDA: define {{.+}} void [[INNER_LAMBDA]](%{{.+}}* [[ARG_PTR:%.+]]) // LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}** [[ARG_PTR_REF:%.+]], g = 2; + sivar = 22; // LAMBDA: [[ARG_PTR:%.+]] = load %{{.+}}*, %{{.+}}** [[ARG_PTR_REF]] + // LAMBDA: [[G_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 // LAMBDA: [[G_REF:%.+]] = load double*, double** [[G_PTR_REF]] // LAMBDA: store double 2.0{{.+}}, double* [[G_REF]] + + // LAMBDA: [[SIVAR_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 1 + // LAMBDA: [[SIVAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[SIVAR_PTR_REF]] + // LAMBDA: store i{{[0-9]+}} 22, i{{[0-9]+}}* [[SIVAR_REF]] }(); } }(); @@ -82,26 +96,38 @@ // BLOCKS: define{{.*}} internal{{.*}} void {{.+}}(i8* // BLOCKS: call {{.*}}void {{.+}} @__kmpc_fork_call({{.+}}, i32 1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i8* {{.+}}) #pragma omp parallel -#pragma omp sections private(g) +#pragma omp sections private(g, sivar) { // BLOCKS: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* %{{.+}}, i32* %{{.+}}, %{{.+}}* [[ARG:%.+]]) // BLOCKS: [[G_PRIVATE_ADDR:%.+]] = alloca double, + // BLOCKS: [[SIVAR_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, // BLOCKS: store %{{.+}}* [[ARG]], %{{.+}}** [[ARG_REF:%.+]], - g = 1; + { + g = 1; + sivar = 111; + } // BLOCKS: call {{.*}}void @__kmpc_for_static_init_4( // BLOCKS: store double 1.0{{.+}}, double* [[G_PRIVATE_ADDR]], + // BLOCKS: store i{{[0-9]+}} 111, i{{[0-9]+}}* [[SIVAR_PRIVATE_ADDR]], // BLOCKS-NOT: [[G]]{{[[^:word:]]}} // BLOCKS: double* [[G_PRIVATE_ADDR]] // BLOCKS-NOT: [[G]]{{[[^:word:]]}} + // BLOCKS-NOT: [[SIVAR]]{{[[^:word:]]}} + // BLOCKS: i{{[0-9]+}}* [[SIVAR_PRIVATE_ADDR]] + // BLOCKS-NOT: [[SIVAR]]{{[[^:word:]]}} // BLOCKS: call {{.*}}void {{%.+}}(i8 // BLOCKS: call {{.*}}void @__kmpc_for_static_fini( #pragma omp section ^{ // BLOCKS: define {{.+}} void {{@.+}}(i8* g = 2; + sivar = 222; // BLOCKS-NOT: [[G]]{{[[^:word:]]}} // BLOCKS: store double 2.0{{.+}}, double* // BLOCKS-NOT: [[G]]{{[[^:word:]]}} + // BLOCKS-NOT: [[SIVAR]]{{[[^:word:]]}} + // BLOCKS: store i{{[0-9]+}} 222, i{{[0-9]+}}* + // BLOCKS-NOT: [[SIVAR]]{{[[^:word:]]}} // BLOCKS: ret }(); } @@ -114,11 +140,12 @@ S s_arr[] = {1, 2}; S var(3); #pragma omp parallel -#pragma omp sections private(t_var, vec, s_arr, s_arr, var, var) +#pragma omp sections private(t_var, vec, s_arr, s_arr, var, var, sivar) { { vec[0] = t_var; s_arr[0] = var; + sivar = 2; } } return tmain(); @@ -140,11 +167,13 @@ // CHECK: [[S_ARR_PRIV:%.+]] = alloca [2 x [[S_FLOAT_TY]]], // CHECK-NOT: alloca [2 x [[S_FLOAT_TY]]], // CHECK: [[VAR_PRIV:%.+]] = alloca [[S_FLOAT_TY]], +// CHECK: [[SIVAR_PRIV:%.+]] = alloca i{{[0-9]+}}, // CHECK-NOT: alloca [[S_FLOAT_TY]], // CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_REF:%.+]] // CHECK: call i32 @__kmpc_single( // CHECK-NOT: [[T_VAR_PRIV]] // CHECK-NOT: [[VEC_PRIV]] +// CHECK-NOT: [[SIVAR_PRIV]] // CHECK: {{.+}}: // CHECK: [[S_ARR_PRIV_ITEM:%.+]] = phi [[S_FLOAT_TY]]* // CHECK: call {{.*}} [[S_FLOAT_TY_DEF_CONSTR]]([[S_FLOAT_TY]]* [[S_ARR_PRIV_ITEM]]) Index: test/OpenMP/sections_private_messages.cpp =================================================================== --- test/OpenMP/sections_private_messages.cpp +++ test/OpenMP/sections_private_messages.cpp @@ -206,6 +206,11 @@ { foo(); } + static int m; +#pragma omp sections private(m) + { + foo(); + } return 0; } Index: test/OpenMP/sections_reduction_messages.cpp =================================================================== --- test/OpenMP/sections_reduction_messages.cpp +++ test/OpenMP/sections_reduction_messages.cpp @@ -416,6 +416,11 @@ { foo(); } + static int m; +#pragma omp sections reduction(+ : m) // OK + { + foo(); + } return tmain(argc) + tmain(fl); // expected-note {{in instantiation of function template specialization 'tmain' requested here}} expected-note {{in instantiation of function template specialization 'tmain' requested here}} } Index: test/OpenMP/simd_lastprivate_messages.cpp =================================================================== --- test/OpenMP/simd_lastprivate_messages.cpp +++ test/OpenMP/simd_lastprivate_messages.cpp @@ -213,5 +213,9 @@ #pragma omp simd lastprivate(j) for (i = 0; i < argc; ++i) foo(); + static int t; +#pragma omp simd lastprivate(t) // OK + for (i = 0; i < argc; ++i) + foo(); return 0; } Index: test/OpenMP/single_firstprivate_codegen.cpp =================================================================== --- test/OpenMP/single_firstprivate_codegen.cpp +++ test/OpenMP/single_firstprivate_codegen.cpp @@ -64,6 +64,7 @@ // CHECK: call {{.*}} [[S_FLOAT_TY_DEF_CONSTR:@.+]]([[S_FLOAT_TY]]* [[TEST]]) // CHECK: ([[S_FLOAT_TY]]*)* [[S_FLOAT_TY_DESTR:@[^ ]+]] {{[^,]+}}, {{.+}}([[S_FLOAT_TY]]* [[TEST]] int main() { + static int sivar; #ifdef LAMBDA // LAMBDA: [[G:@.+]] = global i{{[0-9]+}} 1212, // LAMBDA-LABEL: @main @@ -72,17 +73,26 @@ // LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]]( // LAMBDA: call void {{.+}} @__kmpc_fork_call({{.+}}, i32 1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i8* %{{.+}}) #pragma omp parallel -#pragma omp single firstprivate(g) +#pragma omp single firstprivate(g, sivar) { - // LAMBDA: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* %{{.+}}, i32* %{{.+}}, %{{.+}}* [[ARG:%.+]]) + // LAMBDA: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* %{{.+}}, i32* %{{.+}}, [[CAP_MAIN_TY:%.+]]* [[ARG:%.+]]) // LAMBDA: [[G_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, + // LAMBDA: [[SIVAR_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, // LAMBDA: call i32 @__kmpc_single( // LAMBDA: [[G_VAL:%.+]] = load volatile i{{[0-9]+}}, i{{[0-9]+}}* [[G]] // LAMBDA: store i{{[0-9]+}} [[G_VAL]], i{{[0-9]+}}* [[G_PRIVATE_ADDR]] + // LAMBDA: [[SIVAR_PTR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 0 + // LAMBDA: [[SIVAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[SIVAR_PTR_REF]], + // LAMBDA: [[SIVAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SIVAR_REF]], + // LAMBDA: store i{{[0-9]+}} [[SIVAR_VAL]], i{{[0-9]+}}* [[SIVAR_PRIVATE_ADDR]], g = 1; + sivar = 17; // LAMBDA: store i{{[0-9]+}} 1, i{{[0-9]+}}* [[G_PRIVATE_ADDR]], + // LAMBDA: store i{{[0-9]+}} 17, i{{[0-9]+}}* [[SIVAR_PRIVATE_ADDR]], // LAMBDA: [[G_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 // LAMBDA: store i{{[0-9]+}}* [[G_PRIVATE_ADDR]], i{{[0-9]+}}** [[G_PRIVATE_ADDR_REF]] + // LAMBDA: [[SIVAR_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 1 + // LAMBDA: store i{{[0-9]+}}* [[SIVAR_PRIVATE_ADDR]], i{{[0-9]+}}** [[SIVAR_PRIVATE_ADDR_REF]] // LAMBDA: call void [[INNER_LAMBDA:@.+]](%{{.+}}* [[ARG]]) // LAMBDA: call void @__kmpc_end_single( // LAMBDA: call i32 @__kmpc_cancel_barrier( @@ -90,10 +100,14 @@ // LAMBDA: define {{.+}} void [[INNER_LAMBDA]](%{{.+}}* [[ARG_PTR:%.+]]) // LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}** [[ARG_PTR_REF:%.+]], g = 2; + sivar = 31; // LAMBDA: [[ARG_PTR:%.+]] = load %{{.+}}*, %{{.+}}** [[ARG_PTR_REF]] // LAMBDA: [[G_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 // LAMBDA: [[G_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[G_PTR_REF]] // LAMBDA: store i{{[0-9]+}} 2, i{{[0-9]+}}* [[G_REF]] + // LAMBDA: [[SIVAR_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 1 + // LAMBDA: [[SIVAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[SIVAR_PTR_REF]] + // LAMBDA: store i{{[0-9]+}} 31, i{{[0-9]+}}* [[SIVAR_REF]] }(); } }(); @@ -106,38 +120,53 @@ // BLOCKS: define{{.*}} internal{{.*}} void {{.+}}(i8* // BLOCKS: call void {{.+}} @__kmpc_fork_call({{.+}}, i32 1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i8* %{{.+}}) #pragma omp parallel -#pragma omp single firstprivate(g) +#pragma omp single firstprivate(g, sivar) { - // BLOCKS: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* %{{.+}}, i32* %{{.+}}, %{{.+}}* [[ARG:%.+]]) + // BLOCKS: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* %{{.+}}, i32* %{{.+}}, [[CAP_MAIN_TY:%.+]]* [[ARG:%.+]]) // BLOCKS: [[G_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, + // BLOCKS: [[SIVAR_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, // BLOCKS: call i32 @__kmpc_single( // BLOCKS: [[G_VAL:%.+]] = load volatile i{{[0-9]+}}, i{{[0-9]+}}* [[G]] // BLOCKS: store i{{[0-9]+}} [[G_VAL]], i{{[0-9]+}}* [[G_PRIVATE_ADDR]] + // BLOCKS: [[SIVAR_PTR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 0 + // BLOCKS: [[SIVAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[SIVAR_PTR_REF]], + // BLOCKS: [[SIVAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SIVAR_REF]], + // BLOCKS: store i{{[0-9]+}} [[SIVAR_VAL]], i{{[0-9]+}}* [[SIVAR_PRIVATE_ADDR]], g = 1; + sivar = 37; // BLOCKS: store i{{[0-9]+}} 1, i{{[0-9]+}}* [[G_PRIVATE_ADDR]], + // BLOCKS: store i{{[0-9]+}} 37, i{{[0-9]+}}* [[SIVAR_PRIVATE_ADDR]], // BLOCKS-NOT: [[G]]{{[[^:word:]]}} // BLOCKS: i{{[0-9]+}}* [[G_PRIVATE_ADDR]] // BLOCKS-NOT: [[G]]{{[[^:word:]]}} + // BLOCKS-NOT: [[SIVAR]]{{[[^:word:]]}} + // BLOCKS: i{{[0-9]+}}* [[SIVAR_PRIVATE_ADDR]] + // BLOCKS-NOT: [[SIVAR]]{{[[^:word:]]}} // BLOCKS: call void {{%.+}}(i8 // BLOCKS: call void @__kmpc_end_single( // BLOCKS: call i32 @__kmpc_cancel_barrier( ^{ // BLOCKS: define {{.+}} void {{@.+}}(i8* g = 2; + sivar = 31; // BLOCKS-NOT: [[G]]{{[[^:word:]]}} // BLOCKS: store i{{[0-9]+}} 2, i{{[0-9]+}}* // BLOCKS-NOT: [[G]]{{[[^:word:]]}} + // BLOCKS-NOT: [[SIVAR]]{{[[^:word:]]}} + // BLOCKS: store i{{[0-9]+}} 31, i{{[0-9]+}}* + // BLOCKS-NOT: [[SIVAR]]{{[[^:word:]]}} // BLOCKS: ret }(); } }(); return 0; #else -#pragma omp single firstprivate(t_var, vec, s_arr, var) nowait +#pragma omp single firstprivate(t_var, vec, s_arr, var, sivar) nowait { { vec[0] = t_var; s_arr[0] = var; + sivar = 41; } } return tmain(); @@ -151,6 +180,7 @@ // CHECK: [[VEC_PRIV:%.+]] = alloca [2 x i{{[0-9]+}}], // CHECK: [[S_ARR_PRIV:%.+]] = alloca [2 x [[S_FLOAT_TY]]], // CHECK: [[VAR_PRIV:%.+]] = alloca [[S_FLOAT_TY]], +// CHECK: [[SIVAR_PRIV:%.+]] = alloca i{{[0-9]+}}, // CHECK: call i32 @__kmpc_single( // firstprivate t_var(t_var) @@ -178,6 +208,10 @@ // CHECK: call {{.*}} [[S_FLOAT_TY_COPY_CONSTR]]([[S_FLOAT_TY]]* [[VAR_PRIV]], [[S_FLOAT_TY]]* {{.*}} [[VAR]], [[ST_TY]]* [[ST_TY_TEMP]]) // CHECK: call {{.*}} [[ST_TY_DESTR]]([[ST_TY]]* [[ST_TY_TEMP]]) +// firstprivate isvar +// CHEC: [[SIVAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SIVAR]], +// CHEC: store i{{[0-9]+}} [[SIVAR_VAL]], i{{[0-9]+}}* [[SIVAR_PRIV]], + // ~(firstprivate var), ~(firstprivate s_arr) // CHECK-DAG: call {{.*}} [[S_FLOAT_TY_DESTR]]([[S_FLOAT_TY]]* [[VAR_PRIV]]) // CHECK-DAG: call {{.*}} [[S_FLOAT_TY_DESTR]]([[S_FLOAT_TY]]* Index: test/OpenMP/single_firstprivate_messages.cpp =================================================================== --- test/OpenMP/single_firstprivate_messages.cpp +++ test/OpenMP/single_firstprivate_messages.cpp @@ -242,6 +242,9 @@ #pragma omp parallel reduction(+ : i) // expected-note {{defined as reduction}} #pragma omp single firstprivate(i) // expected-error {{firstprivate variable must be shared}} foo(); + static int t; +#pragma omp single firstprivate(t) // OK + foo(); return foomain(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain' requested here}} } Index: test/OpenMP/single_private_codegen.cpp =================================================================== --- test/OpenMP/single_private_codegen.cpp +++ test/OpenMP/single_private_codegen.cpp @@ -40,6 +40,7 @@ } int main() { + static int sivar; #ifdef LAMBDA // LAMBDA: [[G:@.+]] = global double // LAMBDA-LABEL: @main @@ -48,26 +49,35 @@ // LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]]( // LAMBDA: call {{.*}}void {{.+}} @__kmpc_fork_call({{.+}}, i32 1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i8* %{{.+}}) #pragma omp parallel -#pragma omp single private(g) +#pragma omp single private(g, sivar) { // LAMBDA: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* %{{.+}}, i32* %{{.+}}, %{{.+}}* [[ARG:%.+]]) // LAMBDA: [[G_PRIVATE_ADDR:%.+]] = alloca double, + // LAMBDA: [[SIVAR_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, // LAMBDA: store %{{.+}}* [[ARG]], %{{.+}}** [[ARG_REF:%.+]], g = 1; + sivar = 101; // LAMBDA: call {{.*}}i32 @__kmpc_single( // LAMBDA: store double 1.0{{.+}}, double* [[G_PRIVATE_ADDR]], + // LAMBDA: store i{{[0-9]+}} 101, i{{[0-9]+}}* [[SIVAR_PRIVATE_ADDR]], // LAMBDA: [[G_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 // LAMBDA: store double* [[G_PRIVATE_ADDR]], double** [[G_PRIVATE_ADDR_REF]] + // LAMBDA: [[SIVAR_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 1 + // LAMBDA: store i{{[0-9]+}}* [[SIVAR_PRIVATE_ADDR]], i{{[0-9]+}}** [[SIVAR_PRIVATE_ADDR_REF]] // LAMBDA: call{{.*}} void [[INNER_LAMBDA:@.+]](%{{.+}}* [[ARG]]) // LAMBDA: call {{.*}}void @__kmpc_end_single( [&]() { // LAMBDA: define {{.+}} void [[INNER_LAMBDA]](%{{.+}}* [[ARG_PTR:%.+]]) // LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}** [[ARG_PTR_REF:%.+]], g = 2; + sivar = 211; // LAMBDA: [[ARG_PTR:%.+]] = load %{{.+}}*, %{{.+}}** [[ARG_PTR_REF]] // LAMBDA: [[G_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 // LAMBDA: [[G_REF:%.+]] = load double*, double** [[G_PTR_REF]] // LAMBDA: store double 2.0{{.+}}, double* [[G_REF]] + // LAMBDA: [[SIVAR_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 1 + // LAMBDA: [[SIVAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[SIVAR_PTR_REF]] + // LAMBDA: store i{{[0-9]+}} 211, i{{[0-9]+}}* [[SIVAR_REF]] }(); } }(); @@ -80,25 +90,35 @@ // BLOCKS: define{{.*}} internal{{.*}} void {{.+}}(i8* // BLOCKS: call {{.*}}void {{.+}} @__kmpc_fork_call({{.+}}, i32 1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i8* {{.+}}) #pragma omp parallel -#pragma omp single private(g) +#pragma omp single private(g, sivar) { // BLOCKS: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* %{{.+}}, i32* %{{.+}}, %{{.+}}* [[ARG:%.+]]) // BLOCKS: [[G_PRIVATE_ADDR:%.+]] = alloca double, + // BLOCKS: [[SIVAR_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}}, // BLOCKS: store %{{.+}}* [[ARG]], %{{.+}}** [[ARG_REF:%.+]], g = 1; + sivar = 101; // BLOCKS: call {{.*}}i32 @__kmpc_single( // BLOCKS: store double 1.0{{.+}}, double* [[G_PRIVATE_ADDR]], + // BLOCKS: store i{{[0-9]+}} 101, i{{[0-9]+}}* [[SIVAR_PRIVATE_ADDR]], // BLOCKS-NOT: [[G]]{{[[^:word:]]}} // BLOCKS: double* [[G_PRIVATE_ADDR]] // BLOCKS-NOT: [[G]]{{[[^:word:]]}} + // BLOCKS-NOT: [[SIVAR]]{{[[^:word:]]}} + // BLOCKS: i{{[0-9]+}}* [[SIVAR_PRIVATE_ADDR]] + // BLOCKS-NOT: [[SIVAR]]{{[[^:word:]]}} // BLOCKS: call {{.*}}void {{%.+}}(i8 // BLOCKS: call {{.*}}void @__kmpc_end_single( ^{ // BLOCKS: define {{.+}} void {{@.+}}(i8* g = 2; + sivar = 203; // BLOCKS-NOT: [[G]]{{[[^:word:]]}} // BLOCKS: store double 2.0{{.+}}, double* // BLOCKS-NOT: [[G]]{{[[^:word:]]}} + // BLOCKS-NOT: [[SIVAR]]{{[[^:word:]]}} + // BLOCKS: store i{{[0-9]+}} 203, i{{[0-9]+}}* + // BLOCKS-NOT: [[SIVAR]]{{[[^:word:]]}} // BLOCKS: ret }(); } @@ -111,10 +131,11 @@ S s_arr[] = {1, 2}; S var(3); #pragma omp parallel -#pragma omp single private(t_var, vec, s_arr, s_arr, var, var) +#pragma omp single private(t_var, vec, s_arr, s_arr, var, var, sivar) { vec[0] = t_var; s_arr[0] = var; + sivar = 303; } return tmain(); #endif @@ -136,15 +157,18 @@ // CHECK-NOT: alloca [2 x [[S_FLOAT_TY]]], // CHECK: [[VAR_PRIV:%.+]] = alloca [[S_FLOAT_TY]], // CHECK-NOT: alloca [[S_FLOAT_TY]], +// CHECK: [[SIVAR_PRIV:%.+]] = alloca i{{[0-9]+}}, // CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_REF:%.+]] // CHECK: call i32 @__kmpc_single( // CHECK-NOT: [[T_VAR_PRIV]] // CHECK-NOT: [[VEC_PRIV]] +// CHECK-NOT: [[SIVAR_PRIV]] // CHECK: {{.+}}: // CHECK: [[S_ARR_PRIV_ITEM:%.+]] = phi [[S_FLOAT_TY]]* // CHECK: call {{.*}} [[S_FLOAT_TY_DEF_CONSTR]]([[S_FLOAT_TY]]* [[S_ARR_PRIV_ITEM]]) // CHECK-NOT: [[T_VAR_PRIV]] // CHECK-NOT: [[VEC_PRIV]] +// CHECK-NOT: [[SIVAR_PRIV]] // CHECK: call {{.*}} [[S_FLOAT_TY_DEF_CONSTR]]([[S_FLOAT_TY]]* [[VAR_PRIV]]) // CHECK-DAG: call void [[S_FLOAT_TY_DESTR]]([[S_FLOAT_TY]]* [[VAR_PRIV]]) // CHECK-DAG: call void [[S_FLOAT_TY_DESTR]]([[S_FLOAT_TY]]* Index: test/OpenMP/single_private_messages.cpp =================================================================== --- test/OpenMP/single_private_messages.cpp +++ test/OpenMP/single_private_messages.cpp @@ -142,6 +142,9 @@ foo(); #pragma omp single private(i) foo(); + static int m; +#pragma omp single private(m) // OK + foo(); return 0; } Index: test/OpenMP/task_firstprivate_codegen.cpp =================================================================== --- test/OpenMP/task_firstprivate_codegen.cpp +++ test/OpenMP/task_firstprivate_codegen.cpp @@ -26,7 +26,7 @@ // CHECK-DAG: [[KMP_TASK_T_TY:%.+]] = type { i8*, i32 (i32, i8*)*, i32, i32 (i32, i8*)* } // CHECK-DAG: [[S_DOUBLE_TY:%.+]] = type { double } -// CHECK-DAG: [[CAP_MAIN_TY:%.+]] = type { [2 x i32]*, i32*, [2 x [[S_DOUBLE_TY]]]*, [[S_DOUBLE_TY]]* } +// CHECK-DAG: [[CAP_MAIN_TY:%.+]] = type { [2 x i32]*, i32*, [2 x [[S_DOUBLE_TY]]]*, [[S_DOUBLE_TY]]*, i{{[0-9]+}}* } // CHECK-DAG: [[PRIVATES_MAIN_TY:%.+]] = type {{.?}}{ [[S_DOUBLE_TY]], [2 x [[S_DOUBLE_TY]]], i32, [2 x i32] // CHECK-DAG: [[KMP_TASK_MAIN_TY:%.+]] = type { [[KMP_TASK_T_TY]], [[PRIVATES_MAIN_TY]] } // CHECK-DAG: [[S_INT_TY:%.+]] = type { i32 } @@ -50,22 +50,31 @@ } int main() { + static int sivar; #ifdef LAMBDA // LAMBDA: [[G:@.+]] = global double + // LAMBDA: [[SIVAR:@.+]] = internal global i{{[0-9]+}} 0, // LAMBDA-LABEL: @main // LAMBDA: call{{( x86_thiscallcc)?}} void [[OUTER_LAMBDA:@.+]]( [&]() { // LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]]( - // LAMBDA: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc(%{{[^ ]+}} @{{[^,]+}}, i32 %{{[^,]+}}, i32 1, i64 40, i64 8, i32 (i32, i8*)* bitcast (i32 (i32, %{{[^*]+}}*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*)) + // LAMBDA: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc(%{{[^ ]+}} @{{[^,]+}}, i32 %{{[^,]+}}, i32 1, i64 48, i64 16, i32 (i32, i8*)* bitcast (i32 (i32, %{{[^*]+}}*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*)) // LAMBDA: [[PRIVATES:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i{{.+}} 0, i{{.+}} 1 // LAMBDA: [[G_PRIVATE_ADDR:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[PRIVATES]], i{{.+}} 0, i{{.+}} 0 // LAMBDA: [[G_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i{{.+}} 0, i{{.+}} 0 // LAMBDA: [[G_REF:%.+]] = load double*, double** [[G_ADDR_REF]] // LAMBDA: [[G_VAL:%.+]] = load volatile double, double* [[G_REF]] // LAMBDA: store volatile double [[G_VAL]], double* [[G_PRIVATE_ADDR]] + +// LAMBDA: [[SIVAR_PRIVATE_ADDR:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[PRIVATES]], i{{.+}} 0, i{{.+}} 1 +// LAMBDA: [[SIVAR_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i{{.+}} 0, i{{.+}} 1 +// LAMBDA: [[SIVAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[SIVAR_ADDR_REF]] +// LAMBDA: [[SIVAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SIVAR_REF]] +// LAMBDA: store i{{[0-9]+}} [[SIVAR_VAL]], i{{[0-9]+}}* [[SIVAR_PRIVATE_ADDR]] + // LAMBDA: call i32 @__kmpc_omp_task(%{{.+}}* @{{.+}}, i32 %{{.+}}, i8* [[RES]]) // LAMBDA: ret -#pragma omp task firstprivate(g) +#pragma omp task firstprivate(g, sivar) { // LAMBDA: define {{.+}} void [[INNER_LAMBDA:@.+]](%{{.+}}* [[ARG_PTR:%.+]]) // LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}** [[ARG_PTR_REF:%.+]], @@ -77,11 +86,14 @@ // LAMBDA: store double* %{{.+}}, double** %{{.+}}, // LAMBDA: define internal i32 [[TASK_ENTRY]](i32, %{{.+}}*) g = 1; + sivar = 11; // LAMBDA: store double 1.0{{.+}}, double* %{{.+}}, + // LAMBDA: store i{{[0-9]+}} 11, i{{[0-9]+}}* %{{.+}}, // LAMBDA: call void [[INNER_LAMBDA]](% // LAMBDA: ret [&]() { g = 2; + sivar = 22; }(); } }(); @@ -92,31 +104,45 @@ // BLOCKS: call void {{%.+}}(i8 ^{ // BLOCKS: define{{.*}} internal{{.*}} void {{.+}}(i8* - // BLOCKS: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc(%{{[^ ]+}} @{{[^,]+}}, i32 %{{[^,]+}}, i32 1, i64 40, i64 8, i32 (i32, i8*)* bitcast (i32 (i32, %{{[^*]+}}*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*)) + // BLOCKS: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc(%{{[^ ]+}} @{{[^,]+}}, i32 %{{[^,]+}}, i32 1, i64 48, i64 16, i32 (i32, i8*)* bitcast (i32 (i32, %{{[^*]+}}*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*)) // BLOCKS: [[PRIVATES:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i{{.+}} 0, i{{.+}} 1 // BLOCKS: [[G_PRIVATE_ADDR:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[PRIVATES]], i{{.+}} 0, i{{.+}} 0 // BLOCKS: [[G_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i{{.+}} 0, i{{.+}} 0 // BLOCKS: [[G_REF:%.+]] = load double*, double** [[G_ADDR_REF]] // BLOCKS: [[G_VAL:%.+]] = load volatile double, double* [[G_REF]] // BLOCKS: store volatile double [[G_VAL]], double* [[G_PRIVATE_ADDR]] + + // BLOCKS: [[SIVAR_PRIVATE_ADDR:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[PRIVATES]], i{{.+}} 0, i{{.+}} 1 + // BLOCKS: [[SIVAR_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i{{.+}} 0, i{{.+}} 1 + // BLOCKS: [[SIVAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[SIVAR_ADDR_REF]] + // BLOCKS: [[SIVAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SIVAR_REF]] + // BLOCKS: store i{{[0-9]+}} [[SIVAR_VAL]], i{{[0-9]+}}* [[SIVAR_PRIVATE_ADDR]] // BLOCKS: call i32 @__kmpc_omp_task(%{{.+}}* @{{.+}}, i32 %{{.+}}, i8* [[RES]]) // BLOCKS: ret -#pragma omp task firstprivate(g) +#pragma omp task firstprivate(g, sivar) { // BLOCKS: define {{.+}} void {{@.+}}(i8* // BLOCKS-NOT: [[G]]{{[[^:word:]]}} // BLOCKS: store double 2.0{{.+}}, double* // BLOCKS-NOT: [[G]]{{[[^:word:]]}} + // BLOCKS-NOT: [[ISVAR]]{{[[^:word:]]}} + // BLOCKS: store i{{[0-9]+}} 22, i{{[0-9]+}}* + // BLOCKS-NOT: [[SIVAR]]{{[[^:word:]]}} // BLOCKS: ret // BLOCKS: store double* %{{.+}}, double** %{{.+}}, + // BLOCKS: store i{{[0-9]+}}* %{{.+}}, i{{[0-9]+}}** %{{.+}}, // BLOCKS: define internal i32 [[TASK_ENTRY]](i32, %{{.+}}*) g = 1; + sivar = 11; // BLOCKS: store double 1.0{{.+}}, double* %{{.+}}, // BLOCKS-NOT: [[G]]{{[[^:word:]]}} + // BLOCKS: store i{{[0-9]+}} 11, i{{[0-9]+}}* %{{.+}}, + // BLOCKS-NOT: [[SIVAR]]{{[[^:word:]]}} // BLOCKS: call void {{%.+}}(i8 ^{ g = 2; + sivar = 22; }(); } }(); @@ -128,15 +154,17 @@ int vec[] = {1, 2}; S s_arr[] = {1, 2}; S var(3); -#pragma omp task firstprivate(var, t_var, s_arr, vec, s_arr, var) +#pragma omp task firstprivate(var, t_var, s_arr, vec, s_arr, var, sivar) { vec[0] = t_var; s_arr[0] = var; + sivar = 33; } return tmain(); #endif } +// CHECK: [[SIVAR:.+]] = internal global i{{[0-9]+}} 0, // CHECK: define i{{[0-9]+}} @main() // CHECK: alloca [[S_DOUBLE_TY]], // CHECK: [[TEST:%.+]] = alloca [[S_DOUBLE_TY]], @@ -157,13 +185,15 @@ // CHECK: store [2 x [[S_DOUBLE_TY]]]* [[S_ARR_ADDR]], [2 x [[S_DOUBLE_TY]]]** [[S_ARR_REF]], // CHECK: [[VAR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 3 // CHECK: store [[S_DOUBLE_TY]]* [[VAR_ADDR]], [[S_DOUBLE_TY]]** [[VAR_REF]], +// CHECK: [[SIVAR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* %{{.+}}, i{{[0-9]+}} 0, i{{[0-9]+}} 4 +// CHECK: store i{{[0-9]+}}* [[SIVAR]], i{{[0-9]+}}** [[SIVAR_REF]], // Allocate task. // Returns struct kmp_task_t { // [[KMP_TASK_T]] task_data; // [[KMP_TASK_MAIN_TY]] privates; // }; -// CHECK: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc([[LOC]], i32 [[GTID]], i32 1, i64 72, i64 32, i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_MAIN_TY]]*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*)) +// CHECK: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc([[LOC]], i32 [[GTID]], i32 1, i64 72, i64 40, i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_MAIN_TY]]*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*)) // CHECK: [[RES_KMP_TASK:%.+]] = bitcast i8* [[RES]] to [[KMP_TASK_MAIN_TY]]* // Fill kmp_task_t->shareds by copying from original capture argument. @@ -171,7 +201,7 @@ // CHECK: [[SHAREDS_REF_ADDR:%.+]] = getelementptr inbounds [[KMP_TASK_T_TY]], [[KMP_TASK_T_TY]]* [[TASK]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 // CHECK: [[SHAREDS_REF:%.+]] = load i8*, i8** [[SHAREDS_REF_ADDR]], // CHECK: [[CAPTURES_ADDR:%.+]] = bitcast [[CAP_MAIN_TY]]* %{{.+}} to i8* -// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[SHAREDS_REF]], i8* [[CAPTURES_ADDR]], i64 32, i32 8, i1 false) +// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[SHAREDS_REF]], i8* [[CAPTURES_ADDR]], i64 40, i32 8, i1 false) // Initialize kmp_task_t->privates with default values (no init for simple types, default constructors for classes). // Also copy address of private copy to the corresponding shareds reference. @@ -207,6 +237,13 @@ // CHECK: [[VEC_ADDR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* [[SHAREDS]], i{{.+}} 0, i{{.+}} 0 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64( +// sivar; +// CHECK: [[PRIVATE_SIVAR_REF:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i{{.+}} 0, i{{.+}} 4 +// CHECK: [[SIVAR_ADDR_REF:%.+]] = getelementptr inbounds [[CAP_MAIN_TY]], [[CAP_MAIN_TY]]* [[SHAREDS]], i{{.+}} 0, i{{.+}} 4 +// CHECK: [[SIVAR_REF:%.+]] = load i{{.+}}*, i{{.+}}** [[SIVAR_ADDR_REF]], +// CHECK: [[SIVAR:%.+]] = load i{{.+}}, i{{.+}}* [[SIVAR_REF]], +// CHECK: store i32 [[SIVAR]], i32* [[PRIVATE_SIVAR_REF]], + // Provide pointer to destructor function, which will destroy private variables at the end of the task. // CHECK: [[DESTRUCTORS_REF:%.+]] = getelementptr inbounds [[KMP_TASK_T_TY]], [[KMP_TASK_T_TY]]* [[TASK]], i{{.+}} 0, i{{.+}} 3 // CHECK: store i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_MAIN_TY]]*)* [[DESTRUCTORS:@.+]] to i32 (i32, i8*)*), i32 (i32, i8*)** [[DESTRUCTORS_REF]], @@ -225,7 +262,7 @@ // CHECK: ret // -// CHECK: define internal void [[PRIVATES_MAP_FN:@.+]]([[PRIVATES_MAIN_TY]]* noalias, [[S_DOUBLE_TY]]** noalias, i32** noalias, [2 x [[S_DOUBLE_TY]]]** noalias, [2 x i32]** noalias) +// CHECK: define internal void [[PRIVATES_MAP_FN:@.+]]([[PRIVATES_MAIN_TY]]* noalias, [[S_DOUBLE_TY]]** noalias, i32** noalias, [2 x [[S_DOUBLE_TY]]]** noalias, [2 x i32]** noalias, i32** noalias) // CHECK: [[PRIVATES:%.+]] = load [[PRIVATES_MAIN_TY]]*, [[PRIVATES_MAIN_TY]]** // CHECK: [[PRIV_VAR:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i32 0, i32 0 // CHECK: [[ARG1:%.+]] = load [[S_DOUBLE_TY]]**, [[S_DOUBLE_TY]]*** {{.+}}, @@ -239,6 +276,9 @@ // CHECK: [[PRIV_VEC:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i32 0, i32 3 // CHECK: [[ARG4:%.+]] = load [2 x i32]**, [2 x i32]*** %{{.+}}, // CHECK: store [2 x i32]* [[PRIV_VEC]], [2 x i32]** [[ARG4]], +// CHECK: [[PRIV_SIVAR:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i32 0, i32 4 +// CHECK: [[ARG5:%.+]] = load i{{[0-9]+}}**, i{{[0-9]+}}*** %{{.+}}, +// CHECK: store i{{[0-9]+}}* [[PRIV_SIVAR]], i{{[0-9]+}}** [[ARG5]], // CHECK: ret void // CHECK: define internal i32 [[TASK_ENTRY]](i32, [[KMP_TASK_MAIN_TY]]*) @@ -247,19 +287,24 @@ // CHECK: [[PRIV_T_VAR_ADDR:%.+]] = alloca i32*, // CHECK: [[PRIV_S_ARR_ADDR:%.+]] = alloca [2 x [[S_DOUBLE_TY]]]*, // CHECK: [[PRIV_VEC_ADDR:%.+]] = alloca [2 x i32]*, -// CHECK: store void (i8*, ...)* bitcast (void ([[PRIVATES_MAIN_TY]]*, [[S_DOUBLE_TY]]**, i32**, [2 x [[S_DOUBLE_TY]]]**, [2 x i32]**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), void (i8*, ...)** [[MAP_FN_ADDR:%.+]], +// CHECK: [[PRIV_SIVAR_ADDR:%.+]] = alloca i32*, +// CHECK: store void (i8*, ...)* bitcast (void ([[PRIVATES_MAIN_TY]]*, [[S_DOUBLE_TY]]**, i32**, [2 x [[S_DOUBLE_TY]]]**, [2 x i32]**, i32**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), void (i8*, ...)** [[MAP_FN_ADDR:%.+]], // CHECK: [[MAP_FN:%.+]] = load void (i8*, ...)*, void (i8*, ...)** [[MAP_FN_ADDR]], -// CHECK: call void (i8*, ...) [[MAP_FN]](i8* %{{.+}}, [[S_DOUBLE_TY]]** [[PRIV_VAR_ADDR]], i32** [[PRIV_T_VAR_ADDR]], [2 x [[S_DOUBLE_TY]]]** [[PRIV_S_ARR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]]) + +// CHECK: call void (i8*, ...) [[MAP_FN]](i8* %{{.+}}, [[S_DOUBLE_TY]]** [[PRIV_VAR_ADDR]], i32** [[PRIV_T_VAR_ADDR]], [2 x [[S_DOUBLE_TY]]]** [[PRIV_S_ARR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], i32** [[PRIV_SIVAR_ADDR]]) + // CHECK: [[PRIV_VAR:%.+]] = load [[S_DOUBLE_TY]]*, [[S_DOUBLE_TY]]** [[PRIV_VAR_ADDR]], // CHECK: [[PRIV_T_VAR:%.+]] = load i32*, i32** [[PRIV_T_VAR_ADDR]], // CHECK: [[PRIV_S_ARR:%.+]] = load [2 x [[S_DOUBLE_TY]]]*, [2 x [[S_DOUBLE_TY]]]** [[PRIV_S_ARR_ADDR]], // CHECK: [[PRIV_VEC:%.+]] = load [2 x i32]*, [2 x i32]** [[PRIV_VEC_ADDR]], +// CHECK: [[PRIV_SIVAR:%.+]] = load i32*, i32** [[PRIV_SIVAR_ADDR]], // Privates actually are used. // CHECK-DAG: [[PRIV_VAR]] // CHECK-DAG: [[PRIV_T_VAR]] // CHECK-DAG: [[PRIV_S_ARR]] // CHECK-DAG: [[PRIV_VEC]] +// CHECK-DAG: [[PRIV_SIVAR]] // CHECK: ret Index: test/OpenMP/task_firstprivate_messages.cpp =================================================================== --- test/OpenMP/task_firstprivate_messages.cpp +++ test/OpenMP/task_firstprivate_messages.cpp @@ -71,6 +71,7 @@ S5 g(5); int i; int &j = i; + static int m; #pragma omp task firstprivate // expected-error {{expected '(' after 'firstprivate'}} #pragma omp task firstprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} #pragma omp task firstprivate() // expected-error {{expected expression}} @@ -93,6 +94,7 @@ #pragma omp task shared(i) #pragma omp task firstprivate(i) #pragma omp task firstprivate(j) +#pragma omp task firstprivate(m) // OK foo(); return 0; Index: test/OpenMP/task_private_codegen.cpp =================================================================== --- test/OpenMP/task_private_codegen.cpp +++ test/OpenMP/task_private_codegen.cpp @@ -49,18 +49,20 @@ } int main() { + static int sivar; #ifdef LAMBDA // LAMBDA: [[G:@.+]] = global double // LAMBDA-LABEL: @main // LAMBDA: call{{( x86_thiscallcc)?}} void [[OUTER_LAMBDA:@.+]]( [&]() { // LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]]( - // LAMBDA: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc(%{{[^ ]+}} @{{[^,]+}}, i32 %{{[^,]+}}, i32 1, i64 40, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, %{{[^*]+}}*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*)) + // LAMBDA: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc(%{{[^ ]+}} @{{[^,]+}}, i32 %{{[^,]+}}, i32 1, i64 48, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, %{{[^*]+}}*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*)) // LAMBDA: [[PRIVATES:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i{{.+}} 0, i{{.+}} 1 // LAMBDA: [[G_PRIVATE_ADDR:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[PRIVATES]], i{{.+}} 0, i{{.+}} 0 +// LAMBDA: [[SIVAR_PRIVATE_ADDR:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[PRIVATES]], i{{.+}} 0, i{{.+}} 1 // LAMBDA: call i32 @__kmpc_omp_task(%{{.+}}* @{{.+}}, i32 %{{.+}}, i8* [[RES]]) // LAMBDA: ret -#pragma omp task private(g) +#pragma omp task private(g, sivar) { // LAMBDA: define {{.+}} void [[INNER_LAMBDA:@.+]](%{{.+}}* [[ARG_PTR:%.+]]) // LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}** [[ARG_PTR_REF:%.+]], @@ -68,14 +70,20 @@ // LAMBDA: [[G_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 // LAMBDA: [[G_REF:%.+]] = load double*, double** [[G_PTR_REF]] // LAMBDA: store double 2.0{{.+}}, double* [[G_REF]] + // LAMBDA: [[SIVAR_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 1 + // LAMBDA: [[SIVAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[SIVAR_PTR_REF]] + // LAMBDA: store i{{[0-9]+}} 3, i{{[0-9]+}}* [[SIVAR_REF]] // LAMBDA: define internal i32 [[TASK_ENTRY]](i32, %{{.+}}*) g = 1; + sivar = 2; // LAMBDA: store double 1.0{{.+}}, double* %{{.+}}, + // LAMBDA: store i{{[0-9]+}} 2, i{{[0-9]+}}* %{{.+}}, // LAMBDA: call void [[INNER_LAMBDA]](% // LAMBDA: ret [&]() { g = 2; + sivar = 3; }(); } }(); @@ -86,26 +94,34 @@ // BLOCKS: call void {{%.+}}(i8 ^{ // BLOCKS: define{{.*}} internal{{.*}} void {{.+}}(i8* - // BLOCKS: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc(%{{[^ ]+}} @{{[^,]+}}, i32 %{{[^,]+}}, i32 1, i64 40, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, %{{[^*]+}}*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*)) + // BLOCKS: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc(%{{[^ ]+}} @{{[^,]+}}, i32 %{{[^,]+}}, i32 1, i64 48, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, %{{[^*]+}}*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*)) // BLOCKS: [[PRIVATES:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i{{.+}} 0, i{{.+}} 1 // BLOCKS: [[G_PRIVATE_ADDR:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[PRIVATES]], i{{.+}} 0, i{{.+}} 0 + // BLOCKS: [[SIVAR_PRIVATE_ADDR:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[PRIVATES]], i{{.+}} 0, i{{.+}} 1 // BLOCKS: call i32 @__kmpc_omp_task(%{{.+}}* @{{.+}}, i32 %{{.+}}, i8* [[RES]]) // BLOCKS: ret -#pragma omp task private(g) +#pragma omp task private(g, sivar) { // BLOCKS: define {{.+}} void {{@.+}}(i8* // BLOCKS-NOT: [[G]]{{[[^:word:]]}} // BLOCKS: store double 2.0{{.+}}, double* // BLOCKS-NOT: [[G]]{{[[^:word:]]}} + // BLOCKS-NOT: [[SIVAR]]{{[[^:word:]]}} + // BLOCKS: store i{{[0-9]+}} 4, i{{[0-9]+}}* + // BLOCKS-NOT: [[SIVAR]]{{[[^:word:]]}} // BLOCKS: ret // BLOCKS: define internal i32 [[TASK_ENTRY]](i32, %{{.+}}*) g = 1; + sivar = 3; // BLOCKS: store double 1.0{{.+}}, double* %{{.+}}, // BLOCKS-NOT: [[G]]{{[[^:word:]]}} + // BLOCKS: store i{{[0-9]+}} 3, i{{[0-9]+}}* %{{.+}}, + // BLOCKS-NOT: [[SIVAR]]{{[[^:word:]]}} // BLOCKS: call void {{%.+}}(i8 ^{ g = 2; + sivar = 4; }(); } }(); @@ -116,10 +132,11 @@ int vec[] = {1, 2}; S s_arr[] = {1, 2}; S var(3); -#pragma omp task private(var, t_var, s_arr, vec, s_arr, var) +#pragma omp task private(var, t_var, s_arr, vec, s_arr, var, sivar) { vec[0] = t_var; s_arr[0] = var; + sivar = 8; } return tmain(); #endif @@ -183,7 +200,7 @@ // CHECK: ret // -// CHECK: define internal void [[PRIVATES_MAP_FN:@.+]]([[PRIVATES_MAIN_TY]]* noalias, [[S_DOUBLE_TY]]** noalias, i32** noalias, [2 x [[S_DOUBLE_TY]]]** noalias, [2 x i32]** noalias) +// CHECK: define internal void [[PRIVATES_MAP_FN:@.+]]([[PRIVATES_MAIN_TY]]* noalias, [[S_DOUBLE_TY]]** noalias, i32** noalias, [2 x [[S_DOUBLE_TY]]]** noalias, [2 x i32]** noalias, i32** noalias) // CHECK: [[PRIVATES:%.+]] = load [[PRIVATES_MAIN_TY]]*, [[PRIVATES_MAIN_TY]]** // CHECK: [[PRIV_VAR:%.+]] = getelementptr inbounds [[PRIVATES_MAIN_TY]], [[PRIVATES_MAIN_TY]]* [[PRIVATES]], i32 0, i32 0 // CHECK: [[ARG1:%.+]] = load [[S_DOUBLE_TY]]**, [[S_DOUBLE_TY]]*** {{.+}}, @@ -205,19 +222,22 @@ // CHECK: [[PRIV_T_VAR_ADDR:%.+]] = alloca i32*, // CHECK: [[PRIV_S_ARR_ADDR:%.+]] = alloca [2 x [[S_DOUBLE_TY]]]*, // CHECK: [[PRIV_VEC_ADDR:%.+]] = alloca [2 x i32]*, -// CHECK: store void (i8*, ...)* bitcast (void ([[PRIVATES_MAIN_TY]]*, [[S_DOUBLE_TY]]**, i32**, [2 x [[S_DOUBLE_TY]]]**, [2 x i32]**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), void (i8*, ...)** [[MAP_FN_ADDR:%.+]], +// CHECK: [[PRIV_SIVAR_ADDR:%.+]] = alloca i32*, +// CHECK: store void (i8*, ...)* bitcast (void ([[PRIVATES_MAIN_TY]]*, [[S_DOUBLE_TY]]**, i32**, [2 x [[S_DOUBLE_TY]]]**, [2 x i32]**, i32**)* [[PRIVATES_MAP_FN]] to void (i8*, ...)*), void (i8*, ...)** [[MAP_FN_ADDR:%.+]], // CHECK: [[MAP_FN:%.+]] = load void (i8*, ...)*, void (i8*, ...)** [[MAP_FN_ADDR]], -// CHECK: call void (i8*, ...) [[MAP_FN]](i8* %{{.+}}, [[S_DOUBLE_TY]]** [[PRIV_VAR_ADDR]], i32** [[PRIV_T_VAR_ADDR]], [2 x [[S_DOUBLE_TY]]]** [[PRIV_S_ARR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]]) +// CHECK: call void (i8*, ...) [[MAP_FN]](i8* %{{.+}}, [[S_DOUBLE_TY]]** [[PRIV_VAR_ADDR]], i32** [[PRIV_T_VAR_ADDR]], [2 x [[S_DOUBLE_TY]]]** [[PRIV_S_ARR_ADDR]], [2 x i32]** [[PRIV_VEC_ADDR]], i32** [[PRIV_SIVAR_ADDR]]) // CHECK: [[PRIV_VAR:%.+]] = load [[S_DOUBLE_TY]]*, [[S_DOUBLE_TY]]** [[PRIV_VAR_ADDR]], // CHECK: [[PRIV_T_VAR:%.+]] = load i32*, i32** [[PRIV_T_VAR_ADDR]], // CHECK: [[PRIV_S_ARR:%.+]] = load [2 x [[S_DOUBLE_TY]]]*, [2 x [[S_DOUBLE_TY]]]** [[PRIV_S_ARR_ADDR]], // CHECK: [[PRIV_VEC:%.+]] = load [2 x i32]*, [2 x i32]** [[PRIV_VEC_ADDR]], +// CHECK: [[PRIV_SIVAR:%.+]] = load i32*, i32** [[PRIV_SIVAR_ADDR]], // Privates actually are used. // CHECK-DAG: [[PRIV_VAR]] // CHECK-DAG: [[PRIV_T_VAR]] // CHECK-DAG: [[PRIV_S_ARR]] // CHECK-DAG: [[PRIV_VEC]] +// CHECK_DAG: [[PRIV_SIVAR]] // CHECK: ret Index: test/OpenMP/task_private_messages.cpp =================================================================== --- test/OpenMP/task_private_messages.cpp +++ test/OpenMP/task_private_messages.cpp @@ -93,6 +93,9 @@ #pragma omp task private(i) foo(); } + static int m; +#pragma omp task private(m) // OK + foo(); return 0; } Index: test/OpenMP/teams_firstprivate_messages.cpp =================================================================== --- test/OpenMP/teams_firstprivate_messages.cpp +++ test/OpenMP/teams_firstprivate_messages.cpp @@ -127,6 +127,10 @@ #pragma omp target #pragma omp teams firstprivate(j) foo(); + static int m; +#pragma omp target +#pragma omp teams firstprivate(m) // OK + foo(); return 0; } Index: test/OpenMP/teams_private_messages.cpp =================================================================== --- test/OpenMP/teams_private_messages.cpp +++ test/OpenMP/teams_private_messages.cpp @@ -122,6 +122,10 @@ #pragma omp parallel private(i) foo(); } + static int m; + #pragma omp target + #pragma omp teams private(m) // OK + foo(); return 0; } Index: test/OpenMP/teams_reduction_messages.cpp =================================================================== --- test/OpenMP/teams_reduction_messages.cpp +++ test/OpenMP/teams_reduction_messages.cpp @@ -310,6 +310,10 @@ #pragma omp target #pragma omp teams reduction(+ : fl) foo(); + static int m; +#pragma omp target +#pragma omp teams reduction(+ : m) // OK + foo(); return tmain(argc) + tmain(fl); // expected-note {{in instantiation of function template specialization 'tmain' requested here}} expected-note {{in instantiation of function template specialization 'tmain' requested here}} }