From 2ce84c8d4784dfd24458a63db8d531917d2f8ba5 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Sat, 13 Jun 2009 15:56:47 +0000 Subject: [PATCH] Add a ScalarEvolution::getAnyExtendExpr utility function for performing extension with unspecified bits. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@73293 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Analysis/ScalarEvolution.h | 7 ++++ lib/Analysis/ScalarEvolution.cpp | 59 +++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+) diff --git a/include/llvm/Analysis/ScalarEvolution.h b/include/llvm/Analysis/ScalarEvolution.h index e3d429934cc..41725be1ca3 100644 --- a/include/llvm/Analysis/ScalarEvolution.h +++ b/include/llvm/Analysis/ScalarEvolution.h @@ -393,6 +393,7 @@ namespace llvm { SCEVHandle getTruncateExpr(const SCEVHandle &Op, const Type *Ty); SCEVHandle getZeroExtendExpr(const SCEVHandle &Op, const Type *Ty); SCEVHandle getSignExtendExpr(const SCEVHandle &Op, const Type *Ty); + SCEVHandle getAnyExtendExpr(const SCEVHandle &Op, const Type *Ty); SCEVHandle getAddExpr(std::vector &Ops); SCEVHandle getAddExpr(const SCEVHandle &LHS, const SCEVHandle &RHS) { std::vector Ops; @@ -465,6 +466,12 @@ namespace llvm { /// it is sign extended. The conversion must not be narrowing. SCEVHandle getNoopOrSignExtend(const SCEVHandle &V, const Type *Ty); + /// getNoopOrAnyExtend - Return a SCEV corresponding to a conversion of + /// the input value to the specified type. If the type must be extended, + /// it is extended with unspecified bits. The conversion must not be + /// narrowing. + SCEVHandle getNoopOrAnyExtend(const SCEVHandle &V, const Type *Ty); + /// getTruncateOrNoop - Return a SCEV corresponding to a conversion of the /// input value to the specified type. The conversion must not be /// widening. diff --git a/lib/Analysis/ScalarEvolution.cpp b/lib/Analysis/ScalarEvolution.cpp index fd97db8a9dc..98ab6f484ea 100644 --- a/lib/Analysis/ScalarEvolution.cpp +++ b/lib/Analysis/ScalarEvolution.cpp @@ -937,6 +937,48 @@ SCEVHandle ScalarEvolution::getSignExtendExpr(const SCEVHandle &Op, return Result; } +/// getAnyExtendExpr - Return a SCEV for the given operand extended with +/// unspecified bits out to the given type. +/// +SCEVHandle ScalarEvolution::getAnyExtendExpr(const SCEVHandle &Op, + const Type *Ty) { + assert(getTypeSizeInBits(Op->getType()) < getTypeSizeInBits(Ty) && + "This is not an extending conversion!"); + assert(isSCEVable(Ty) && + "This is not a conversion to a SCEVable type!"); + Ty = getEffectiveSCEVType(Ty); + + // Sign-extend negative constants. + if (const SCEVConstant *SC = dyn_cast(Op)) + if (SC->getValue()->getValue().isNegative()) + return getSignExtendExpr(Op, Ty); + + // Peel off a truncate cast. + if (const SCEVTruncateExpr *T = dyn_cast(Op)) { + SCEVHandle NewOp = T->getOperand(); + if (getTypeSizeInBits(NewOp->getType()) < getTypeSizeInBits(Ty)) + return getAnyExtendExpr(NewOp, Ty); + return getTruncateOrNoop(NewOp, Ty); + } + + // Next try a zext cast. If the cast is folded, use it. + SCEVHandle ZExt = getZeroExtendExpr(Op, Ty); + if (!isa(ZExt)) + return ZExt; + + // Next try a sext cast. If the cast is folded, use it. + SCEVHandle SExt = getSignExtendExpr(Op, Ty); + if (!isa(SExt)) + return SExt; + + // If the expression is obviously signed, use the sext cast value. + if (isa(Op)) + return SExt; + + // Absent any other information, use the zext cast value. + return ZExt; +} + /// getAddExpr - Get a canonical add expression, or something simpler if /// possible. SCEVHandle ScalarEvolution::getAddExpr(std::vector &Ops) { @@ -1903,6 +1945,23 @@ ScalarEvolution::getNoopOrSignExtend(const SCEVHandle &V, const Type *Ty) { return getSignExtendExpr(V, Ty); } +/// getNoopOrAnyExtend - Return a SCEV corresponding to a conversion of +/// the input value to the specified type. If the type must be extended, +/// it is extended with unspecified bits. The conversion must not be +/// narrowing. +SCEVHandle +ScalarEvolution::getNoopOrAnyExtend(const SCEVHandle &V, const Type *Ty) { + const Type *SrcTy = V->getType(); + assert((SrcTy->isInteger() || (TD && isa(SrcTy))) && + (Ty->isInteger() || (TD && isa(Ty))) && + "Cannot noop or any extend with non-integer arguments!"); + assert(getTypeSizeInBits(SrcTy) <= getTypeSizeInBits(Ty) && + "getNoopOrAnyExtend cannot truncate!"); + if (getTypeSizeInBits(SrcTy) == getTypeSizeInBits(Ty)) + return V; // No conversion + return getAnyExtendExpr(V, Ty); +} + /// getTruncateOrNoop - Return a SCEV corresponding to a conversion of the /// input value to the specified type. The conversion must not be widening. SCEVHandle -- 2.11.0