diff --git a/clang/lib/CodeGen/CGStmtOpenMP.cpp b/clang/lib/CodeGen/CGStmtOpenMP.cpp index 473c6f7950ae..e34b820625c2 100644 --- a/clang/lib/CodeGen/CGStmtOpenMP.cpp +++ b/clang/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/clang/test/OpenMP/parallel_for_codegen.cpp b/clang/test/OpenMP/parallel_for_codegen.cpp index 4329dd4f9398..9e3390214d78 100644 --- a/clang/test/OpenMP/parallel_for_codegen.cpp +++ b/clang/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) { } }