diff options
-rw-r--r-- | include/llvm/Analysis/ScalarEvolutionExpander.h | 2 | ||||
-rw-r--r-- | lib/Analysis/ScalarEvolutionExpander.cpp | 30 | ||||
-rw-r--r-- | test/Transforms/IndVarsSimplify/2008-06-15-SCEVExpanderBug.ll | 17 |
3 files changed, 33 insertions, 16 deletions
diff --git a/include/llvm/Analysis/ScalarEvolutionExpander.h b/include/llvm/Analysis/ScalarEvolutionExpander.h index daff373..9a69b24 100644 --- a/include/llvm/Analysis/ScalarEvolutionExpander.h +++ b/include/llvm/Analysis/ScalarEvolutionExpander.h @@ -88,7 +88,7 @@ namespace llvm { /// InsertBinop - Insert the specified binary operator, doing a small amount /// of work to avoid inserting an obviously redundant operation. static Value *InsertBinop(Instruction::BinaryOps Opcode, Value *LHS, - Value *RHS, Instruction *&InsertPt); + Value *RHS, Instruction *InsertPt); protected: Value *expand(SCEV *S); diff --git a/lib/Analysis/ScalarEvolutionExpander.cpp b/lib/Analysis/ScalarEvolutionExpander.cpp index a241960..9872ced 100644 --- a/lib/Analysis/ScalarEvolutionExpander.cpp +++ b/lib/Analysis/ScalarEvolutionExpander.cpp @@ -73,7 +73,7 @@ Value *SCEVExpander::InsertCastOfTo(Instruction::CastOps opcode, Value *V, /// InsertBinop - Insert the specified binary operator, doing a small amount /// of work to avoid inserting an obviously redundant operation. Value *SCEVExpander::InsertBinop(Instruction::BinaryOps Opcode, Value *LHS, - Value *RHS, Instruction *&InsertPt) { + Value *RHS, Instruction *InsertPt) { // Fold a binop with constant operands. if (Constant *CLHS = dyn_cast<Constant>(LHS)) if (Constant *CRHS = dyn_cast<Constant>(RHS)) @@ -81,21 +81,21 @@ Value *SCEVExpander::InsertBinop(Instruction::BinaryOps Opcode, Value *LHS, // Do a quick scan to see if we have this binop nearby. If so, reuse it. unsigned ScanLimit = 6; - for (BasicBlock::iterator IP = InsertPt, E = InsertPt->getParent()->begin(); - ScanLimit; --IP, --ScanLimit) { - if (BinaryOperator *BinOp = dyn_cast<BinaryOperator>(IP)) - if (BinOp->getOpcode() == Opcode && BinOp->getOperand(0) == LHS && - BinOp->getOperand(1) == RHS) { - // If we found the instruction *at* the insert point, insert later - // instructions after it. - if (BinOp == InsertPt) - InsertPt = ++IP; - return BinOp; - } - if (IP == E) break; + BasicBlock::iterator BlockBegin = InsertPt->getParent()->begin(); + if (InsertPt != BlockBegin) { + // Scanning starts from the last instruction before InsertPt. + BasicBlock::iterator IP = InsertPt; + --IP; + for (; ScanLimit; --IP, --ScanLimit) { + if (BinaryOperator *BinOp = dyn_cast<BinaryOperator>(IP)) + if (BinOp->getOpcode() == Opcode && BinOp->getOperand(0) == LHS && + BinOp->getOperand(1) == RHS) + return BinOp; + if (IP == BlockBegin) break; + } } - - // If we don't have + + // If we haven't found this binop, insert it. return BinaryOperator::Create(Opcode, LHS, RHS, "tmp", InsertPt); } diff --git a/test/Transforms/IndVarsSimplify/2008-06-15-SCEVExpanderBug.ll b/test/Transforms/IndVarsSimplify/2008-06-15-SCEVExpanderBug.ll new file mode 100644 index 0000000..aac8d97 --- /dev/null +++ b/test/Transforms/IndVarsSimplify/2008-06-15-SCEVExpanderBug.ll @@ -0,0 +1,17 @@ +; RUN: llvm-as < %s | opt -indvars -disable-output +; PR2434 + +define fastcc void @regcppop() nounwind { +entry: + %tmp61 = add i32 0, -5 ; <i32> [#uses=1] + br label %bb + +bb: ; preds = %bb, %entry + %PL_savestack_ix.tmp.0 = phi i32 [ %tmp61, %entry ], [ %tmp127, %bb ] ; <i32> [#uses=2] + %indvar10 = phi i32 [ 0, %entry ], [ %indvar.next11, %bb ] ; <i32> [#uses=2] + %tmp13 = mul i32 %indvar10, -4 ; <i32> [#uses=0] + %tmp111 = add i32 %PL_savestack_ix.tmp.0, -3 ; <i32> [#uses=0] + %tmp127 = add i32 %PL_savestack_ix.tmp.0, -4 ; <i32> [#uses=1] + %indvar.next11 = add i32 %indvar10, 1 ; <i32> [#uses=1] + br label %bb +} |