diff --git a/llvm/include/llvm/Analysis/ScalarEvolution.h b/llvm/include/llvm/Analysis/ScalarEvolution.h index bbe94c8ed8f6f..a2b9b59ec2247 100644 --- a/llvm/include/llvm/Analysis/ScalarEvolution.h +++ b/llvm/include/llvm/Analysis/ScalarEvolution.h @@ -704,6 +704,9 @@ class ScalarEvolution { /// cases do exist. const SCEV *getPointerBase(const SCEV *V); + /// Compute an expression equivalent to S - getPointerBase(S). + const SCEV *removePointerBase(const SCEV *S); + /// Return a SCEV expression for the specified value at the specified scope /// in the program. The L value specifies a loop nest to evaluate the /// expression at, where null is the top-level or a specified loop is diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp index 5539c620a93f5..d77934c215e35 100644 --- a/llvm/lib/Analysis/ScalarEvolution.cpp +++ b/llvm/lib/Analysis/ScalarEvolution.cpp @@ -4154,17 +4154,16 @@ const SCEV *ScalarEvolution::getNotSCEV(const SCEV *V) { return getMinusSCEV(getMinusOne(Ty), V); } -/// Compute an expression equivalent to S - getPointerBase(S). -static const SCEV *removePointerBase(ScalarEvolution *SE, const SCEV *P) { +const SCEV *ScalarEvolution::removePointerBase(const SCEV *P) { assert(P->getType()->isPointerTy()); if (auto *AddRec = dyn_cast(P)) { // The base of an AddRec is the first operand. SmallVector Ops{AddRec->operands()}; - Ops[0] = removePointerBase(SE, Ops[0]); + Ops[0] = removePointerBase(Ops[0]); // Don't try to transfer nowrap flags for now. We could in some cases // (for example, if pointer operand of the AddRec is a SCEVUnknown). - return SE->getAddRecExpr(Ops, AddRec->getLoop(), SCEV::FlagAnyWrap); + return getAddRecExpr(Ops, AddRec->getLoop(), SCEV::FlagAnyWrap); } if (auto *Add = dyn_cast(P)) { // The base of an Add is the pointer operand. @@ -4176,13 +4175,13 @@ static const SCEV *removePointerBase(ScalarEvolution *SE, const SCEV *P) { PtrOp = &AddOp; } } - *PtrOp = removePointerBase(SE, *PtrOp); + *PtrOp = removePointerBase(*PtrOp); // Don't try to transfer nowrap flags for now. We could in some cases // (for example, if the pointer operand of the Add is a SCEVUnknown). - return SE->getAddExpr(Ops); + return getAddExpr(Ops); } // Any other expression must be a pointer base. - return SE->getZero(P->getType()); + return getZero(P->getType()); } const SCEV *ScalarEvolution::getMinusSCEV(const SCEV *LHS, const SCEV *RHS, @@ -4199,8 +4198,8 @@ const SCEV *ScalarEvolution::getMinusSCEV(const SCEV *LHS, const SCEV *RHS, if (!LHS->getType()->isPointerTy() || getPointerBase(LHS) != getPointerBase(RHS)) return getCouldNotCompute(); - LHS = removePointerBase(this, LHS); - RHS = removePointerBase(this, RHS); + LHS = removePointerBase(LHS); + RHS = removePointerBase(RHS); } // We represent LHS - RHS as LHS + (-1)*RHS. This transformation diff --git a/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp b/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp index 5d3d98a25b66d..38978c38aba89 100644 --- a/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp +++ b/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp @@ -917,28 +917,6 @@ Value *SCEVExpander::visitUDivExpr(const SCEVUDivExpr *S) { /*IsSafeToHoist*/ SE.isKnownNonZero(S->getRHS())); } -/// Move parts of Base into Rest to leave Base with the minimal -/// expression that provides a pointer operand suitable for a -/// GEP expansion. -static void ExposePointerBase(const SCEV *&Base, const SCEV *&Rest, - ScalarEvolution &SE) { - while (const SCEVAddRecExpr *A = dyn_cast(Base)) { - Base = A->getStart(); - Rest = SE.getAddExpr(Rest, - SE.getAddRecExpr(SE.getConstant(A->getType(), 0), - A->getStepRecurrence(SE), - A->getLoop(), - A->getNoWrapFlags(SCEV::FlagNW))); - } - if (const SCEVAddExpr *A = dyn_cast(Base)) { - Base = A->getOperand(A->getNumOperands()-1); - SmallVector NewAddOps(A->operands()); - NewAddOps.back() = Rest; - Rest = SE.getAddExpr(NewAddOps); - ExposePointerBase(Base, Rest, SE); - } -} - /// Determine if this is a well-behaved chain of instructions leading back to /// the PHI. If so, it may be reused by expanded expressions. bool SCEVExpander::isNormalAddRecExprPHI(PHINode *PN, Instruction *IncV, @@ -1568,24 +1546,17 @@ Value *SCEVExpander::visitAddRecExpr(const SCEVAddRecExpr *S) { // {X,+,F} --> X + {0,+,F} if (!S->getStart()->isZero()) { + if (PointerType *PTy = dyn_cast(S->getType())) { + Value *StartV = expand(SE.getPointerBase(S)); + assert(StartV->getType() == PTy && "Pointer type mismatch for GEP!"); + return expandAddToGEP(SE.removePointerBase(S), PTy, Ty, StartV); + } + SmallVector NewOps(S->operands()); NewOps[0] = SE.getConstant(Ty, 0); const SCEV *Rest = SE.getAddRecExpr(NewOps, L, S->getNoWrapFlags(SCEV::FlagNW)); - // Turn things like ptrtoint+arithmetic+inttoptr into GEP. See the - // comments on expandAddToGEP for details. - const SCEV *Base = S->getStart(); - // Dig into the expression to find the pointer base for a GEP. - const SCEV *ExposedRest = Rest; - ExposePointerBase(Base, ExposedRest, SE); - // If we found a pointer, expand the AddRec with a GEP. - if (PointerType *PTy = dyn_cast(Base->getType())) { - Value *StartV = expand(Base); - assert(StartV->getType() == PTy && "Pointer type mismatch for GEP!"); - return expandAddToGEP(ExposedRest, PTy, Ty, StartV); - } - // Just do a normal add. Pre-expand the operands to suppress folding. // // The LHS and RHS values are factored out of the expand call to make the