Index: llvm/trunk/lib/Transforms/Utils/LoopUnroll.cpp =================================================================== --- llvm/trunk/lib/Transforms/Utils/LoopUnroll.cpp +++ llvm/trunk/lib/Transforms/Utils/LoopUnroll.cpp @@ -318,6 +318,10 @@ return false; } + // The current loop unroll pass can only unroll loops with a single latch + // that's a conditional branch exiting the loop. + // FIXME: The implementation can be extended to work with more complicated + // cases, e.g. loops with multiple latches. BasicBlock *Header = L->getHeader(); BranchInst *BI = dyn_cast(LatchBlock->getTerminator()); @@ -328,6 +332,17 @@ return false; } + auto CheckSuccessors = [&](unsigned S1, unsigned S2) { + return BI->getSuccessor(S1) == Header && !L->contains(BI->getSuccessor(S2)); + + }; + + if (!CheckSuccessors(0, 1) && !CheckSuccessors(1, 0)) { + DEBUG(dbgs() << "Can't unroll; only loops with one conditional latch" + " exiting the loop can be unrolled\n"); + return false; + } + if (Header->hasAddressTaken()) { // The loop-rotate pass can be helpful to avoid this in many cases. DEBUG(dbgs() << Index: llvm/trunk/test/Transforms/LoopUnroll/not-rotated.ll =================================================================== --- llvm/trunk/test/Transforms/LoopUnroll/not-rotated.ll +++ llvm/trunk/test/Transforms/LoopUnroll/not-rotated.ll @@ -0,0 +1,26 @@ +; PR28103 +; Bail out if the two successors are not the header +; and another bb outside of the loop. This case is not +; properly handled by LoopUnroll, currently. + +; RUN: opt -loop-unroll -verify-dom-info %s +; REQUIRE: asserts + +define void @tinkywinky(i1 %patatino) { +entry: + br label %header1 +header1: + %indvars.iv = phi i64 [ 1, %body2 ], [ 0, %entry ] + %exitcond = icmp ne i64 %indvars.iv, 1 + br i1 %exitcond, label %body1, label %exit +body1: + br i1 %patatino, label %body2, label %sink +body2: + br i1 %patatino, label %header1, label %body3 +body3: + br label %sink +sink: + br label %body2 +exit: + ret void +}