Fix PR 3471, and some cleanups.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@64177 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Dale Johannesen 2009-02-09 22:14:15 +00:00
parent 65b52dffe0
commit 1de17d574c
2 changed files with 65 additions and 17 deletions

View File

@ -430,8 +430,8 @@ static bool getSCEVStartAndStride(const SCEVHandle &SH, Loop *L,
if (!AddRec->isAffine()) return false; if (!AddRec->isAffine()) return false;
// If Start contains an SCEVAddRecExpr from a different loop, other than an // 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 // outer loop of the current loop, reject it. SCEV has no concept of
// on one loop at a time so don't confuse it with such expressions. // operating on one loop at a time so don't confuse it with such expressions.
if (containsAddRecFromDifferentLoop(Start, L)) if (containsAddRecFromDifferentLoop(Start, L))
return false; 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 // 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 // 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 // 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 // loop because multiple copies sometimes do useful sinking of code in
// case(?). // that case(?).
Instruction *OldLoc = dyn_cast<Instruction>(OperandValToReplace); Instruction *OldLoc = dyn_cast<Instruction>(OperandValToReplace);
if (L->contains(OldLoc->getParent())) { if (L->contains(OldLoc->getParent())) {
// If this is a critical edge, split the edge so that we do not insert the // If this is a critical edge, split the edge so that we do not insert
// code on all predecessor/successor paths. We do this unless this is the // the code on all predecessor/successor paths. We do this unless this
// canonical backedge for this loop, as this can make some inserted code // is the canonical backedge for this loop, as this can make some
// be in an illegal position. // inserted code be in an illegal position.
BasicBlock *PHIPred = PN->getIncomingBlock(i); BasicBlock *PHIPred = PN->getIncomingBlock(i);
if (e != 1 && PHIPred->getTerminator()->getNumSuccessors() > 1 && if (e != 1 && PHIPred->getTerminator()->getNumSuccessors() > 1 &&
(PN->getParent() != L->getHeader() || !L->contains(PHIPred))) { (PN->getParent() != L->getHeader() || !L->contains(PHIPred))) {
@ -1224,19 +1224,21 @@ bool LoopStrengthReduce::ValidStride(bool HasBaseReg,
return true; return true;
} }
/// RequiresTypeConversion - Returns true if converting Ty to NewTy is not /// RequiresTypeConversion - Returns true if converting Ty1 to Ty2 is not
/// a nop. /// a nop.
bool LoopStrengthReduce::RequiresTypeConversion(const Type *Ty1, bool LoopStrengthReduce::RequiresTypeConversion(const Type *Ty1,
const Type *Ty2) { const Type *Ty2) {
if (Ty1 == Ty2) if (Ty1 == Ty2)
return false; return false;
if (Ty1->canLosslesslyBitCastTo(Ty2))
return false;
if (TLI && TLI->isTruncateFree(Ty1, Ty2)) if (TLI && TLI->isTruncateFree(Ty1, Ty2))
return false; return false;
return (!Ty1->canLosslesslyBitCastTo(Ty2) && if (isa<PointerType>(Ty2) && Ty1->canLosslesslyBitCastTo(UIntPtrTy))
!(isa<PointerType>(Ty2) && return false;
Ty1->canLosslesslyBitCastTo(UIntPtrTy)) && if (isa<PointerType>(Ty1) && Ty2->canLosslesslyBitCastTo(UIntPtrTy))
!(isa<PointerType>(Ty1) && return false;
Ty2->canLosslesslyBitCastTo(UIntPtrTy))); return true;
} }
/// CheckForIVReuse - Returns the multiple if the stride is the multiple /// CheckForIVReuse - Returns the multiple if the stride is the multiple
@ -1661,15 +1663,28 @@ void LoopStrengthReduce::StrengthReduceStridedIVUsers(const SCEVHandle &Stride,
Rewriter.clear(); Rewriter.clear();
// If we are reusing the iv, then it must be multiplied by a constant // 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) || if (!isa<SCEVConstant>(RewriteFactor) ||
!cast<SCEVConstant>(RewriteFactor)->isZero()) { !cast<SCEVConstant>(RewriteFactor)->isZero()) {
// If we're reusing an IV with a nonzero base (currently this happens // 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. // 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 // The base has been used to initialize the PHI node but we don't want
// it here. // it here.
if (!ReuseIV.Base->isZero()) if (!ReuseIV.Base->isZero()) {
RewriteExpr = SE->getMinusSCEV(RewriteExpr, ReuseIV.Base); 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. // Multiply old variable, with base removed, by new scale factor.
RewriteExpr = SE->getMulExpr(RewriteFactor, RewriteExpr = SE->getMulExpr(RewriteFactor,

View File

@ -0,0 +1,33 @@
; RUN: llvm-as < %s | llc
; This used to crash.
; ModuleID = 'bugpoint-reduced-simplified.bc'
target datalayout ="e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128"
target triple = "x86_64-unknown-linux-gnu"
define void @parse_number(i8* nocapture %p) nounwind {
entry:
%shift.0 = select i1 false, i32 4, i32 2 ; <i32> [#uses=1]
br label %bb47
bb47: ; preds = %bb47, %entry
br i1 false, label %bb54, label %bb47
bb54: ; preds = %bb47
br i1 false, label %bb56, label %bb66
bb56: ; preds = %bb62, %bb54
%p_addr.0.pn.rec = phi i64 [ %p_addr.6.rec, %bb62 ], [ 0, %bb54 ] ; <i64> [#uses=2]
%ch.6.in.in = phi i8* [ %p_addr.6, %bb62 ], [ null, %bb54 ] ; <i8*> [#uses=0]
%indvar202 = trunc i64 %p_addr.0.pn.rec to i32 ; <i32>[#uses=1]
%frac_bits.0 = mul i32 %indvar202, %shift.0 ; <i32>[#uses=1]
%p_addr.6.rec = add i64 %p_addr.0.pn.rec, 1 ; <i64>[#uses=2]
%p_addr.6 = getelementptr i8* null, i64 %p_addr.6.rec ; <i8*>[#uses=1]
br i1 false, label %bb66, label %bb62
bb62: ; preds = %bb56
br label %bb56
bb66: ; preds = %bb56, %bb54
%frac_bits.1 = phi i32 [ 0, %bb54 ], [ %frac_bits.0, %bb56 ] ; <i32> [#uses=0]
unreachable
}