From: Tobias Grosser Date: Wed, 23 Mar 2016 06:57:51 +0000 (+0000) Subject: Codegen:Do not invalidate dominator tree when bailing out during code generation X-Git-Tag: llvmorg-3.9.0-rc1~11172 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=bfb6a9683bd9b9812ee58af2181d190b07e7221c;p=platform%2Fupstream%2Fllvm.git Codegen:Do not invalidate dominator tree when bailing out during code generation When codegenerating invariant loads in some rare cases we cannot generate code and bail out. This change ensures that we maintain a valid dominator tree in these situations. This fixes llvm.org/PR26736 Contributed-by: Matthias Reisinger llvm-svn: 264142 --- diff --git a/polly/lib/CodeGen/CodeGeneration.cpp b/polly/lib/CodeGen/CodeGeneration.cpp index d66ff94..ec10b3e 100644 --- a/polly/lib/CodeGen/CodeGeneration.cpp +++ b/polly/lib/CodeGen/CodeGeneration.cpp @@ -110,6 +110,17 @@ public: } } + /// @brief Mark a basic block unreachable. + /// + /// Marks the basic block @p Block unreachable by equipping it with an + /// UnreachableInst. + void markBlockUnreachable(BasicBlock &Block, PollyIRBuilder &Builder) { + auto *OrigTerminator = Block.getTerminator(); + Builder.SetInsertPoint(OrigTerminator); + Builder.CreateUnreachable(); + OrigTerminator->eraseFromParent(); + } + /// @brief Generate LLVM-IR for the SCoP @p S. bool runOnScop(Scop &S) override { AI = &getAnalysis(); @@ -146,7 +157,7 @@ public: // code generating this scop. BasicBlock *StartBlock = executeScopConditionally(S, this, Builder.getTrue()); - auto SplitBlock = StartBlock->getSinglePredecessor(); + auto *SplitBlock = StartBlock->getSinglePredecessor(); // First generate code for the hoisted invariant loads and transitively the // parameters they reference. Afterwards, for the remaining parameters that @@ -156,15 +167,26 @@ public: Builder.SetInsertPoint(SplitBlock->getTerminator()); if (!NodeBuilder.preloadInvariantLoads()) { + // Patch the introduced branch condition to ensure that we always execute + // the original SCoP. auto *FalseI1 = Builder.getFalse(); auto *SplitBBTerm = Builder.GetInsertBlock()->getTerminator(); SplitBBTerm->setOperand(0, FalseI1); - auto *StartBBTerm = StartBlock->getTerminator(); - Builder.SetInsertPoint(StartBBTerm); - Builder.CreateUnreachable(); - StartBBTerm->eraseFromParent(); - isl_ast_node_free(AstRoot); + // Since the other branch is hence ignored we mark it as unreachable and + // adjust the dominator tree accordingly. + auto *ExitingBlock = StartBlock->getUniqueSuccessor(); + assert(ExitingBlock); + auto *MergeBlock = ExitingBlock->getUniqueSuccessor(); + assert(MergeBlock); + markBlockUnreachable(*StartBlock, Builder); + markBlockUnreachable(*ExitingBlock, Builder); + auto *ExitingBB = R->getExitingBlock(); + assert(ExitingBB); + DT->changeImmediateDominator(MergeBlock, ExitingBB); + DT->eraseNode(ExitingBlock); + + isl_ast_node_free(AstRoot); } else { NodeBuilder.addParameters(S.getContext()); diff --git a/polly/test/Isl/CodeGen/stack-overflow-in-load-hoisting.ll b/polly/test/Isl/CodeGen/stack-overflow-in-load-hoisting.ll index 9534b72..e43baca 100644 --- a/polly/test/Isl/CodeGen/stack-overflow-in-load-hoisting.ll +++ b/polly/test/Isl/CodeGen/stack-overflow-in-load-hoisting.ll @@ -1,4 +1,4 @@ -; RUN: opt %loadPolly -polly-codegen -S < %s | FileCheck %s +; RUN: opt %loadPolly -verify-dom-info -polly-codegen -S < %s | FileCheck %s ; ; This caused an infinite recursion during invariant load hoisting at some ; point. Check it does not and we add a "false" runtime check.