Skip to content

Commit 7650c1d

Browse files
LebedevRImemfrob
authored andcommitted
[SCEV] SCEVPtrToIntExpr simplifications
If we've got an SCEVPtrToIntExpr(op), where op is not an SCEVUnknown, we want to sink the SCEVPtrToIntExpr into an operand, so that the operation is performed on integers, and eventually we end up with just an `SCEVPtrToIntExpr(SCEVUnknown)`. Reviewed By: mkazantsev Differential Revision: https://reviews.llvm.org/D89692
1 parent a9c2dc2 commit 7650c1d

File tree

5 files changed

+118
-77
lines changed

5 files changed

+118
-77
lines changed

llvm/lib/Analysis/ScalarEvolution.cpp

Lines changed: 50 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1047,17 +1047,61 @@ const SCEV *ScalarEvolution::getPtrToIntExpr(const SCEV *Op, Type *Ty,
10471047
ID.AddPointer(Op);
10481048
void *IP = nullptr;
10491049
if (const SCEV *S = UniqueSCEVs.FindNodeOrInsertPos(ID, IP))
1050-
return getTruncateOrZeroExtend(S, Ty);
1050+
return getTruncateOrZeroExtend(S, Ty, Depth);
10511051

1052-
assert(!isa<SCEVConstant>(Op) &&
1053-
"SCEVConstant is an integer, no constant folding to do.");
1052+
assert((isa<SCEVNAryExpr>(Op) || isa<SCEVUnknown>(Op)) &&
1053+
"We can only gen an nary expression, or an unknown here.");
10541054

1055-
// FIXME: simplifications.
1055+
Type *IntPtrTy = getDataLayout().getIntPtrType(Op->getType());
1056+
1057+
// If the input operand is not an unknown (and thus is an nary expression),
1058+
// sink the cast to operands, so that the operation is performed on integers,
1059+
// and we eventually end up with just an ptrtoint(unknown).
1060+
if (const SCEVNAryExpr *NaryExpr = dyn_cast<SCEVNAryExpr>(Op)) {
1061+
SmallVector<const SCEV *, 2> NewOps;
1062+
NewOps.reserve(NaryExpr->getNumOperands());
1063+
for (const SCEV *Op : NaryExpr->operands())
1064+
NewOps.push_back(Op->getType()->isPointerTy()
1065+
? getPtrToIntExpr(Op, IntPtrTy, Depth + 1)
1066+
: Op);
1067+
const SCEV *NewNaryExpr = nullptr;
1068+
switch (SCEVTypes SCEVType = NaryExpr->getSCEVType()) {
1069+
case scAddExpr:
1070+
NewNaryExpr = getAddExpr(NewOps, NaryExpr->getNoWrapFlags(), Depth + 1);
1071+
break;
1072+
case scAddRecExpr:
1073+
NewNaryExpr =
1074+
getAddRecExpr(NewOps, cast<SCEVAddRecExpr>(NaryExpr)->getLoop(),
1075+
NaryExpr->getNoWrapFlags());
1076+
break;
1077+
case scUMaxExpr:
1078+
case scSMaxExpr:
1079+
case scUMinExpr:
1080+
case scSMinExpr:
1081+
NewNaryExpr = getMinMaxExpr(SCEVType, NewOps);
1082+
break;
1083+
1084+
case scMulExpr:
1085+
NewNaryExpr = getMulExpr(NewOps, NaryExpr->getNoWrapFlags(), Depth + 1);
1086+
break;
1087+
case scUDivExpr:
1088+
NewNaryExpr = getUDivExpr(NewOps[0], NewOps[1]);
1089+
break;
1090+
case scConstant:
1091+
case scTruncate:
1092+
case scZeroExtend:
1093+
case scSignExtend:
1094+
case scPtrToInt:
1095+
case scUnknown:
1096+
case scCouldNotCompute:
1097+
llvm_unreachable("We can't get these types here.");
1098+
}
1099+
return getTruncateOrZeroExtend(NewNaryExpr, Ty, Depth);
1100+
}
10561101

10571102
// The cast wasn't folded; create an explicit cast node. We can reuse
10581103
// the existing insert position since if we get here, we won't have
10591104
// made any changes which would invalidate it.
1060-
Type *IntPtrTy = getDataLayout().getIntPtrType(Op->getType());
10611105
assert(getDataLayout().getTypeSizeInBits(getEffectiveSCEVType(
10621106
Op->getType())) == getDataLayout().getTypeSizeInBits(IntPtrTy) &&
10631107
"We can only model ptrtoint if SCEV's effective (integer) type is "
@@ -1066,7 +1110,7 @@ const SCEV *ScalarEvolution::getPtrToIntExpr(const SCEV *Op, Type *Ty,
10661110
SCEVPtrToIntExpr(ID.Intern(SCEVAllocator), Op, IntPtrTy);
10671111
UniqueSCEVs.InsertNode(S, IP);
10681112
addToLoopUseLists(S);
1069-
return getTruncateOrZeroExtend(S, Ty);
1113+
return getTruncateOrZeroExtend(S, Ty, Depth);
10701114
}
10711115

10721116
const SCEV *ScalarEvolution::getTruncateExpr(const SCEV *Op, Type *Ty,

0 commit comments

Comments
 (0)