Index: lib/Transforms/Utils/LoopUtils.cpp =================================================================== --- lib/Transforms/Utils/LoopUtils.cpp +++ lib/Transforms/Utils/LoopUtils.cpp @@ -68,6 +68,12 @@ IsDedicatedExit = false; } + // Remove duplicate pred blocks (ex: switch pred with duplicate edges) + std::sort(InLoopPredecessors.begin(), InLoopPredecessors.end()); + auto LastPred = + std::unique(InLoopPredecessors.begin(), InLoopPredecessors.end()); + InLoopPredecessors.erase(LastPred, InLoopPredecessors.end()); + assert(!InLoopPredecessors.empty() && "Must have *some* loop predecessor!"); // Nothing to do if this is already a dedicated exit. 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