Index: lib/Transforms/Utils/LoopUtils.cpp =================================================================== --- lib/Transforms/Utils/LoopUtils.cpp +++ lib/Transforms/Utils/LoopUtils.cpp @@ -55,18 +55,24 @@ auto Cleanup = make_scope_exit([&] { InLoopPredecessors.clear(); }); // See if there are any non-loop predecessors of this exit block and - // keep track of the in-loop predecessors. + // keep track of the unique in-loop predecessors. bool IsDedicatedExit = true; + SmallPtrSet PushedBlocks; for (auto *PredBB : predecessors(BB)) if (L->contains(PredBB)) { if (isa(PredBB->getTerminator())) // We cannot rewrite exiting edges from an indirectbr. return false; - InLoopPredecessors.push_back(PredBB); + // Switch-like insts may have duplicate edges. + if (!PushedBlocks.count(PredBB)) { + InLoopPredecessors.push_back(PredBB); + PushedBlocks.insert(PredBB); + } } else { IsDedicatedExit = false; } + PushedBlocks.clear(); assert(!InLoopPredecessors.empty() && "Must have *some* loop predecessor!"); Index: test/Transforms/LoopSimplify/preserve-llvm-loop-metadata2.ll =================================================================== --- test/Transforms/LoopSimplify/preserve-llvm-loop-metadata2.ll +++ test/Transforms/LoopSimplify/preserve-llvm-loop-metadata2.ll @@ -10,7 +10,10 @@ ; CHECK: outer.header.loopexit: ; CHECK-NEXT: llvm.loop [[UJAMTAG:.*]] -; CHECK-NOT: br i1 {{.*}}, label {{.*}}, label %outer.header.loopexit, !llvm.loop +; CHECK: switch {{.*}}, label %inner.body [ +; CHECK-NEXT: i64 0, label %outer.header.loopexit +; CHECK-NEXT: i64 1, label %outer.header.loopexit +; CHECK-NOT: ], !llvm.loop ; CHECK: br label %inner.header, !llvm.loop [[UNROLLTAG:.*]] ; CHECK: distinct !{[[UJAMTAG]], [[UJAM:.*]]} @@ -23,8 +26,8 @@ entry: br label %outer.header -outer.header: ; preds = %inner.header, %entry - %ii.0 = phi i64 [ 2, %entry ], [ %add, %inner.header ] +outer.header: ; preds = %entry, %inner.header, %inner.header + %ii.0 = phi i64 [ 0, %entry ], [ %add, %inner.header ], [ %add, %inner.header ] %cmp = icmp ult i64 %ii.0, 64 br i1 %cmp, label %inner.header, label %outer.header.cleanup @@ -34,8 +37,12 @@ inner.header: ; preds = %outer.header, %inner.body %j.0 = phi i64 [ %add10, %inner.body ], [ %ii.0, %outer.header ] %add = add nuw nsw i64 %ii.0, 16 - %cmp2 = icmp ult i64 %j.0, %add - br i1 %cmp2, label %inner.body, label %outer.header, !llvm.loop !2 + %sub = sub i64 %add, %j.0 +; corner case: latch to outer loop is switch with duplicate edges + switch i64 %sub, label %inner.body [ + i64 0, label %outer.header + i64 1, label %outer.header + ], !llvm.loop !2 inner.body: ; preds = %inner.header %add10 = add nuw nsw i64 %j.0, 1