diff --git a/lib/Transforms/Scalar/GVN.cpp b/lib/Transforms/Scalar/GVN.cpp index a08ee68ca62..eb12abe243c 100644 --- a/lib/Transforms/Scalar/GVN.cpp +++ b/lib/Transforms/Scalar/GVN.cpp @@ -651,7 +651,8 @@ namespace { SmallVector& toErase); bool processNonLocalLoad(LoadInst* L, SmallVector& toErase); Value *performPHIConstruction(BasicBlock *BB, LoadInst* orig, - DenseMap &Phis); + DenseMap &Phis, + SmallPtrSet& visited); void dump(DenseMap& d); }; @@ -706,7 +707,8 @@ void GVN::dump(DenseMap& d) { Value *GVN::performPHIConstruction(BasicBlock *BB, LoadInst* orig, - DenseMap &Phis) { + DenseMap &Phis, + SmallPtrSet& visited) { DenseMap::iterator DI = Phis.find(BB); if (DI != Phis.end()) return DI->second; @@ -719,17 +721,25 @@ Value *GVN::performPHIConstruction(BasicBlock *BB, LoadInst* orig, Phis.insert(std::make_pair(BB, DI->second)); return DI->second; } else { - Value* domV = performPHIConstruction(*pred_begin(BB), orig, Phis); + visited.insert(BB); + Value* domV = performPHIConstruction(*pred_begin(BB), orig, Phis, visited); + visited.erase(BB); + Phis.insert(std::make_pair(BB, domV)); return domV; } } else { PHINode *PN = new PHINode(orig->getType(), orig->getName()+".rle", BB->begin()); PN->reserveOperandSpace(numPreds); - + + visited.insert(BB); // Fill in the incoming values for the block. for (pred_iterator PI = pred_begin(BB), E = pred_end(BB); PI != E; ++PI) - PN->addIncoming(performPHIConstruction(*PI, orig, Phis), *PI); + if (!visited.count(*PI)) + PN->addIncoming(performPHIConstruction(*PI, orig, Phis, visited), *PI); + else + PN->addIncoming(PN, *PI); + visited.erase(BB); bool all_same = PN->getNumIncomingValues() != 1; Value* first = PN->getIncomingValue(0); @@ -772,7 +782,8 @@ bool GVN::processNonLocalLoad(LoadInst* L, SmallVector& toErase return false; } - Value* v = performPHIConstruction(L->getParent(), L, repl); + SmallPtrSet visited; + Value* v = performPHIConstruction(L->getParent(), L, repl, visited); MD.removeInstruction(L); L->replaceAllUsesWith(v); diff --git a/test/Transforms/GVN/2007-07-25-InfiniteLoop.ll b/test/Transforms/GVN/2007-07-25-InfiniteLoop.ll new file mode 100644 index 00000000000..50eaf2f8c0c --- /dev/null +++ b/test/Transforms/GVN/2007-07-25-InfiniteLoop.ll @@ -0,0 +1,14 @@ +; RUN: llvm-as < %s | opt -gvn | llvm-dis + + %struct.INT2 = type { i32, i32 } +@blkshifts = external global %struct.INT2* ; <%struct.INT2**> [#uses=2] + +define i32 @xcompact() { +entry: + store %struct.INT2* null, %struct.INT2** @blkshifts, align 4 + br label %bb + +bb: ; preds = %bb, %entry + %tmp10 = load %struct.INT2** @blkshifts, align 4 ; <%struct.INT2*> [#uses=0] + br label %bb +}