1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-23 19:23:23 +01:00

indvars: Improve LFTR by eliminating truncation when comparing against a constant.

Patch by Michele Scandale!

Adds a special handling of the case where, during the loop exit
condition rewriting, the exit value is a constant of bitwidth lower
than the type of the induction variable: instead of introducing a
trunc operation in order to match correctly the operand types, it
allows to convert the constant value to an equivalent constant,
depending on the initial value of the induction variable and the trip
count, in order have an equivalent comparison between the induction
variable and the new constant.

llvm-svn: 186107
This commit is contained in:
Andrew Trick 2013-07-11 17:08:59 +00:00
parent adac2cbb4a
commit fe577c9f45
2 changed files with 48 additions and 4 deletions

View File

@ -1612,10 +1612,29 @@ LinearFunctionTestReplace(Loop *L,
<< " IVCount:\t" << *IVCount << "\n");
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);
if (isa<SCEVConstant>(ARStart) && isa<SCEVConstant>(IVCount)) {
const APInt &Start = cast<SCEVConstant>(ARStart)->getValue()->getValue();
const APInt &Count = cast<SCEVConstant>(IVCount)->getValue()->getValue();
APInt NewLimit;
if (cast<SCEVConstant>(ARStep)->getValue()->isNegative())
NewLimit = Start - Count.zext(CmpIndVarSize);
else
NewLimit = Start + Count.zext(CmpIndVarSize);
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");

View File

@ -0,0 +1,25 @@
;RUN: opt -S %s -indvars | FileCheck %s
; Function Attrs: nounwind uwtable
define void @foo() #0 {
entry:
br label %for.body
for.body: ; preds = %entry, %for.body
%i.01 = phi i16 [ 0, %entry ], [ %inc, %for.body ]
%conv2 = sext i16 %i.01 to i32
call void @bar(i32 %conv2) #1
%inc = add i16 %i.01, 1
;CHECK-NOT: %lftr.wideiv = trunc i32 %indvars.iv.next to i16
;CHECK: %exitcond = icmp ne i32 %indvars.iv.next, 512
%cmp = icmp slt i16 %inc, 512
br i1 %cmp, label %for.body, label %for.end
for.end: ; preds = %for.body
ret void
}
declare void @bar(i32)
attributes #0 = { nounwind uwtable }
attributes #1 = { nounwind }