Author: Roman Lebedev Date: 2020-12-18T00:37:22+03:00 New Revision: 2d07414ee5f74a09fb89723b4a9bb0818bdc2e18
URL: https://github.com/llvm/llvm-project/commit/2d07414ee5f74a09fb89723b4a9bb0818bdc2e18 DIFF: https://github.com/llvm/llvm-project/commit/2d07414ee5f74a09fb89723b4a9bb0818bdc2e18.diff LOG: [SimplifyCFG] Teach simplifyUnreachable() to preserve DomTree Pretty boring, removeUnwindEdge() already known how to update DomTree, so if we are to call it, we must first flush our own pending updates; otherwise, we just stop predecessors from branching to us, and for certain predecessors, stop their predecessors from branching to them also. Added: Modified: llvm/lib/Transforms/Utils/SimplifyCFG.cpp llvm/test/Transforms/CallSiteSplitting/split-loop.ll llvm/test/Transforms/LoopDeletion/2008-05-06-Phi.ll llvm/test/Transforms/SimplifyCFG/UnreachableEliminate.ll llvm/test/Transforms/SimplifyCFG/X86/PR30210.ll llvm/test/Transforms/SimplifyCFG/branch-fold.ll llvm/test/Transforms/SimplifyCFG/empty-catchpad.ll llvm/test/Transforms/SimplifyCFG/invoke_unwind_lifetime.ll llvm/test/Transforms/SimplifyCFG/switch-profmd.ll llvm/test/Transforms/SimplifyCFG/switch-range-to-icmp.ll llvm/test/Transforms/SimplifyCFG/unreachable_assume.ll llvm/test/Transforms/SimplifyCFG/wineh-unreachable.ll Removed: ################################################################################ diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp index 9e4650fefff7..6a0859d84c89 100644 --- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp +++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp @@ -4479,9 +4479,12 @@ bool SimplifyCFGOpt::simplifyUnreachable(UnreachableInst *UI) { if (&BB->front() != UI) return Changed; + std::vector<DominatorTree::UpdateType> Updates; + SmallVector<BasicBlock *, 8> Preds(pred_begin(BB), pred_end(BB)); for (unsigned i = 0, e = Preds.size(); i != e; ++i) { - Instruction *TI = Preds[i]->getTerminator(); + auto *Predecessor = Preds[i]; + Instruction *TI = Predecessor->getTerminator(); IRBuilder<> Builder(TI); if (auto *BI = dyn_cast<BranchInst>(TI)) { if (BI->isUnconditional()) { @@ -4491,6 +4494,9 @@ bool SimplifyCFGOpt::simplifyUnreachable(UnreachableInst *UI) { Changed = true; } else { Value* Cond = BI->getCondition(); + assert(BI->getSuccessor(0) != BI->getSuccessor(1) && + "Same-destination conditional branch instruction was " + "already canonicalized into an unconditional branch."); if (BI->getSuccessor(0) == BB) { Builder.CreateAssumption(Builder.CreateNot(Cond)); Builder.CreateBr(BI->getSuccessor(1)); @@ -4502,6 +4508,7 @@ bool SimplifyCFGOpt::simplifyUnreachable(UnreachableInst *UI) { EraseTerminatorAndDCECond(BI); Changed = true; } + Updates.push_back({DominatorTree::Delete, Predecessor, BB}); } else if (auto *SI = dyn_cast<SwitchInst>(TI)) { SwitchInstProfUpdateWrapper SU(*SI); for (auto i = SU->case_begin(), e = SU->case_end(); i != e;) { @@ -4514,14 +4521,21 @@ bool SimplifyCFGOpt::simplifyUnreachable(UnreachableInst *UI) { e = SU->case_end(); Changed = true; } + Updates.push_back({DominatorTree::Delete, Predecessor, BB}); } else if (auto *II = dyn_cast<InvokeInst>(TI)) { if (II->getUnwindDest() == BB) { - removeUnwindEdge(TI->getParent()); + if (DTU) + DTU->applyUpdatesPermissive(Updates); + Updates.clear(); + removeUnwindEdge(TI->getParent(), DTU); Changed = true; } } else if (auto *CSI = dyn_cast<CatchSwitchInst>(TI)) { if (CSI->getUnwindDest() == BB) { - removeUnwindEdge(TI->getParent()); + if (DTU) + DTU->applyUpdatesPermissive(Updates); + Updates.clear(); + removeUnwindEdge(TI->getParent(), DTU); Changed = true; continue; } @@ -4536,35 +4550,54 @@ bool SimplifyCFGOpt::simplifyUnreachable(UnreachableInst *UI) { Changed = true; } } + Updates.push_back({DominatorTree::Delete, Predecessor, BB}); if (CSI->getNumHandlers() == 0) { - BasicBlock *CatchSwitchBB = CSI->getParent(); if (CSI->hasUnwindDest()) { - // Redirect preds to the unwind dest - CatchSwitchBB->replaceAllUsesWith(CSI->getUnwindDest()); + // Redirect all predecessors of the block containing CatchSwitchInst + // to instead branch to the CatchSwitchInst's unwind destination. + for (auto *PredecessorOfPredecessor : predecessors(Predecessor)) { + Updates.push_back( + {DominatorTree::Delete, PredecessorOfPredecessor, Predecessor}); + Updates.push_back({DominatorTree::Insert, PredecessorOfPredecessor, + CSI->getUnwindDest()}); + } + Predecessor->replaceAllUsesWith(CSI->getUnwindDest()); } else { // Rewrite all preds to unwind to caller (or from invoke to call). - SmallVector<BasicBlock *, 8> EHPreds(predecessors(CatchSwitchBB)); + if (DTU) + DTU->applyUpdatesPermissive(Updates); + Updates.clear(); + SmallVector<BasicBlock *, 8> EHPreds(predecessors(Predecessor)); for (BasicBlock *EHPred : EHPreds) - removeUnwindEdge(EHPred); + removeUnwindEdge(EHPred, DTU); } // The catchswitch is no longer reachable. new UnreachableInst(CSI->getContext(), CSI); CSI->eraseFromParent(); Changed = true; } - } else if (isa<CleanupReturnInst>(TI)) { + } else if (auto *CRI = dyn_cast<CleanupReturnInst>(TI)) { + assert(CRI->hasUnwindDest() && CRI->getUnwindDest() == BB && + "Expected to always have an unwind to BB."); + Updates.push_back({DominatorTree::Delete, Predecessor, BB}); new UnreachableInst(TI->getContext(), TI); TI->eraseFromParent(); Changed = true; } } + if (DTU) + DTU->applyUpdatesPermissive(Updates); + // If this block is now dead, remove it. if (pred_empty(BB) && BB != &BB->getParent()->getEntryBlock()) { // We know there are no successors, so just nuke the block. if (LoopHeaders) LoopHeaders->erase(BB); - BB->eraseFromParent(); + if (DTU) + DTU->deleteBB(BB); + else + BB->eraseFromParent(); return true; } diff --git a/llvm/test/Transforms/CallSiteSplitting/split-loop.ll b/llvm/test/Transforms/CallSiteSplitting/split-loop.ll index 1e71643b7b9e..0c65e724c8a7 100644 --- a/llvm/test/Transforms/CallSiteSplitting/split-loop.ll +++ b/llvm/test/Transforms/CallSiteSplitting/split-loop.ll @@ -1,5 +1,5 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py -; RUN: opt -S -callsite-splitting -simplifycfg < %s | FileCheck %s +; RUN: opt -S -callsite-splitting -simplifycfg -simplifycfg-require-and-preserve-domtree=1 < %s | FileCheck %s define i16 @test1() { ; CHECK-LABEL: @test1( diff --git a/llvm/test/Transforms/LoopDeletion/2008-05-06-Phi.ll b/llvm/test/Transforms/LoopDeletion/2008-05-06-Phi.ll index f5f7970566cb..79170e6615b7 100644 --- a/llvm/test/Transforms/LoopDeletion/2008-05-06-Phi.ll +++ b/llvm/test/Transforms/LoopDeletion/2008-05-06-Phi.ll @@ -1,4 +1,4 @@ -; RUN: opt < %s -inline -instcombine -jump-threading -licm -simple-loop-unswitch -instcombine -indvars -loop-deletion -gvn -simplifycfg -verify -disable-output +; RUN: opt < %s -inline -instcombine -jump-threading -licm -simple-loop-unswitch -instcombine -indvars -loop-deletion -gvn -simplifycfg -simplifycfg-require-and-preserve-domtree=1 -verify -disable-output target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128" target triple = "i386-apple-darwin9" @@ -18,7 +18,7 @@ target triple = "i386-apple-darwin9" @scaleFactorsPH = external global [2 x [2 x %struct.BF_PartHolder*]] ; <[2 x [2 x %struct.BF_PartHolder*]]*> [#uses=1] @slen1_tab = external constant [16 x i32] ; <[16 x i32]*> [#uses=1] -declare %struct.BF_PartHolder* @BF_addElement(%struct.BF_PartHolder*, %struct.BF_BitstreamElement*) nounwind +declare %struct.BF_PartHolder* @BF_addElement(%struct.BF_PartHolder*, %struct.BF_BitstreamElement*) nounwind define %struct.BF_PartHolder* @BF_addEntry(%struct.BF_PartHolder* %thePH, i32 %value, i32 %length) nounwind { entry: @@ -38,7 +38,7 @@ bb13: ; preds = %entry define void @III_format_bitstream(%struct.lame_global_flags* %gfp, i32 %bitsPerFrame, [2 x [576 x i32]]* %l3_enc, %struct.III_side_info_t* %l3_side, [2 x %struct.III_scalefac_t]* %scalefac, %struct.Bit_stream_struc* %in_bs) nounwind { entry: - call fastcc void @encodeMainData( %struct.lame_global_flags* %gfp, [2 x [576 x i32]]* %l3_enc, %struct.III_side_info_t* %l3_side, [2 x %struct.III_scalefac_t]* %scalefac ) nounwind + call fastcc void @encodeMainData( %struct.lame_global_flags* %gfp, [2 x [576 x i32]]* %l3_enc, %struct.III_side_info_t* %l3_side, [2 x %struct.III_scalefac_t]* %scalefac ) nounwind unreachable } diff --git a/llvm/test/Transforms/SimplifyCFG/UnreachableEliminate.ll b/llvm/test/Transforms/SimplifyCFG/UnreachableEliminate.ll index c8f59d4bd9ae..4ec8fe7e68f8 100644 --- a/llvm/test/Transforms/SimplifyCFG/UnreachableEliminate.ll +++ b/llvm/test/Transforms/SimplifyCFG/UnreachableEliminate.ll @@ -1,5 +1,5 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py -; RUN: opt < %s -simplifycfg -S | FileCheck %s +; RUN: opt < %s -simplifycfg -simplifycfg-require-and-preserve-domtree=1 -S | FileCheck %s define void @test1(i1 %C, i1* %BP) { ; CHECK-LABEL: @test1( diff --git a/llvm/test/Transforms/SimplifyCFG/X86/PR30210.ll b/llvm/test/Transforms/SimplifyCFG/X86/PR30210.ll index bc422ddcd5f6..8704bcf005ea 100644 --- a/llvm/test/Transforms/SimplifyCFG/X86/PR30210.ll +++ b/llvm/test/Transforms/SimplifyCFG/X86/PR30210.ll @@ -1,5 +1,5 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py -; RUN: opt -S -simplifycfg < %s | FileCheck %s +; RUN: opt -S -simplifycfg -simplifycfg-require-and-preserve-domtree=1 < %s | FileCheck %s target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu" diff --git a/llvm/test/Transforms/SimplifyCFG/branch-fold.ll b/llvm/test/Transforms/SimplifyCFG/branch-fold.ll index 7097dea424e1..a4ac23bada70 100644 --- a/llvm/test/Transforms/SimplifyCFG/branch-fold.ll +++ b/llvm/test/Transforms/SimplifyCFG/branch-fold.ll @@ -1,4 +1,4 @@ -; RUN: opt < %s -simplifycfg -S | FileCheck %s +; RUN: opt < %s -simplifycfg -simplifycfg-require-and-preserve-domtree=1 -S | FileCheck %s define void @test(i32* %P, i32* %Q, i1 %A, i1 %B) { ; CHECK: test diff --git a/llvm/test/Transforms/SimplifyCFG/empty-catchpad.ll b/llvm/test/Transforms/SimplifyCFG/empty-catchpad.ll index 2926cd3f7dc7..6e9141568df6 100644 --- a/llvm/test/Transforms/SimplifyCFG/empty-catchpad.ll +++ b/llvm/test/Transforms/SimplifyCFG/empty-catchpad.ll @@ -1,4 +1,4 @@ -; RUN: opt < %s -simplifycfg -S | FileCheck %s +; RUN: opt < %s -simplifycfg -simplifycfg-require-and-preserve-domtree=1 -S | FileCheck %s declare void @f() declare void @llvm.foo(i32) nounwind diff --git a/llvm/test/Transforms/SimplifyCFG/invoke_unwind_lifetime.ll b/llvm/test/Transforms/SimplifyCFG/invoke_unwind_lifetime.ll index a498976c10f8..c758826dc435 100644 --- a/llvm/test/Transforms/SimplifyCFG/invoke_unwind_lifetime.ll +++ b/llvm/test/Transforms/SimplifyCFG/invoke_unwind_lifetime.ll @@ -1,5 +1,5 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py -; RUN: opt < %s -simplifycfg -S | FileCheck %s +; RUN: opt < %s -simplifycfg -simplifycfg-require-and-preserve-domtree=1 -S | FileCheck %s declare void @llvm.lifetime.start.p0i8(i64, i8*) declare void @llvm.lifetime.end.p0i8(i64, i8*) diff --git a/llvm/test/Transforms/SimplifyCFG/switch-profmd.ll b/llvm/test/Transforms/SimplifyCFG/switch-profmd.ll index c17214e18f20..3f8f5716604a 100644 --- a/llvm/test/Transforms/SimplifyCFG/switch-profmd.ll +++ b/llvm/test/Transforms/SimplifyCFG/switch-profmd.ll @@ -1,4 +1,4 @@ -; RUN: opt -S -simplifycfg < %s | FileCheck %s +; RUN: opt -S -simplifycfg -simplifycfg-require-and-preserve-domtree=1 < %s | FileCheck %s declare i32 @f(i32 %val) diff --git a/llvm/test/Transforms/SimplifyCFG/switch-range-to-icmp.ll b/llvm/test/Transforms/SimplifyCFG/switch-range-to-icmp.ll index d99e84b6b940..7125575b2f33 100644 --- a/llvm/test/Transforms/SimplifyCFG/switch-range-to-icmp.ll +++ b/llvm/test/Transforms/SimplifyCFG/switch-range-to-icmp.ll @@ -1,5 +1,5 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py -; RUN: opt %s -simplifycfg -S | FileCheck %s +; RUN: opt %s -simplifycfg -simplifycfg-require-and-preserve-domtree=1 -S | FileCheck %s declare i32 @f(i32) diff --git a/llvm/test/Transforms/SimplifyCFG/unreachable_assume.ll b/llvm/test/Transforms/SimplifyCFG/unreachable_assume.ll index e0d1e27a9952..2eb7f4da1d8a 100644 --- a/llvm/test/Transforms/SimplifyCFG/unreachable_assume.ll +++ b/llvm/test/Transforms/SimplifyCFG/unreachable_assume.ll @@ -1,5 +1,5 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py -; RUN: opt %s -simplifycfg -instcombine -S | FileCheck %s +; RUN: opt %s -simplifycfg -simplifycfg-require-and-preserve-domtree=1 -instcombine -S | FileCheck %s define i32 @assume1(i32 %p) { ; CHECK-LABEL: @assume1( diff --git a/llvm/test/Transforms/SimplifyCFG/wineh-unreachable.ll b/llvm/test/Transforms/SimplifyCFG/wineh-unreachable.ll index 7655fa7875f2..c951294233ff 100644 --- a/llvm/test/Transforms/SimplifyCFG/wineh-unreachable.ll +++ b/llvm/test/Transforms/SimplifyCFG/wineh-unreachable.ll @@ -1,4 +1,4 @@ -; RUN: opt -S -simplifycfg < %s | FileCheck %s +; RUN: opt -S -simplifycfg -simplifycfg-require-and-preserve-domtree=1 < %s | FileCheck %s declare void @Personality() declare void @f() _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits