diff --git a/llvm/lib/Target/PowerPC/PPCTargetTransformInfo.h b/llvm/lib/Target/PowerPC/PPCTargetTransformInfo.h --- a/llvm/lib/Target/PowerPC/PPCTargetTransformInfo.h +++ b/llvm/lib/Target/PowerPC/PPCTargetTransformInfo.h @@ -33,7 +33,8 @@ const PPCSubtarget *getST() const { return ST; } const PPCTargetLowering *getTLI() const { return TLI; } - bool mightUseCTR(BasicBlock *BB, TargetLibraryInfo *LibInfo); + bool mightUseCTR(BasicBlock *BB, TargetLibraryInfo *LibInfo, + SmallPtrSetImpl &Visited); public: explicit PPCTTIImpl(const PPCTargetMachine *TM, const Function &F) diff --git a/llvm/lib/Target/PowerPC/PPCTargetTransformInfo.cpp b/llvm/lib/Target/PowerPC/PPCTargetTransformInfo.cpp --- a/llvm/lib/Target/PowerPC/PPCTargetTransformInfo.cpp +++ b/llvm/lib/Target/PowerPC/PPCTargetTransformInfo.cpp @@ -217,8 +217,8 @@ return BaseT::getUserCost(U, Operands); } -bool PPCTTIImpl::mightUseCTR(BasicBlock *BB, - TargetLibraryInfo *LibInfo) { +bool PPCTTIImpl::mightUseCTR(BasicBlock *BB, TargetLibraryInfo *LibInfo, + SmallPtrSetImpl &Visited) { const PPCTargetMachine &TM = ST->getTargetMachine(); // Loop through the inline asm constraints and look for something that @@ -237,8 +237,11 @@ // Determining the address of a TLS variable results in a function call in // certain TLS models. - std::function memAddrUsesCTR = - [&memAddrUsesCTR, &TM](const Value *MemAddr) -> bool { + std::function memAddrUsesCTR = + [&memAddrUsesCTR, &TM, &Visited](const Value *MemAddr) -> bool { + // No need to traverse again if we already checked this operand. + if (!Visited.insert(MemAddr).second) + return false; const auto *GV = dyn_cast(MemAddr); if (!GV) { // Recurse to check for constants that refer to TLS global variables. @@ -502,9 +505,10 @@ // We don't want to spill/restore the counter register, and so we don't // want to use the counter register if the loop contains calls. + SmallPtrSet Visited; for (Loop::block_iterator I = L->block_begin(), IE = L->block_end(); I != IE; ++I) - if (mightUseCTR(*I, LibInfo)) + if (mightUseCTR(*I, LibInfo, Visited)) return false; SmallVector ExitingBlocks;