Index: lib/Transforms/Utils/BasicBlockUtils.cpp =================================================================== --- lib/Transforms/Utils/BasicBlockUtils.cpp +++ lib/Transforms/Utils/BasicBlockUtils.cpp @@ -119,7 +119,14 @@ 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(); Index: test/Transforms/SimplifyCFG/dce-cond-after-folding-terminator.ll =================================================================== --- test/Transforms/SimplifyCFG/dce-cond-after-folding-terminator.ll +++ test/Transforms/SimplifyCFG/dce-cond-after-folding-terminator.ll @@ -37,10 +37,7 @@ 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] Index: unittests/Transforms/Utils/BasicBlockUtils.cpp =================================================================== --- unittests/Transforms/Utils/BasicBlockUtils.cpp +++ unittests/Transforms/Utils/BasicBlockUtils.cpp @@ -50,3 +50,32 @@ 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, nullptr, nullptr, nullptr)); +}