diff --git a/lib/Transforms/Utils/LoopSimplify.cpp b/lib/Transforms/Utils/LoopSimplify.cpp index 16902ff9150..fee7f081333 100644 --- a/lib/Transforms/Utils/LoopSimplify.cpp +++ b/lib/Transforms/Utils/LoopSimplify.cpp @@ -622,6 +622,11 @@ LoopSimplify::InsertUniqueBackedgeBlock(Loop *L, BasicBlock *Preheader) { std::vector BackedgeBlocks; for (pred_iterator I = pred_begin(Header), E = pred_end(Header); I != E; ++I){ BasicBlock *P = *I; + + // Indirectbr edges cannot be split, so we must fail if we find one. + if (isa(P->getTerminator())) + return 0; + if (P != Preheader) BackedgeBlocks.push_back(P); } diff --git a/test/Transforms/LoopSimplify/indirectbr-backedge.ll b/test/Transforms/LoopSimplify/indirectbr-backedge.ll new file mode 100644 index 00000000000..ca6e47fcecd --- /dev/null +++ b/test/Transforms/LoopSimplify/indirectbr-backedge.ll @@ -0,0 +1,35 @@ +; RUN: opt -loopsimplify -S < %s | FileCheck %s + +; LoopSimplify shouldn't split loop backedges that use indirectbr. + +; CHECK: bb1: ; preds = %bb5, %bb +; CHECK-NEXT: indirectbr + +; CHECK: bb5: ; preds = %bb1 +; CHECK-NEXT: br label %bb1{{$}} + +define void @foo(i8* %p) nounwind { +bb: + br label %bb1 + +bb1: ; preds = %bb5, %bb1, %bb + indirectbr i8* %p, [label %bb6, label %bb7, label %bb1, label %bb2, label %bb3, label %bb5, label %bb4] + +bb2: ; preds = %bb1 + ret void + +bb3: ; preds = %bb1 + ret void + +bb4: ; preds = %bb1 + ret void + +bb5: ; preds = %bb1 + br label %bb1 + +bb6: ; preds = %bb1 + ret void + +bb7: ; preds = %bb1 + ret void +}