diff --git a/lib/Transforms/Scalar/LICM.cpp b/lib/Transforms/Scalar/LICM.cpp index dcbf2d42c54..f039692e201 100644 --- a/lib/Transforms/Scalar/LICM.cpp +++ b/lib/Transforms/Scalar/LICM.cpp @@ -244,8 +244,16 @@ struct LegacyLICMPass : public LoopPass { using llvm::Pass::doFinalization; bool doFinalization() override { - assert(LICM.getLoopToAliasSetMap().empty() && + auto &AliasSetMap = LICM.getLoopToAliasSetMap(); + // All loops in the AliasSetMap should be cleaned up already. The only case + // where we fail to do so is if an outer loop gets deleted before LICM + // visits it. + assert(all_of(AliasSetMap, + [](LoopInvariantCodeMotion::ASTrackerMapTy::value_type &KV) { + return !KV.first->getParentLoop(); + }) && "Didn't free loop alias sets"); + AliasSetMap.clear(); return false; } diff --git a/test/Transforms/LICM/outer-loop-deleted-before-licm.ll b/test/Transforms/LICM/outer-loop-deleted-before-licm.ll new file mode 100644 index 00000000000..1865ed32ecb --- /dev/null +++ b/test/Transforms/LICM/outer-loop-deleted-before-licm.ll @@ -0,0 +1,46 @@ +; RUN: opt %s -S -loop-unroll -licm | FileCheck %s + +; Check that we can deal with loops where a parent loop gets deleted before it +; is visited by LICM. +define void @test() { +; CHECK-LABEL: define void @test() { +; CHECK-LABEL: entry: +; CHECK-NEXT: br label %for.body43 + +; CHECK-LABEL: for.body43: ; preds = %entry +; CHECK-NEXT: br label %if.else75 + +; CHECK-LABEL: if.else75: ; preds = %for.body43 +; CHECK-NEXT: br label %for.body467 + +; CHECK-LABEL: for.body467: ; preds = %for.body467.for.body467_crit_edge, %if.else75 +; CHECK-NEXT: br label %for.body467.for.body467_crit_edge + +; CHECK-LABEL: for.body467.for.body467_crit_edge: ; preds = %for.body467 +; CHECK-NEXT: br i1 false, label %for.end539, label %for.body467 + +; CHECK-LABEL: for.end539: ; preds = %for.body467.for.body467_crit_edge +; CHECK-NEXT: ret void +; + +entry: + br label %for.body43 + +for.body43: ; preds = %for.end539, %entry + br label %if.else75 + +if.else75: ; preds = %for.body43 + br label %for.body467 + +for.body467: ; preds = %for.body467.for.body467_crit_edge, %if.else75 + br label %for.body467.for.body467_crit_edge + +for.body467.for.body467_crit_edge: ; preds = %for.body467 + br i1 false, label %for.end539, label %for.body467 + +for.end539: ; preds = %for.body467 + br i1 undef, label %for.body43, label %for.end547 + +for.end547: ; preds = %for.body43 + ret void +}