From 9534232b8132447e646b94751fc9e32ada373c5b Mon Sep 17 00:00:00 2001 From: Xin Tong Date: Mon, 18 Jun 2018 22:59:13 +0000 Subject: [PATCH] Simplify blockaddress usage before giving up in MergeBlockIntoPredecessor Summary: Simplify blockaddress usage before giving up in MergeBlockIntoPredecessor This is a missing small optimization in MergeBlockIntoPredecessor. This helps with one simplifycfg test which expects this case to be handled. Reviewers: davide, spatel, brzycki, asbirlea Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D48284 llvm-svn: 334992 --- lib/Transforms/Utils/BasicBlockUtils.cpp | 9 +++++- .../dce-cond-after-folding-terminator.ll | 5 +--- .../Transforms/Utils/BasicBlockUtils.cpp | 28 +++++++++++++++++++ 3 files changed, 37 insertions(+), 5 deletions(-) diff --git a/lib/Transforms/Utils/BasicBlockUtils.cpp b/lib/Transforms/Utils/BasicBlockUtils.cpp index 59837042550..4b89b0435e0 100644 --- a/lib/Transforms/Utils/BasicBlockUtils.cpp +++ b/lib/Transforms/Utils/BasicBlockUtils.cpp @@ -119,7 +119,14 @@ bool llvm::MergeBlockIntoPredecessor(BasicBlock *BB, DominatorTree *DT, LoopInfo *LI, MemoryDependenceResults *MemDep) { // Don't merge away blocks who have their address taken. - if (BB->hasAddressTaken()) return false; + if (BB->hasAddressTaken()) { + // If the block has its address taken, it may be a tree of dead constants + // hanging off of it. These shouldn't keep the block alive. + BlockAddress *BA = BlockAddress::get(BB); + BA->removeDeadConstantUsers(); + if (!BA->use_empty()) + return false; + } // Can't merge if there are multiple predecessors, or no predecessors. BasicBlock *PredBB = BB->getUniquePredecessor(); diff --git a/test/Transforms/SimplifyCFG/dce-cond-after-folding-terminator.ll b/test/Transforms/SimplifyCFG/dce-cond-after-folding-terminator.ll index 036a615e7ff..a15cdd6a28f 100644 --- a/test/Transforms/SimplifyCFG/dce-cond-after-folding-terminator.ll +++ b/test/Transforms/SimplifyCFG/dce-cond-after-folding-terminator.ll @@ -37,10 +37,7 @@ define void @test_indirectbr(i32 %x) { entry: ; CHECK-LABEL: @test_indirectbr( ; CHECK-NEXT: entry: -; Ideally this should now check: -; CHK-NEXT: ret void -; But that doesn't happen yet. Instead: -; CHECK-NEXT: br label %L1 +; CHECK-NEXT: ret void %label = bitcast i8* blockaddress(@test_indirectbr, %L1) to i8* indirectbr i8* %label, [label %L1, label %L2] diff --git a/unittests/Transforms/Utils/BasicBlockUtils.cpp b/unittests/Transforms/Utils/BasicBlockUtils.cpp index 2d0a9302011..590e7f6ada6 100644 --- a/unittests/Transforms/Utils/BasicBlockUtils.cpp +++ b/unittests/Transforms/Utils/BasicBlockUtils.cpp @@ -50,3 +50,31 @@ TEST(BasicBlockUtils, SplitBlockPredecessors) { SplitBlockPredecessors(&F->getEntryBlock(), {}, "split.entry", &DT); EXPECT_TRUE(DT.verify()); } + +TEST(BasicBlockUtils, MergeBlockIntoPredecessor) { + LLVMContext C; + std::unique_ptr M = parseIR(C, + R"( + + define i32 @f(i8* %str) { + entry: + %dead = extractvalue [1 x i8*] [ i8* blockaddress(@f, %L0) ], 0 + br label %L0 + L0: + ret i32 0 + } + )"); + + // First remove the dead instruction to empty the usage of the constant + // containing blockaddress(@f, %L0) + Function *F = M->getFunction("f"); + auto BBI = F->begin(); + Instruction *DI = &*((*BBI).begin()); + EXPECT_TRUE(DI->use_empty()); + DI->eraseFromParent(); + + // Get L0 and make sure that it can be merged into entry block. + ++BBI; + BasicBlock *BB = &(*BBI); + EXPECT_TRUE(MergeBlockIntoPredecessor(BB)); +}