summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexey Bataev <a.bataev@hotmail.com>2019-09-18 19:24:07 +0000
committerAlexey Bataev <a.bataev@hotmail.com>2019-09-18 19:24:07 +0000
commitf71939c0995191bea1adca754e9b7e17f9c1572a (patch)
treead317c81cede7937082b13d21171aebbc831548e
parent164dbd386d00fe62991d3ab4e7b25b599f3fb7dc (diff)
downloadbcm5719-llvm-f71939c0995191bea1adca754e9b7e17f9c1572a.tar.gz
bcm5719-llvm-f71939c0995191bea1adca754e9b7e17f9c1572a.zip
[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. llvm-svn: 372252
-rw-r--r--clang/lib/CodeGen/CGStmtOpenMP.cpp16
-rw-r--r--clang/test/OpenMP/parallel_for_codegen.cpp6
2 files changed, 20 insertions, 2 deletions
diff --git a/clang/lib/CodeGen/CGStmtOpenMP.cpp b/clang/lib/CodeGen/CGStmtOpenMP.cpp
index 473c6f7950a..e34b820625c 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<const VarDecl *> EmittedAsPrivate;
for (const auto *E : S.counters()) {
const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(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<OMPPrivateClause>()) {
+ for (const Expr *IRef : C->varlists()) {
+ const auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(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<DeclStmt>(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 4329dd4f939..9e3390214d7 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) {
}
}
OpenPOWER on IntegriCloud