@@ -277,11 +277,13 @@ void SCEV::print(raw_ostream &OS) const {
277277 case scVScale:
278278 OS << "vscale";
279279 return;
280+ case scPtrToAddr:
280281 case scPtrToInt: {
281- const SCEVPtrToIntExpr *PtrToInt = cast<SCEVPtrToIntExpr>(this);
282- const SCEV *Op = PtrToInt->getOperand();
283- OS << "(ptrtoint " << *Op->getType() << " " << *Op << " to "
284- << *PtrToInt->getType() << ")";
282+ const SCEVCastExpr *PtrCast = cast<SCEVCastExpr>(this);
283+ const SCEV *Op = PtrCast->getOperand();
284+ StringRef OpS = getSCEVType() == scPtrToAddr ? "addr" : "int";
285+ OS << "(ptrto" << OpS << " " << *Op->getType() << " " << *Op << " to "
286+ << *PtrCast->getType() << ")";
285287 return;
286288 }
287289 case scTruncate: {
@@ -386,6 +388,7 @@ Type *SCEV::getType() const {
386388 return cast<SCEVConstant>(this)->getType();
387389 case scVScale:
388390 return cast<SCEVVScale>(this)->getType();
391+ case scPtrToAddr:
389392 case scPtrToInt:
390393 case scTruncate:
391394 case scZeroExtend:
@@ -420,6 +423,7 @@ ArrayRef<const SCEV *> SCEV::operands() const {
420423 case scVScale:
421424 case scUnknown:
422425 return {};
426+ case scPtrToAddr:
423427 case scPtrToInt:
424428 case scTruncate:
425429 case scZeroExtend:
@@ -512,6 +516,13 @@ SCEVCastExpr::SCEVCastExpr(const FoldingSetNodeIDRef ID, SCEVTypes SCEVTy,
512516 const SCEV *op, Type *ty)
513517 : SCEV(ID, SCEVTy, computeExpressionSize(op)), Op(op), Ty(ty) {}
514518
519+ SCEVPtrToAddrExpr::SCEVPtrToAddrExpr(const FoldingSetNodeIDRef ID,
520+ const SCEV *Op, Type *ITy)
521+ : SCEVCastExpr(ID, scPtrToAddr, Op, ITy) {
522+ assert(getOperand()->getType()->isPointerTy() && Ty->isIntegerTy() &&
523+ "Must be a non-bit-width-changing pointer-to-integer cast!");
524+ }
525+
515526SCEVPtrToIntExpr::SCEVPtrToIntExpr(const FoldingSetNodeIDRef ID, const SCEV *Op,
516527 Type *ITy)
517528 : SCEVCastExpr(ID, scPtrToInt, Op, ITy) {
@@ -724,6 +735,7 @@ CompareSCEVComplexity(const LoopInfo *const LI, const SCEV *LHS,
724735 case scTruncate:
725736 case scZeroExtend:
726737 case scSignExtend:
738+ case scPtrToAddr:
727739 case scPtrToInt:
728740 case scAddExpr:
729741 case scMulExpr:
@@ -1004,10 +1016,11 @@ SCEVAddRecExpr::evaluateAtIteration(ArrayRef<const SCEV *> Operands,
10041016// SCEV Expression folder implementations
10051017//===----------------------------------------------------------------------===//
10061018
1007- const SCEV *ScalarEvolution::getLosslessPtrToIntExpr(const SCEV *Op,
1008- unsigned Depth) {
1019+ const SCEV *ScalarEvolution::getLosslessPtrToIntOrAddrExpr(SCEVTypes Kind,
1020+ const SCEV *Op,
1021+ unsigned Depth) {
10091022 assert(Depth <= 1 &&
1010- "getLosslessPtrToIntExpr () should self-recurse at most once.");
1023+ "getLosslessPtrToIntOrAddrExpr () should self-recurse at most once.");
10111024
10121025 // We could be called with an integer-typed operands during SCEV rewrites.
10131026 // Since the operand is an integer already, just perform zext/trunc/self cast.
@@ -1052,35 +1065,45 @@ const SCEV *ScalarEvolution::getLosslessPtrToIntExpr(const SCEV *Op,
10521065 // Create an explicit cast node.
10531066 // We can reuse the existing insert position since if we get here,
10541067 // we won't have made any changes which would invalidate it.
1055- SCEV *S = new (SCEVAllocator)
1056- SCEVPtrToIntExpr(ID.Intern(SCEVAllocator), Op, IntPtrTy);
1068+ SCEV *S;
1069+ if (Kind == scPtrToInt) {
1070+ S = new (SCEVAllocator)
1071+ SCEVPtrToIntExpr(ID.Intern(SCEVAllocator), Op, IntPtrTy);
1072+ } else {
1073+ S = new (SCEVAllocator)
1074+ SCEVPtrToAddrExpr(ID.Intern(SCEVAllocator), Op, IntPtrTy);
1075+ }
10571076 UniqueSCEVs.InsertNode(S, IP);
10581077 registerUser(S, Op);
10591078 return S;
10601079 }
10611080
1062- assert(Depth == 0 && "getLosslessPtrToIntExpr() should not self-recurse for "
1063- "non-SCEVUnknown's.");
1081+ assert(Depth == 0 &&
1082+ "getLosslessPtrToIntOrAddrExpr() should not self-recurse for "
1083+ "non-SCEVUnknown's.");
10641084
10651085 // Otherwise, we've got some expression that is more complex than just a
1066- // single SCEVUnknown. But we don't want to have a SCEVPtrToIntExpr of an
1067- // arbitrary expression, we want to have SCEVPtrToIntExpr of an SCEVUnknown
1068- // only, and the expressions must otherwise be integer-typed.
1069- // So sink the cast down to the SCEVUnknown's.
1086+ // single SCEVUnknown. But we don't want to have a SCEVPtrTo(Int|Addr)Expr of
1087+ // an arbitrary expression, we want to have SCEVPtrTo(Int|Addr)Expr of an
1088+ // SCEVUnknown only, and the expressions must otherwise be integer-typed. So
1089+ // sink the cast down to the SCEVUnknown's.
10701090
1071- /// The SCEVPtrToIntSinkingRewriter takes a scalar evolution expression,
1091+ /// The SCEVPtrToIntOrAddrSinkingRewriter takes a scalar evolution expression,
10721092 /// which computes a pointer-typed value, and rewrites the whole expression
10731093 /// tree so that *all* the computations are done on integers, and the only
10741094 /// pointer-typed operands in the expression are SCEVUnknown.
1075- class SCEVPtrToIntSinkingRewriter
1076- : public SCEVRewriteVisitor<SCEVPtrToIntSinkingRewriter> {
1077- using Base = SCEVRewriteVisitor<SCEVPtrToIntSinkingRewriter>;
1095+ class SCEVPtrToIntOrAddrSinkingRewriter
1096+ : public SCEVRewriteVisitor<SCEVPtrToIntOrAddrSinkingRewriter> {
1097+ using Base = SCEVRewriteVisitor<SCEVPtrToIntOrAddrSinkingRewriter>;
1098+ const SCEVTypes Kind;
10781099
10791100 public:
1080- SCEVPtrToIntSinkingRewriter(ScalarEvolution &SE) : SCEVRewriteVisitor(SE) {}
1101+ SCEVPtrToIntOrAddrSinkingRewriter(SCEVTypes Kind, ScalarEvolution &SE)
1102+ : SCEVRewriteVisitor(SE), Kind(Kind) {}
10811103
1082- static const SCEV *rewrite(const SCEV *Scev, ScalarEvolution &SE) {
1083- SCEVPtrToIntSinkingRewriter Rewriter(SE);
1104+ static const SCEV *rewrite(const SCEV *Scev, SCEVTypes Kind,
1105+ ScalarEvolution &SE) {
1106+ SCEVPtrToIntOrAddrSinkingRewriter Rewriter(Kind, SE);
10841107 return Rewriter.visit(Scev);
10851108 }
10861109
@@ -1116,18 +1139,37 @@ const SCEV *ScalarEvolution::getLosslessPtrToIntExpr(const SCEV *Op,
11161139 const SCEV *visitUnknown(const SCEVUnknown *Expr) {
11171140 assert(Expr->getType()->isPointerTy() &&
11181141 "Should only reach pointer-typed SCEVUnknown's.");
1119- return SE.getLosslessPtrToIntExpr( Expr, /*Depth=*/1);
1142+ return SE.getLosslessPtrToIntOrAddrExpr(Kind, Expr, /*Depth=*/1);
11201143 }
11211144 };
11221145
11231146 // And actually perform the cast sinking.
1124- const SCEV *IntOp = SCEVPtrToIntSinkingRewriter::rewrite(Op, *this);
1147+ const SCEV *IntOp =
1148+ SCEVPtrToIntOrAddrSinkingRewriter::rewrite(Op, Kind, *this);
11251149 assert(IntOp->getType()->isIntegerTy() &&
11261150 "We must have succeeded in sinking the cast, "
11271151 "and ending up with an integer-typed expression!");
11281152 return IntOp;
11291153}
11301154
1155+ const SCEV *ScalarEvolution::getLosslessPtrToAddrExpr(const SCEV *Op) {
1156+ return getLosslessPtrToIntOrAddrExpr(scPtrToAddr, Op);
1157+ }
1158+
1159+ const SCEV *ScalarEvolution::getLosslessPtrToIntExpr(const SCEV *Op) {
1160+ return getLosslessPtrToIntOrAddrExpr(scPtrToInt, Op);
1161+ }
1162+
1163+ const SCEV *ScalarEvolution::getPtrToAddrExpr(const SCEV *Op, Type *Ty) {
1164+ assert(Ty->isIntegerTy() && "Target type must be an integer type!");
1165+
1166+ const SCEV *IntOp = getLosslessPtrToAddrExpr(Op);
1167+ if (isa<SCEVCouldNotCompute>(IntOp))
1168+ return IntOp;
1169+
1170+ return getTruncateOrZeroExtend(IntOp, Ty);
1171+ }
1172+
11311173const SCEV *ScalarEvolution::getPtrToIntExpr(const SCEV *Op, Type *Ty) {
11321174 assert(Ty->isIntegerTy() && "Target type must be an integer type!");
11331175
@@ -4076,6 +4118,8 @@ class SCEVSequentialMinMaxDeduplicatingVisitor final
40764118
40774119 RetVal visitVScale(const SCEVVScale *VScale) { return VScale; }
40784120
4121+ RetVal visitPtrToAddrExpr(const SCEVPtrToAddrExpr *Expr) { return Expr; }
4122+
40794123 RetVal visitPtrToIntExpr(const SCEVPtrToIntExpr *Expr) { return Expr; }
40804124
40814125 RetVal visitTruncateExpr(const SCEVTruncateExpr *Expr) { return Expr; }
@@ -4126,6 +4170,7 @@ static bool scevUnconditionallyPropagatesPoisonFromOperands(SCEVTypes Kind) {
41264170 case scTruncate:
41274171 case scZeroExtend:
41284172 case scSignExtend:
4173+ case scPtrToAddr:
41294174 case scPtrToInt:
41304175 case scAddExpr:
41314176 case scMulExpr:
@@ -6361,8 +6406,9 @@ APInt ScalarEvolution::getConstantMultipleImpl(const SCEV *S,
63616406 switch (S->getSCEVType()) {
63626407 case scConstant:
63636408 return cast<SCEVConstant>(S)->getAPInt();
6409+ case scPtrToAddr:
63646410 case scPtrToInt:
6365- return getConstantMultiple(cast<SCEVPtrToIntExpr >(S)->getOperand(), CtxI );
6411+ return getConstantMultiple(cast<SCEVCastExpr >(S)->getOperand());
63666412 case scUDivExpr:
63676413 case scVScale:
63686414 return APInt(BitWidth, 1);
@@ -6639,6 +6685,7 @@ ScalarEvolution::getRangeRefIter(const SCEV *S,
66396685 case scTruncate:
66406686 case scZeroExtend:
66416687 case scSignExtend:
6688+ case scPtrToAddr:
66426689 case scPtrToInt:
66436690 case scAddExpr:
66446691 case scMulExpr:
@@ -6766,10 +6813,11 @@ const ConstantRange &ScalarEvolution::getRangeRef(
67666813 SExt, SignHint,
67676814 ConservativeResult.intersectWith(X.signExtend(BitWidth), RangeType));
67686815 }
6816+ case scPtrToAddr:
67696817 case scPtrToInt: {
6770- const SCEVPtrToIntExpr *PtrToInt = cast<SCEVPtrToIntExpr >(S);
6771- ConstantRange X = getRangeRef(PtrToInt ->getOperand(), SignHint, Depth + 1);
6772- return setRange(PtrToInt , SignHint, X);
6818+ const SCEVCastExpr *Cast = cast<SCEVCastExpr >(S);
6819+ ConstantRange X = getRangeRef(Cast ->getOperand(), SignHint, Depth + 1);
6820+ return setRange(Cast , SignHint, X);
67736821 }
67746822 case scAddExpr: {
67756823 const SCEVAddExpr *Add = cast<SCEVAddExpr>(S);
@@ -7662,6 +7710,7 @@ ScalarEvolution::getOperandsToCreate(Value *V, SmallVectorImpl<Value *> &Ops) {
76627710 case Instruction::Trunc:
76637711 case Instruction::ZExt:
76647712 case Instruction::SExt:
7713+ case Instruction::PtrToAddr:
76657714 case Instruction::PtrToInt:
76667715 Ops.push_back(U->getOperand(0));
76677716 return nullptr;
@@ -8134,13 +8183,16 @@ const SCEV *ScalarEvolution::createSCEV(Value *V) {
81348183 return getSCEV(U->getOperand(0));
81358184 break;
81368185
8186+ case Instruction::PtrToAddr:
81378187 case Instruction::PtrToInt: {
81388188 // Pointer to integer cast is straight-forward, so do model it.
81398189 const SCEV *Op = getSCEV(U->getOperand(0));
81408190 Type *DstIntTy = U->getType();
81418191 // But only if effective SCEV (integer) type is wide enough to represent
81428192 // all possible pointer values.
8143- const SCEV *IntOp = getPtrToIntExpr(Op, DstIntTy);
8193+ const SCEV *IntOp = U->getOpcode() == Instruction::PtrToInt
8194+ ? getPtrToIntExpr(Op, DstIntTy)
8195+ : getPtrToAddrExpr(Op, DstIntTy);
81448196 if (isa<SCEVCouldNotCompute>(IntOp))
81458197 return getUnknown(V);
81468198 return IntOp;
@@ -9942,6 +9994,13 @@ static Constant *BuildConstantFromSCEV(const SCEV *V) {
99429994 return cast<SCEVConstant>(V)->getValue();
99439995 case scUnknown:
99449996 return dyn_cast<Constant>(cast<SCEVUnknown>(V)->getValue());
9997+ case scPtrToAddr: {
9998+ const SCEVPtrToAddrExpr *P2I = cast<SCEVPtrToAddrExpr>(V);
9999+ if (Constant *CastOp = BuildConstantFromSCEV(P2I->getOperand()))
10000+ return ConstantExpr::getPtrToAddr(CastOp, P2I->getType());
10001+
10002+ return nullptr;
10003+ }
994510004 case scPtrToInt: {
994610005 const SCEVPtrToIntExpr *P2I = cast<SCEVPtrToIntExpr>(V);
994710006 if (Constant *CastOp = BuildConstantFromSCEV(P2I->getOperand()))
@@ -10000,6 +10059,7 @@ ScalarEvolution::getWithOperands(const SCEV *S,
1000010059 case scTruncate:
1000110060 case scZeroExtend:
1000210061 case scSignExtend:
10062+ case scPtrToAddr:
1000310063 case scPtrToInt:
1000410064 return getCastExpr(S->getSCEVType(), NewOps[0], S->getType());
1000510065 case scAddRecExpr: {
@@ -10084,6 +10144,7 @@ const SCEV *ScalarEvolution::computeSCEVAtScope(const SCEV *V, const Loop *L) {
1008410144 case scTruncate:
1008510145 case scZeroExtend:
1008610146 case scSignExtend:
10147+ case scPtrToAddr:
1008710148 case scPtrToInt:
1008810149 case scAddExpr:
1008910150 case scMulExpr:
@@ -14187,6 +14248,7 @@ ScalarEvolution::computeLoopDisposition(const SCEV *S, const Loop *L) {
1418714248 case scTruncate:
1418814249 case scZeroExtend:
1418914250 case scSignExtend:
14251+ case scPtrToAddr:
1419014252 case scPtrToInt:
1419114253 case scAddExpr:
1419214254 case scMulExpr:
@@ -14268,6 +14330,7 @@ ScalarEvolution::computeBlockDisposition(const SCEV *S, const BasicBlock *BB) {
1426814330 case scTruncate:
1426914331 case scZeroExtend:
1427014332 case scSignExtend:
14333+ case scPtrToAddr:
1427114334 case scPtrToInt:
1427214335 case scAddExpr:
1427314336 case scMulExpr:
0 commit comments