diff options
author | Dale Johannesen <dalej@apple.com> | 2009-02-09 22:14:15 +0000 |
---|---|---|
committer | Dale Johannesen <dalej@apple.com> | 2009-02-09 22:14:15 +0000 |
commit | 1de17d574c0a4503f7dd6a4a3efce6f9353bf3c5 (patch) | |
tree | f5d17666c3504d966c0a8bd01671d3d6174b40c9 /lib/Transforms/Scalar/LoopStrengthReduce.cpp | |
parent | 65b52dffe02d6ffce8d63b4fe2d7714d69968476 (diff) |
Fix PR 3471, and some cleanups.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@64177 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms/Scalar/LoopStrengthReduce.cpp')
-rw-r--r-- | lib/Transforms/Scalar/LoopStrengthReduce.cpp | 49 |
1 files changed, 32 insertions, 17 deletions
diff --git a/lib/Transforms/Scalar/LoopStrengthReduce.cpp b/lib/Transforms/Scalar/LoopStrengthReduce.cpp index 425add0a8b..a5fcdb43be 100644 --- a/lib/Transforms/Scalar/LoopStrengthReduce.cpp +++ b/lib/Transforms/Scalar/LoopStrengthReduce.cpp @@ -430,8 +430,8 @@ static bool getSCEVStartAndStride(const SCEVHandle &SH, Loop *L, if (!AddRec->isAffine()) return false; // If Start contains an SCEVAddRecExpr from a different loop, other than an - // outer loop of the current loop, reject it. SCEV has no concept of operating - // on one loop at a time so don't confuse it with such expressions. + // outer loop of the current loop, reject it. SCEV has no concept of + // operating on one loop at a time so don't confuse it with such expressions. if (containsAddRecFromDifferentLoop(Start, L)) return false; @@ -774,14 +774,14 @@ void BasedUser::RewriteInstructionToUseNewBase(const SCEVHandle &NewBase, // which need not be an immediate predecessor of this PHI. This way we // need only one copy of it even if it is referenced multiple times in // the PHI. We don't do this when the original expression is inside the - // loop because multiple copies sometimes do useful sinking of code in that - // case(?). + // loop because multiple copies sometimes do useful sinking of code in + // that case(?). Instruction *OldLoc = dyn_cast<Instruction>(OperandValToReplace); if (L->contains(OldLoc->getParent())) { - // If this is a critical edge, split the edge so that we do not insert the - // code on all predecessor/successor paths. We do this unless this is the - // canonical backedge for this loop, as this can make some inserted code - // be in an illegal position. + // If this is a critical edge, split the edge so that we do not insert + // the code on all predecessor/successor paths. We do this unless this + // is the canonical backedge for this loop, as this can make some + // inserted code be in an illegal position. BasicBlock *PHIPred = PN->getIncomingBlock(i); if (e != 1 && PHIPred->getTerminator()->getNumSuccessors() > 1 && (PN->getParent() != L->getHeader() || !L->contains(PHIPred))) { @@ -1224,19 +1224,21 @@ bool LoopStrengthReduce::ValidStride(bool HasBaseReg, return true; } -/// RequiresTypeConversion - Returns true if converting Ty to NewTy is not +/// RequiresTypeConversion - Returns true if converting Ty1 to Ty2 is not /// a nop. bool LoopStrengthReduce::RequiresTypeConversion(const Type *Ty1, const Type *Ty2) { if (Ty1 == Ty2) return false; + if (Ty1->canLosslesslyBitCastTo(Ty2)) + return false; if (TLI && TLI->isTruncateFree(Ty1, Ty2)) return false; - return (!Ty1->canLosslesslyBitCastTo(Ty2) && - !(isa<PointerType>(Ty2) && - Ty1->canLosslesslyBitCastTo(UIntPtrTy)) && - !(isa<PointerType>(Ty1) && - Ty2->canLosslesslyBitCastTo(UIntPtrTy))); + if (isa<PointerType>(Ty2) && Ty1->canLosslesslyBitCastTo(UIntPtrTy)) + return false; + if (isa<PointerType>(Ty1) && Ty2->canLosslesslyBitCastTo(UIntPtrTy)) + return false; + return true; } /// CheckForIVReuse - Returns the multiple if the stride is the multiple @@ -1661,15 +1663,28 @@ void LoopStrengthReduce::StrengthReduceStridedIVUsers(const SCEVHandle &Stride, Rewriter.clear(); // If we are reusing the iv, then it must be multiplied by a constant - // factor take advantage of addressing mode scale component. + // factor to take advantage of the addressing mode scale component. if (!isa<SCEVConstant>(RewriteFactor) || !cast<SCEVConstant>(RewriteFactor)->isZero()) { // If we're reusing an IV with a nonzero base (currently this happens // only when all reuses are outside the loop) subtract that base here. // The base has been used to initialize the PHI node but we don't want // it here. - if (!ReuseIV.Base->isZero()) - RewriteExpr = SE->getMinusSCEV(RewriteExpr, ReuseIV.Base); + if (!ReuseIV.Base->isZero()) { + SCEVHandle typedBase = ReuseIV.Base; + if (RewriteExpr->getType()->getPrimitiveSizeInBits() != + ReuseIV.Base->getType()->getPrimitiveSizeInBits()) { + // It's possible the original IV is a larger type than the new IV, + // in which case we have to truncate the Base. We checked in + // RequiresTypeConversion that this is valid. + assert (RewriteExpr->getType()->getPrimitiveSizeInBits() < + ReuseIV.Base->getType()->getPrimitiveSizeInBits() && + "Unexpected lengthening conversion!"); + typedBase = SE->getTruncateExpr(ReuseIV.Base, + RewriteExpr->getType()); + } + RewriteExpr = SE->getMinusSCEV(RewriteExpr, typedBase); + } // Multiply old variable, with base removed, by new scale factor. RewriteExpr = SE->getMulExpr(RewriteFactor, |