From 6e8248fdad5fc59306beb286a3089fe401460826 Mon Sep 17 00:00:00 2001 From: Alexey Bataev Date: Thu, 11 Jun 2015 10:53:56 +0000 Subject: [PATCH] [OPENMP] Fox for http://llvm.org/PR23663: OpenMP crash Destroy RuntimeCleanupScope before generation of termination instruction in parallel loop precondition. llvm-svn: 239524 --- clang/lib/CodeGen/CGStmtOpenMP.cpp | 50 +++++++++++----------- clang/test/OpenMP/parallel_for_codegen.cpp | 10 ++++- 2 files changed, 34 insertions(+), 26 deletions(-) diff --git a/clang/lib/CodeGen/CGStmtOpenMP.cpp b/clang/lib/CodeGen/CGStmtOpenMP.cpp index 07fc6e966af6..895baa72a7d3 100644 --- a/clang/lib/CodeGen/CGStmtOpenMP.cpp +++ b/clang/lib/CodeGen/CGStmtOpenMP.cpp @@ -647,30 +647,32 @@ static void EmitPrivateLoopCounters(CodeGenFunction &CGF, static void emitPreCond(CodeGenFunction &CGF, const OMPLoopDirective &S, const Expr *Cond, llvm::BasicBlock *TrueBlock, llvm::BasicBlock *FalseBlock, uint64_t TrueCount) { - CodeGenFunction::OMPPrivateScope PreCondScope(CGF); - EmitPrivateLoopCounters(CGF, PreCondScope, S.counters()); - const VarDecl *IVDecl = - cast(cast(S.getIterationVariable())->getDecl()); - bool IsRegistered = PreCondScope.addPrivate(IVDecl, [&]() -> llvm::Value *{ - // Emit var without initialization. - auto VarEmission = CGF.EmitAutoVarAlloca(*IVDecl); - CGF.EmitAutoVarCleanups(VarEmission); - return VarEmission.getAllocatedAddress(); - }); - assert(IsRegistered && "counter already registered as private"); - // Silence the warning about unused variable. - (void)IsRegistered; - (void)PreCondScope.Privatize(); - // Initialize internal counter to 0 to calculate initial values of real - // counters. - LValue IV = CGF.EmitLValue(S.getIterationVariable()); - CGF.EmitStoreOfScalar( - llvm::ConstantInt::getNullValue( - IV.getAddress()->getType()->getPointerElementType()), - CGF.EmitLValue(S.getIterationVariable()), /*isInit=*/true); - // Get initial values of real counters. - for (auto I : S.updates()) { - CGF.EmitIgnoredExpr(I); + { + CodeGenFunction::OMPPrivateScope PreCondScope(CGF); + EmitPrivateLoopCounters(CGF, PreCondScope, S.counters()); + const VarDecl *IVDecl = + cast(cast(S.getIterationVariable())->getDecl()); + bool IsRegistered = PreCondScope.addPrivate(IVDecl, [&]() -> llvm::Value *{ + // Emit var without initialization. + auto VarEmission = CGF.EmitAutoVarAlloca(*IVDecl); + CGF.EmitAutoVarCleanups(VarEmission); + return VarEmission.getAllocatedAddress(); + }); + assert(IsRegistered && "counter already registered as private"); + // Silence the warning about unused variable. + (void)IsRegistered; + (void)PreCondScope.Privatize(); + // Initialize internal counter to 0 to calculate initial values of real + // counters. + LValue IV = CGF.EmitLValue(S.getIterationVariable()); + CGF.EmitStoreOfScalar( + llvm::ConstantInt::getNullValue( + IV.getAddress()->getType()->getPointerElementType()), + CGF.EmitLValue(S.getIterationVariable()), /*isInit=*/true); + // Get initial values of real counters. + for (auto I : S.updates()) { + CGF.EmitIgnoredExpr(I); + } } // Check that loop is executed at least one time. CGF.EmitBranchOnBoolExpr(Cond, TrueBlock, FalseBlock, TrueCount); diff --git a/clang/test/OpenMP/parallel_for_codegen.cpp b/clang/test/OpenMP/parallel_for_codegen.cpp index 43bf83269655..6262e761e0da 100644 --- a/clang/test/OpenMP/parallel_for_codegen.cpp +++ b/clang/test/OpenMP/parallel_for_codegen.cpp @@ -2,6 +2,7 @@ // RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -emit-pch -o %t %s // RUN: %clang_cc1 -fopenmp -x c++ -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s // RUN: %clang_cc1 -verify -triple x86_64-apple-darwin10 -fopenmp -fexceptions -fcxx-exceptions -gline-tables-only -x c++ -emit-llvm %s -o - | FileCheck %s --check-prefix=TERM_DEBUG +// RUN: %clang_cc1 -verify -triple x86_64-apple-darwin10 -O1 -fopenmp -emit-llvm %s -o - | FileCheck %s --check-prefix=CLEANUP // // expected-no-diagnostics #ifndef HEADER @@ -376,6 +377,7 @@ void runtime(float *a, float *b, float *c, float *d) { int foo() {return 0;}; // TERM_DEBUG-LABEL: parallel_for +// CLEANUP: parallel_for void parallel_for(float *a) { #pragma omp parallel for schedule(static, 5) // TERM_DEBUG-NOT: __kmpc_global_thread_num @@ -388,13 +390,17 @@ void parallel_for(float *a) { // TERM_DEBUG: [[TERM_LPAD]] // TERM_DEBUG: call void @__clang_call_terminate // TERM_DEBUG: unreachable + // CLEANUP-NOT: __kmpc_global_thread_num + // CLEANUP: call void @__kmpc_for_static_init_4u({{.+}}) + // CLEANUP: call void @__kmpc_for_static_fini({{.+}}) + // CLEANUP: call {{.+}} @__kmpc_cancel_barrier({{.+}}) for (unsigned i = 131071; i <= 2147483647; i += 127) a[i] += foo(); } // Check source line corresponds to "#pragma omp parallel for schedule(static, 5)" above: // TERM_DEBUG-DAG: [[DBG_LOC_START]] = !DILocation(line: [[@LINE-4]], -// TERM_DEBUG-DAG: [[DBG_LOC_END]] = !DILocation(line: [[@LINE-16]], -// TERM_DEBUG-DAG: [[DBG_LOC_CANCEL]] = !DILocation(line: [[@LINE-17]], +// TERM_DEBUG-DAG: [[DBG_LOC_END]] = !DILocation(line: [[@LINE-20]], +// TERM_DEBUG-DAG: [[DBG_LOC_CANCEL]] = !DILocation(line: [[@LINE-21]], #endif // HEADER