diff --git a/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp b/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp --- a/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp +++ b/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp @@ -1265,6 +1265,32 @@ if (UsedInLoop) continue; + // If none operand is used in or after the loop exit block, sinking the + // instruction from pre-header to exit block will extend operands' + // live range, hence could increase register pressure. The instruction + // should not be sinked for conservativeness. + bool OperandsUsedAfterLoop = false; + for (Value *Op : I->operands()) { + if (isa(Op)) { + continue; + } + for (Use &U : Op->uses()) { + Instruction *User = cast(U.getUser()); + BasicBlock *UseBB = User->getParent(); + if (PHINode *P = dyn_cast(User)) { + unsigned i = + PHINode::getIncomingValueNumForOperand(U.getOperandNo()); + UseBB = P->getIncomingBlock(i); + } + if (DT->dominates(ExitBlock, UseBB)) { + OperandsUsedAfterLoop = true; + break; + } + } + } + if (!OperandsUsedAfterLoop) + continue; + // Otherwise, sink it to the exit block. Instruction *ToMove = &*I; bool Done = false;