diff --git a/llvm/include/llvm/Analysis/ScalarEvolution.h b/llvm/include/llvm/Analysis/ScalarEvolution.h index ccdf29cf3a187b..414baac3f91851 100644 --- a/llvm/include/llvm/Analysis/ScalarEvolution.h +++ b/llvm/include/llvm/Analysis/ScalarEvolution.h @@ -512,7 +512,8 @@ class ScalarEvolution { const SCEV *getConstant(ConstantInt *V); const SCEV *getConstant(const APInt &Val); const SCEV *getConstant(Type *Ty, uint64_t V, bool isSigned = false); - const SCEV *getPtrToIntExpr(const SCEV *Op, Type *Ty, unsigned Depth = 0); + const SCEV *getLosslessPtrToIntExpr(const SCEV *Op, unsigned Depth = 0); + const SCEV *getPtrToIntExpr(const SCEV *Op, Type *Ty); const SCEV *getTruncateExpr(const SCEV *Op, Type *Ty, unsigned Depth = 0); const SCEV *getZeroExtendExpr(const SCEV *Op, Type *Ty, unsigned Depth = 0); const SCEV *getSignExtendExpr(const SCEV *Op, Type *Ty, unsigned Depth = 0); diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp index cb820dfde632b8..a6fa8427461c86 100644 --- a/llvm/lib/Analysis/ScalarEvolution.cpp +++ b/llvm/lib/Analysis/ScalarEvolution.cpp @@ -1043,15 +1043,15 @@ const SCEV *SCEVAddRecExpr::evaluateAtIteration(const SCEV *It, // SCEV Expression folder implementations //===----------------------------------------------------------------------===// -const SCEV *ScalarEvolution::getPtrToIntExpr(const SCEV *Op, Type *Ty, - unsigned Depth) { - assert(Ty->isIntegerTy() && "Target type must be an integer type!"); - assert(Depth <= 1 && "getPtrToIntExpr() should self-recurse at most once."); +const SCEV *ScalarEvolution::getLosslessPtrToIntExpr(const SCEV *Op, + unsigned Depth) { + assert(Depth <= 1 && + "getLosslessPtrToIntExpr() should self-recurse at most once."); // We could be called with an integer-typed operands during SCEV rewrites. // Since the operand is an integer already, just perform zext/trunc/self cast. if (!Op->getType()->isPointerTy()) - return getTruncateOrZeroExtend(Op, Ty); + return Op; assert(!getDataLayout().isNonIntegralPointerType(Op->getType()) && "Source pointer type must be integral for ptrtoint!"); @@ -1065,22 +1065,24 @@ const SCEV *ScalarEvolution::getPtrToIntExpr(const SCEV *Op, Type *Ty, // Is there already an expression for such a cast? if (const SCEV *S = UniqueSCEVs.FindNodeOrInsertPos(ID, IP)) - return getTruncateOrZeroExtend(S, Ty); + return S; + + Type *IntPtrTy = getDataLayout().getIntPtrType(Op->getType()); + + // We can only model ptrtoint if SCEV's effective (integer) type + // is sufficiently wide to represent all possible pointer values. + if (getDataLayout().getTypeSizeInBits(getEffectiveSCEVType(Op->getType())) != + getDataLayout().getTypeSizeInBits(IntPtrTy)) + return getCouldNotCompute(); // If not, is this expression something we can't reduce any further? if (auto *U = dyn_cast(Op)) { - Type *IntPtrTy = getDataLayout().getIntPtrType(Op->getType()); - assert(getDataLayout().getTypeSizeInBits(getEffectiveSCEVType( - Op->getType())) == getDataLayout().getTypeSizeInBits(IntPtrTy) && - "We can only model ptrtoint if SCEV's effective (integer) type is " - "sufficiently wide to represent all possible pointer values."); - // Perform some basic constant folding. If the operand of the ptr2int cast // is a null pointer, don't create a ptr2int SCEV expression (that will be // left as-is), but produce a zero constant. // NOTE: We could handle a more general case, but lack motivational cases. if (isa(U->getValue())) - return getZero(Ty); + return getZero(IntPtrTy); // Create an explicit cast node. // We can reuse the existing insert position since if we get here, @@ -1089,11 +1091,11 @@ const SCEV *ScalarEvolution::getPtrToIntExpr(const SCEV *Op, Type *Ty, SCEVPtrToIntExpr(ID.Intern(SCEVAllocator), Op, IntPtrTy); UniqueSCEVs.InsertNode(S, IP); addToLoopUseLists(S); - return getTruncateOrZeroExtend(S, Ty); + return S; } - assert(Depth == 0 && - "getPtrToIntExpr() should not self-recurse for non-SCEVUnknown's."); + assert(Depth == 0 && "getLosslessPtrToIntExpr() should not self-recurse for " + "non-SCEVUnknown's."); // Otherwise, we've got some expression that is more complex than just a // single SCEVUnknown. But we don't want to have a SCEVPtrToIntExpr of an @@ -1150,8 +1152,7 @@ const SCEV *ScalarEvolution::getPtrToIntExpr(const SCEV *Op, Type *Ty, Type *ExprPtrTy = Expr->getType(); assert(ExprPtrTy->isPointerTy() && "Should only reach pointer-typed SCEVUnknown's."); - Type *ExprIntPtrTy = SE.getDataLayout().getIntPtrType(ExprPtrTy); - return SE.getPtrToIntExpr(Expr, ExprIntPtrTy, /*Depth=*/1); + return SE.getLosslessPtrToIntExpr(Expr, /*Depth=*/1); } }; @@ -1160,6 +1161,16 @@ const SCEV *ScalarEvolution::getPtrToIntExpr(const SCEV *Op, Type *Ty, assert(IntOp->getType()->isIntegerTy() && "We must have succeeded in sinking the cast, " "and ending up with an integer-typed expression!"); + return IntOp; +} + +const SCEV *ScalarEvolution::getPtrToIntExpr(const SCEV *Op, Type *Ty) { + assert(Ty->isIntegerTy() && "Target type must be an integer type!"); + + const SCEV *IntOp = getLosslessPtrToIntExpr(Op); + if (isa(IntOp)) + return IntOp; + return getTruncateOrZeroExtend(IntOp, Ty); } @@ -6777,17 +6788,14 @@ const SCEV *ScalarEvolution::createSCEV(Value *V) { case Instruction::PtrToInt: { // Pointer to integer cast is straight-forward, so do model it. - Value *Ptr = U->getOperand(0); - const SCEV *Op = getSCEV(Ptr); + const SCEV *Op = getSCEV(U->getOperand(0)); Type *DstIntTy = U->getType(); - Type *PtrTy = Ptr->getType(); - Type *IntPtrTy = getDataLayout().getIntPtrType(PtrTy); // But only if effective SCEV (integer) type is wide enough to represent // all possible pointer values. - if (getDataLayout().getTypeSizeInBits(getEffectiveSCEVType(PtrTy)) != - getDataLayout().getTypeSizeInBits(IntPtrTy)) + const SCEV *IntOp = getPtrToIntExpr(Op, DstIntTy); + if (isa(IntOp)) return getUnknown(V); - return getPtrToIntExpr(Op, DstIntTy); + return IntOp; } case Instruction::IntToPtr: // Just don't deal with inttoptr casts.