diff --git a/llvm/include/llvm/Analysis/ScalarEvolution.h b/llvm/include/llvm/Analysis/ScalarEvolution.h --- a/llvm/include/llvm/Analysis/ScalarEvolution.h +++ b/llvm/include/llvm/Analysis/ScalarEvolution.h @@ -629,6 +629,7 @@ const SCEV *getZeroExtendExprImpl(const SCEV *Op, Type *Ty, unsigned Depth = 0); const SCEV *getSignExtendExpr(const SCEV *Op, Type *Ty, unsigned Depth = 0); + const SCEV *getSignExtendExprImpl(const SCEV *Op, Type *Ty, unsigned Depth = 0); const SCEV *getCastExpr(SCEVTypes Kind, const SCEV *Op, Type *Ty); const SCEV *getAnyExtendExpr(const SCEV *Op, Type *Ty); const SCEV *getAddExpr(SmallVectorImpl &Ops, diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp --- a/llvm/lib/Analysis/ScalarEvolution.cpp +++ b/llvm/lib/Analysis/ScalarEvolution.cpp @@ -1930,6 +1930,32 @@ assert(!Op->getType()->isPointerTy() && "Can't extend pointer!"); Ty = getEffectiveSCEVType(Ty); + FoldID ID; + ID.addInteger(scSignExtend); + ID.addPointer(Op); + ID.addPointer(Ty); + auto Iter = FoldCache.insert({ID, nullptr}); + if (Iter.second || !Iter.first->second) { + auto *S = getSignExtendExprImpl(Op, Ty, Depth); + + Iter = FoldCache.insert({ID, nullptr}); + Iter.first->second = S; + + auto R = FoldCacheUser.insert({S, {}}); + R.first->second.push_back(ID); + } + return Iter.first->second; +} + +const SCEV * +ScalarEvolution::getSignExtendExprImpl(const SCEV *Op, Type *Ty, unsigned Depth) { + assert(getTypeSizeInBits(Op->getType()) < getTypeSizeInBits(Ty) && + "This is not an extending conversion!"); + assert(isSCEVable(Ty) && + "This is not a conversion to a SCEVable type!"); + assert(!Op->getType()->isPointerTy() && "Can't extend pointer!"); + Ty = getEffectiveSCEVType(Ty); + // Fold if the operand is constant. if (const SCEVConstant *SC = dyn_cast(Op)) return getConstant(