@@ -1047,17 +1047,61 @@ const SCEV *ScalarEvolution::getPtrToIntExpr(const SCEV *Op, Type *Ty,
1047
1047
ID.AddPointer(Op);
1048
1048
void *IP = nullptr;
1049
1049
if (const SCEV *S = UniqueSCEVs.FindNodeOrInsertPos(ID, IP))
1050
- return getTruncateOrZeroExtend(S, Ty);
1050
+ return getTruncateOrZeroExtend(S, Ty, Depth );
1051
1051
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 .");
1054
1054
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
+ }
1056
1101
1057
1102
// The cast wasn't folded; create an explicit cast node. We can reuse
1058
1103
// the existing insert position since if we get here, we won't have
1059
1104
// made any changes which would invalidate it.
1060
- Type *IntPtrTy = getDataLayout().getIntPtrType(Op->getType());
1061
1105
assert(getDataLayout().getTypeSizeInBits(getEffectiveSCEVType(
1062
1106
Op->getType())) == getDataLayout().getTypeSizeInBits(IntPtrTy) &&
1063
1107
"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,
1066
1110
SCEVPtrToIntExpr(ID.Intern(SCEVAllocator), Op, IntPtrTy);
1067
1111
UniqueSCEVs.InsertNode(S, IP);
1068
1112
addToLoopUseLists(S);
1069
- return getTruncateOrZeroExtend(S, Ty);
1113
+ return getTruncateOrZeroExtend(S, Ty, Depth );
1070
1114
}
1071
1115
1072
1116
const SCEV *ScalarEvolution::getTruncateExpr(const SCEV *Op, Type *Ty,
0 commit comments