From 358084ecfd0201984272d1dd69d3acad51154d02 Mon Sep 17 00:00:00 2001 From: Alexey Bataev Date: Wed, 18 Sep 2019 19:24:07 +0000 Subject: [PATCH] [OPENMP]Fix for PR43349: Crash for privatized loop bound. If the variable, used in the loop boundaries, is not captured in the construct, this variable must be considered as undefined if it was privatized. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@372252 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CGStmtOpenMP.cpp | 16 ++++++++++++++++ test/OpenMP/parallel_for_codegen.cpp | 6 ++++-- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/lib/CodeGen/CGStmtOpenMP.cpp b/lib/CodeGen/CGStmtOpenMP.cpp index 473c6f7950..e34b820625 100644 --- a/lib/CodeGen/CGStmtOpenMP.cpp +++ b/lib/CodeGen/CGStmtOpenMP.cpp @@ -120,11 +120,27 @@ public: class OMPLoopScope : public CodeGenFunction::RunCleanupsScope { void emitPreInitStmt(CodeGenFunction &CGF, const OMPLoopDirective &S) { CodeGenFunction::OMPMapVars PreCondVars; + llvm::DenseSet EmittedAsPrivate; for (const auto *E : S.counters()) { const auto *VD = cast(cast(E)->getDecl()); + EmittedAsPrivate.insert(VD->getCanonicalDecl()); (void)PreCondVars.setVarAddr( CGF, VD, CGF.CreateMemTemp(VD->getType().getNonReferenceType())); } + // Mark private vars as undefs. + for (const auto *C : S.getClausesOfKind()) { + for (const Expr *IRef : C->varlists()) { + const auto *OrigVD = cast(cast(IRef)->getDecl()); + if (EmittedAsPrivate.insert(OrigVD->getCanonicalDecl()).second) { + (void)PreCondVars.setVarAddr( + CGF, OrigVD, + Address(llvm::UndefValue::get( + CGF.ConvertTypeForMem(CGF.getContext().getPointerType( + OrigVD->getType().getNonReferenceType()))), + CGF.getContext().getDeclAlign(OrigVD))); + } + } + } (void)PreCondVars.apply(CGF); if (const auto *PreInits = cast_or_null(S.getPreInits())) { for (const auto *I : PreInits->decls()) diff --git a/test/OpenMP/parallel_for_codegen.cpp b/test/OpenMP/parallel_for_codegen.cpp index 4329dd4f93..9e3390214d 100644 --- a/test/OpenMP/parallel_for_codegen.cpp +++ b/test/OpenMP/parallel_for_codegen.cpp @@ -35,12 +35,14 @@ void with_var_schedule() { // CHECK: [[CHUNK:%.+]] = load i64, i64* % // CHECK: call void {{.+}} @__kmpc_fork_call({{.+}}, i64 [[CHUNK]]) +// CHECK: [[UNDEF_A:%.+]] = load double, double* undef +// CHECK: fadd double 2.000000e+00, [[UNDEF_A]] // CHECK: [[CHUNK_VAL:%.+]] = load i8, i8* % // CHECK: [[CHUNK_SIZE:%.+]] = sext i8 [[CHUNK_VAL]] to i64 // CHECK: call void @__kmpc_for_static_init_8u([[IDENT_T_TY]]* [[LOOP_LOC]], i32 [[GTID:%[^,]+]], i32 33, i32* [[IS_LAST:%[^,]+]], i64* [[OMP_LB:%[^,]+]], i64* [[OMP_UB:%[^,]+]], i64* [[OMP_ST:%[^,]+]], i64 1, i64 [[CHUNK_SIZE]]) // CHECK: call void @__kmpc_for_static_fini([[IDENT_T_TY]]* [[LOOP_LOC]], i32 [[GTID]]) -#pragma omp parallel for schedule(static, char(a)) - for (unsigned long long i = 1; i < 2; ++i) { +#pragma omp parallel for schedule(static, char(a)) private(a) + for (unsigned long long i = 1; i < 2 + a; ++i) { } } -- 2.40.0