LFTR improvement to avoid truncation.

This is a reimplemntation of the patch originally in r186107.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@186215 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Andrew Trick
2013-07-12 22:08:48 +00:00
parent 807e6c71a8
commit 16404cc817
2 changed files with 76 additions and 6 deletions

View File

@@ -1590,15 +1590,41 @@ LinearFunctionTestReplace(Loop *L,
<< " RHS:\t" << *ExitCnt << "\n"
<< " IVCount:\t" << *IVCount << "\n");
IRBuilder<> Builder(BI);
// LFTR can ignore IV overflow and truncate to the width of
// BECount. This avoids materializing the add(zext(add)) expression.
IRBuilder<> Builder(BI);
if (SE->getTypeSizeInBits(CmpIndVar->getType())
> SE->getTypeSizeInBits(ExitCnt->getType())) {
CmpIndVar = Builder.CreateTrunc(CmpIndVar, ExitCnt->getType(),
"lftr.wideiv");
}
unsigned CmpIndVarSize = SE->getTypeSizeInBits(CmpIndVar->getType());
unsigned ExitCntSize = SE->getTypeSizeInBits(ExitCnt->getType());
if (CmpIndVarSize > ExitCntSize) {
const SCEVAddRecExpr *AR = cast<SCEVAddRecExpr>(SE->getSCEV(IndVar));
const SCEV *ARStart = AR->getStart();
const SCEV *ARStep = AR->getStepRecurrence(*SE);
// For constant IVCount, avoid truncation.
if (isa<SCEVConstant>(ARStart) && isa<SCEVConstant>(IVCount)) {
const APInt &Start = cast<SCEVConstant>(ARStart)->getValue()->getValue();
APInt Count = cast<SCEVConstant>(IVCount)->getValue()->getValue();
// Note that the post-inc value of BackedgeTakenCount may have overflowed
// above such that IVCount is now zero.
if (IVCount != BackedgeTakenCount && Count == 0) {
Count = APInt::getMaxValue(Count.getBitWidth()).zext(CmpIndVarSize);
++Count;
}
else
Count = Count.zext(CmpIndVarSize);
APInt NewLimit;
if (cast<SCEVConstant>(ARStep)->getValue()->isNegative())
NewLimit = Start - Count;
else
NewLimit = Start + Count;
ExitCnt = ConstantInt::get(CmpIndVar->getType(), NewLimit);
DEBUG(dbgs() << " Widen RHS:\t" << *ExitCnt << "\n");
} else {
CmpIndVar = Builder.CreateTrunc(CmpIndVar, ExitCnt->getType(),
"lftr.wideiv");
}
}
Value *Cond = Builder.CreateICmp(P, CmpIndVar, ExitCnt, "exitcond");
Value *OrigCond = BI->getCondition();
// It's tempting to use replaceAllUsesWith here to fully replace the old