diff --git a/llvm/lib/Analysis/LoopNestAnalysis.cpp b/llvm/lib/Analysis/LoopNestAnalysis.cpp --- a/llvm/lib/Analysis/LoopNestAnalysis.cpp +++ b/llvm/lib/Analysis/LoopNestAnalysis.cpp @@ -210,7 +210,7 @@ assert(From && "Expecting valid From"); assert(End && "Expecting valid End"); - if (From == End || !From->getSingleSuccessor()) + if (From == End || !From->getUniqueSuccessor()) return *From; auto IsEmpty = [](const BasicBlock *BB) { @@ -219,12 +219,12 @@ // Visited is used to avoid running into an infinite loop. SmallPtrSet Visited; - const BasicBlock *BB = From->getSingleSuccessor(); + const BasicBlock *BB = From->getUniqueSuccessor(); const BasicBlock *PredBB = BB; while (BB && BB != End && IsEmpty(BB) && !Visited.count(BB)) { Visited.insert(BB); PredBB = BB; - BB = BB->getSingleSuccessor(); + BB = BB->getUniqueSuccessor(); } return (BB == End) ? *End : *PredBB; diff --git a/llvm/test/Analysis/LoopNestAnalysis/duplicate-successors.ll b/llvm/test/Analysis/LoopNestAnalysis/duplicate-successors.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Analysis/LoopNestAnalysis/duplicate-successors.ll @@ -0,0 +1,44 @@ +; RUN: opt -passes='print' %s 2>&1 | FileCheck %s +@global = external dso_local global [1000 x [1000 x i32]], align 16 + +; CHECK: IsPerfect=true, Depth=1, OutermostLoop: inner.header, Loops: ( inner.header ) +; CHECK-NEXT: IsPerfect=true, Depth=2, OutermostLoop: outer.header, Loops: ( outer.header inner.header ) + +define void @foo1(i1 %cmp) { +entry: + br i1 %cmp, label %bb1, label %bb1 + +bb1: ; preds = %entry, %entry + br i1 %cmp, label %outer.header.preheader, label %outer.header.preheader + +outer.header.preheader: ; preds = %bb1, %bb1 + br label %outer.header + +outer.header: ; preds = %outer.header.preheader, %outer.latch + %outer.iv = phi i64 [ %outer.iv.next, %outer.latch ], [ 0, %outer.header.preheader ] + br i1 %cmp, label %inner.header.preheader, label %inner.header.preheader + +inner.header.preheader: ; preds = %outer.header, %outer.header + br label %inner.header + +inner.header: ; preds = %inner.header.preheader, %inner.header + %inner.iv = phi i64 [ %inner.iv.next, %inner.header ], [ 5, %inner.header.preheader ] + %ptr = getelementptr inbounds [1000 x [1000 x i32]], [1000 x [1000 x i32]]* @global, i64 0, i64 %inner.iv, i64 %outer.iv + %lv = load i32, i32* %ptr, align 4 + %v = mul i32 %lv, 100 + store i32 %v, i32* %ptr, align 4 + %inner.iv.next = add nsw i64 %inner.iv, 1 + %cond1 = icmp eq i64 %inner.iv.next, 1000 + br i1 %cond1, label %outer.latch, label %inner.header + +outer.latch: ; preds = %inner.header + %outer.iv.next = add nuw nsw i64 %outer.iv, 1 + %cond2 = icmp eq i64 %outer.iv.next, 1000 + br i1 %cond2, label %bb9, label %outer.header + +bb9: ; preds = %outer.latch + br label %bb10 + +bb10: ; preds = %bb9 + ret void +}