From 414afdf940e8473db4156d0c1bc500ec527f1a1f Mon Sep 17 00:00:00 2001 From: Alexey Bataev Date: Thu, 14 May 2020 16:37:30 -0400 Subject: [PATCH] [OPENMP]Fix PR45911: Data sharing and lambda capture. Summary: No need to generate inlined OpenMP region for variables captured in lambdas or block decls, only for implicitly captured variables in the OpenMP region. Reviewers: jdoerfert Subscribers: yaxunl, guansong, cfe-commits, caomhin Tags: #clang Differential Revision: https://reviews.llvm.org/D79966 --- clang/lib/CodeGen/CGOpenMPRuntime.cpp | 7 ++++++- clang/test/OpenMP/task_firstprivate_codegen.cpp | 12 ++++++++++-- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/clang/lib/CodeGen/CGOpenMPRuntime.cpp b/clang/lib/CodeGen/CGOpenMPRuntime.cpp index 549d864..6a724ca 100644 --- a/clang/lib/CodeGen/CGOpenMPRuntime.cpp +++ b/clang/lib/CodeGen/CGOpenMPRuntime.cpp @@ -4836,11 +4836,16 @@ static void emitPrivatesInit(CodeGenFunction &CGF, C.getDeclAlign(OriginalVD)), SharedRefLValue.getType(), LValueBaseInfo(AlignmentSource::Decl), SharedRefLValue.getTBAAInfo()); + } else if (CGF.LambdaCaptureFields.count( + Pair.second.Original->getCanonicalDecl()) > 0 || + dyn_cast_or_null(CGF.CurCodeDecl)) { + SharedRefLValue = CGF.EmitLValue(Pair.second.OriginalRef); } else { + // Processing for implicitly captured variables. InlinedOpenMPRegionRAII Region( CGF, [](CodeGenFunction &, PrePostActionTy &) {}, OMPD_unknown, /*HasCancel=*/false); - SharedRefLValue = CGF.EmitLValue(Pair.second.OriginalRef); + SharedRefLValue = CGF.EmitLValue(Pair.second.OriginalRef); } if (Type->isArrayType()) { // Initialize firstprivate array. diff --git a/clang/test/OpenMP/task_firstprivate_codegen.cpp b/clang/test/OpenMP/task_firstprivate_codegen.cpp index 079c342..d5d495e 100644 --- a/clang/test/OpenMP/task_firstprivate_codegen.cpp +++ b/clang/test/OpenMP/task_firstprivate_codegen.cpp @@ -56,6 +56,7 @@ T tmain() { int main() { static int sivar; + float local = 0; #ifdef LAMBDA // LAMBDA: [[G:@.+]] = global double // LAMBDA: [[SIVAR:@.+]] = internal global i{{[0-9]+}} 0, @@ -73,9 +74,12 @@ int main() { // LAMBDA: [[SIVAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SIVAR]], // LAMBDA: store i{{[0-9]+}} [[SIVAR_VAL]], i{{[0-9]+}}* [[SIVAR_PRIVATE_ADDR]] +// LAMBDA: [[LOCAL_PRIVATE_ADDR:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[PRIVATES]], i{{.+}} 0, i{{.+}} 2 +// LAMBDA: store float %{{.+}}, float* [[LOCAL_PRIVATE_ADDR]] + // LAMBDA: call i32 @__kmpc_omp_task(%{{.+}}* @{{.+}}, i32 %{{.+}}, i8* [[RES]]) // LAMBDA: ret -#pragma omp task firstprivate(g, sivar) +#pragma omp task firstprivate(g, sivar, local) { // LAMBDA: define {{.+}} void [[INNER_LAMBDA:@.+]](%{{.+}}* [[ARG_PTR:%.+]]) // LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}** [[ARG_PTR_REF:%.+]], @@ -115,9 +119,13 @@ int main() { // BLOCKS: [[SIVAR_PRIVATE_ADDR:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[PRIVATES]], i{{.+}} 0, i{{.+}} 1 // BLOCKS: [[SIVAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SIVAR]], // BLOCKS: store i{{[0-9]+}} [[SIVAR_VAL]], i{{[0-9]+}}* [[SIVAR_PRIVATE_ADDR]], + + // BLOCKS: [[LOCAL_PRIVATE_ADDR:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[PRIVATES]], i{{.+}} 0, i{{.+}} 2 + // BLOCKS: store float %{{.+}}, float* [[LOCAL_PRIVATE_ADDR]] + // BLOCKS: call i32 @__kmpc_omp_task(%{{.+}}* @{{.+}}, i32 %{{.+}}, i8* [[RES]]) // BLOCKS: ret -#pragma omp task firstprivate(g, sivar) +#pragma omp task firstprivate(g, sivar, local) { // BLOCKS: define {{.+}} void {{@.+}}(i8* // BLOCKS-NOT: [[G]]{{[[^:word:]]}} -- 2.7.4