Skip to content

Commit

Permalink
Check loop exit predicate properly while eliminating one iteration loop.
Browse files Browse the repository at this point in the history
This patch fixes PR 2869


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@57369 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
Devang Patel committed Oct 10, 2008
1 parent 875314b commit fc19fbd
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 13 deletions.
28 changes: 15 additions & 13 deletions lib/Transforms/Scalar/LoopIndexSplit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -585,16 +585,7 @@ bool LoopIndexSplit::processOneIterationLoop(SplitInfo &SD) {
// only when index variable is equal to split value.
IndVar->replaceAllUsesWith(SD.SplitValue);

// Remove Latch to Header edge.
BasicBlock *LatchSucc = NULL;
Header->removePredecessor(Latch);
for (succ_iterator SI = succ_begin(Latch), E = succ_end(Latch);
SI != E; ++SI) {
if (Header != *SI)
LatchSucc = *SI;
}
BR->setUnconditionalDest(LatchSucc);

Instruction *LTerminator = Latch->getTerminator();
Instruction *Terminator = Header->getTerminator();
Value *ExitValue = ExitCondition->getOperand(ExitValueNum);

Expand All @@ -606,22 +597,33 @@ bool LoopIndexSplit::processOneIterationLoop(SplitInfo &SD) {
// c2 = icmp ult i32 SplitValue, ExitValue
// and i32 c1, c2
bool SignedPredicate = ExitCondition->isSignedPredicate();
CmpInst::Predicate C2Predicate = ExitCondition->getPredicate();
if (LTerminator->getOperand(0) != Header)
C2Predicate = CmpInst::getInversePredicate(C2Predicate);
Instruction *C1 = new ICmpInst(SignedPredicate ?
ICmpInst::ICMP_SGE : ICmpInst::ICMP_UGE,
SD.SplitValue, StartValue, "lisplit",
Terminator);
Instruction *C2 = new ICmpInst(SignedPredicate ?
ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT,
Instruction *C2 = new ICmpInst(C2Predicate,
SD.SplitValue, ExitValue, "lisplit",
Terminator);
Instruction *NSplitCond = BinaryOperator::CreateAnd(C1, C2, "lisplit",
Terminator);
SD.SplitCondition->replaceAllUsesWith(NSplitCond);
SD.SplitCondition->eraseFromParent();

// Remove Latch to Header edge.
BasicBlock *LatchSucc = NULL;
Header->removePredecessor(Latch);
for (succ_iterator SI = succ_begin(Latch), E = succ_end(Latch);
SI != E; ++SI) {
if (Header != *SI)
LatchSucc = *SI;
}
BR->setUnconditionalDest(LatchSucc);

// Now, clear latch block. Remove instructions that are responsible
// to increment induction variable.
Instruction *LTerminator = Latch->getTerminator();
for (BasicBlock::iterator LB = Latch->begin(), LE = Latch->end();
LB != LE; ) {
Instruction *I = LB;
Expand Down
66 changes: 66 additions & 0 deletions test/Transforms/LoopIndexSplit/2008-10-10-OneIteration.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
; RUN: llvm-as < %s | opt -loop-index-split | llvm-dis | grep sle | count 1
; PR 2869

@w = external global [2 x [2 x i32]] ; <[2 x [2 x i32]]*> [#uses=5]

declare i32 @f() nounwind

define i32 @main() noreturn nounwind {
entry:
br label %bb1.i.outer

bb1.i.outer: ; preds = %bb5.i, %entry
%i.0.reg2mem.0.ph.i.ph = phi i32 [ 0, %entry ], [ %4, %bb5.i ] ; <i32> [#uses=3]
br label %bb1.i

bb1.i: ; preds = %bb3.i, %bb1.i.outer
%j.0.reg2mem.0.i = phi i32 [ %2, %bb3.i ], [ 0, %bb1.i.outer ] ; <i32> [#uses=3]
%0 = icmp eq i32 %i.0.reg2mem.0.ph.i.ph, %j.0.reg2mem.0.i ; <i1> [#uses=1]
br i1 %0, label %bb2.i, label %bb3.i

bb2.i: ; preds = %bb1.i
%1 = getelementptr [2 x [2 x i32]]* @w, i32 0, i32 %i.0.reg2mem.0.ph.i.ph, i32 %j.0.reg2mem.0.i ; <i32*> [#uses=1]
store i32 1, i32* %1, align 4
br label %bb3.i

bb3.i: ; preds = %bb2.i, %bb1.i
%2 = add i32 %j.0.reg2mem.0.i, 1 ; <i32> [#uses=2]
%3 = icmp sgt i32 %2, 1 ; <i1> [#uses=1]
br i1 %3, label %bb5.i, label %bb1.i

bb5.i: ; preds = %bb3.i
%4 = add i32 %i.0.reg2mem.0.ph.i.ph, 1 ; <i32> [#uses=2]
%5 = icmp sgt i32 %4, 1 ; <i1> [#uses=1]
br i1 %5, label %f.exit, label %bb1.i.outer

f.exit: ; preds = %bb5.i
%6 = load i32* getelementptr ([2 x [2 x i32]]* @w, i32 0, i32 0, i32 0), align 4 ; <i32> [#uses=1]
%7 = icmp eq i32 %6, 1 ; <i1> [#uses=1]
br i1 %7, label %bb, label %bb3

bb: ; preds = %f.exit
%8 = load i32* getelementptr ([2 x [2 x i32]]* @w, i32 0, i32 1, i32 1), align 4 ; <i32> [#uses=1]
%9 = icmp eq i32 %8, 1 ; <i1> [#uses=1]
br i1 %9, label %bb1, label %bb3

bb1: ; preds = %bb
%10 = load i32* getelementptr ([2 x [2 x i32]]* @w, i32 0, i32 1, i32 0), align 4 ; <i32> [#uses=1]
%11 = icmp eq i32 %10, 0 ; <i1> [#uses=1]
br i1 %11, label %bb2, label %bb3

bb2: ; preds = %bb1
%12 = load i32* getelementptr ([2 x [2 x i32]]* @w, i32 0, i32 0, i32 1), align 4 ; <i32> [#uses=1]
%13 = icmp eq i32 %12, 0 ; <i1> [#uses=1]
br i1 %13, label %bb4, label %bb3

bb3: ; preds = %bb2, %bb1, %bb, %f.exit
tail call void @abort() noreturn nounwind
unreachable

bb4: ; preds = %bb2
ret i32 0
}

declare void @abort() noreturn nounwind

declare void @exit(i32) noreturn nounwind

0 comments on commit fc19fbd

Please sign in to comment.