Index: llvm/lib/Transforms/Scalar/ADCE.cpp =================================================================== --- llvm/lib/Transforms/Scalar/ADCE.cpp +++ llvm/lib/Transforms/Scalar/ADCE.cpp @@ -182,7 +182,7 @@ /// Identify connected sections of the control flow graph which have /// dead terminators and rewrite the control flow graph to remove them. - void updateDeadRegions(); + bool updateDeadRegions(); /// Set the BlockInfo::PostOrder field based on a post-order /// numbering of the reverse control flow graph. @@ -505,7 +505,7 @@ //===----------------------------------------------------------------------===// bool AggressiveDeadCodeElimination::removeDeadInstructions() { // Updates control and dataflow around dead blocks - updateDeadRegions(); + bool RegionsUpdated = updateDeadRegions(); LLVM_DEBUG({ for (Instruction &I : instructions(F)) { @@ -556,11 +556,11 @@ I->eraseFromParent(); } - return !Worklist.empty(); + return !Worklist.empty() || RegionsUpdated; } // A dead region is the set of dead blocks with a common live post-dominator. -void AggressiveDeadCodeElimination::updateDeadRegions() { +bool AggressiveDeadCodeElimination::updateDeadRegions() { LLVM_DEBUG({ dbgs() << "final dead terminator blocks: " << '\n'; for (auto *BB : BlocksWithDeadTerminators) @@ -570,6 +570,7 @@ // Don't compute the post ordering unless we needed it. bool HavePostOrder = false; + bool Changed = false; for (auto *BB : BlocksWithDeadTerminators) { auto &Info = BlockInfo[BB]; @@ -624,7 +625,10 @@ .applyUpdates(DeletedEdges); NumBranchesRemoved += 1; + Changed = true; } + + return Changed; } // reverse top-sort order @@ -685,10 +689,14 @@ return PreservedAnalyses::all(); PreservedAnalyses PA; - PA.preserveSet(); + // TODO: We could track if we have actually done CFG changes. + if (!RemoveControlFlowFlag) + PA.preserveSet(); + else { + PA.preserve(); + PA.preserve(); + } PA.preserve(); - PA.preserve(); - PA.preserve(); return PA; } Index: llvm/test/Transforms/ADCE/broken-loop-info.ll =================================================================== --- llvm/test/Transforms/ADCE/broken-loop-info.ll +++ llvm/test/Transforms/ADCE/broken-loop-info.ll @@ -1,17 +1,24 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt -licm -adce -licm -S < %s | FileCheck %s ; RUN: opt -passes='loop(licm),adce,loop(licm)' -S < %s | FileCheck %s ; -; XFAIL: * -; REQUIRES: asserts -; -; This test demonstrates a bug in ADCE's work with loop info. It does some -; changes that make loop's block unreachable, but never bothers to update -; loop info accordingly. target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128-ni:1-p2:32:8:8:32-ni:2" target triple = "x86_64-unknown-linux-gnu" define void @test() { -; CHECK-LABEL: test +; CHECK-LABEL: @test( +; CHECK-NEXT: bb: +; CHECK-NEXT: br label [[BB2:%.*]] +; CHECK: bb1: +; CHECK-NEXT: ret void +; CHECK: bb2: +; CHECK-NEXT: br label [[BB4:%.*]] +; CHECK: bb3: +; CHECK-NEXT: unreachable +; CHECK: bb4: +; CHECK-NEXT: br i1 true, label [[BB1:%.*]], label [[BB2]] +; bb: br label %bb2