[PATCH] Little improvement in IndVarSimplify
Andrew Trick
atrick at apple.com
Fri Jul 12 17:04:07 PDT 2013
On Jul 12, 2013, at 4:20 AM, Chandler Carruth <chandlerc at google.com> wrote:
> I've reverted in r186152. It caused a really serious regression. Test case attached here (it's not quite in the right form for committing yet -- you can probably write it more directly against indvars once debugged.
Many thanks for the test case. I cleaned up the code so corner cases should be more clear and reimplemented the patch in r186215.
-Andy
> % cat bad2.ll
> ; ModuleID = '<stdin>'
> 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-n8:16:32:64-S128"
> target triple = "x86_64-unknown-linux-gnu"
>
> @.str = private unnamed_addr constant [4 x i8] c"%d\0A\00", align 1
>
> ; Function Attrs: nounwind uwtable
> define i32 @main() #0 {
> entry:
> br label %do.body
>
> do.body: ; preds = %do.body, %entry
> %first.0 = phi i8 [ 0, %entry ], [ %inc, %do.body ]
> %conv = zext i8 %first.0 to i32
> %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i64 0, i64 0), i32 %conv) #1
> %inc = add i8 %first.0, 1
> %cmp = icmp eq i8 %first.0, -1
> br i1 %cmp, label %do.end, label %do.body
>
> do.end: ; preds = %do.body
> ret i32 0
> }
>
> declare i32 @printf(i8*, ...)
>
> attributes #0 = { nounwind uwtable }
> attributes #1 = { nounwind }
>
> % ./bin/llc -O0 <bad2.ll | ./bin/clang -x assembler -
> % ./a.out
> 0
> 1
> 2
> <snip>
> 255
>
> % ./bin/opt -S -indvars <bad2.ll | ./bin/llc -O0 | ./bin/clang -x assembler -
> 0
> 1
> 2
> <snip>
> 255
> 256
> 257
> ...
>
> This goes on until the 64-bit register wraps back to zero. ;] It looks like the problem is extending the integer induction variable and exit value without accounting for wrapping.
>
> The bad2.ll test case is attached for easier access.
>
>
>
> On Thu, Jul 11, 2013 at 10:38 AM, Andrew Trick <atrick at apple.com> wrote:
> On Jul 11, 2013, at 12:29 AM, Michele Scandale <michele.scandale at gmail.com> wrote:
>
>> Here an updated version of the patch fixing code style as suggested by Andrew.
>
> Committed r186107. Thanks.
> -Andy
>
>>
>> Thanks again.
>>
>> Michele Scandale
>>
>> Hi atrick,
>>
>> http://llvm-reviews.chandlerc.com/D1112
>>
>> CHANGE SINCE LAST DIFF
>> http://llvm-reviews.chandlerc.com/D1112?vs=2713&id=2765#toc
>>
>> Files:
>> lib/Transforms/Scalar/IndVarSimplify.cpp
>> test/Transforms/IndVarSimplify/exitcnt-const-arstart-const-opt.ll
>>
>> Index: lib/Transforms/Scalar/IndVarSimplify.cpp
>> ===================================================================
>> --- lib/Transforms/Scalar/IndVarSimplify.cpp
>> +++ lib/Transforms/Scalar/IndVarSimplify.cpp
>> @@ -1612,10 +1612,29 @@
>> << " 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");
>> Index: test/Transforms/IndVarSimplify/exitcnt-const-arstart-const-opt.ll
>> ===================================================================
>> --- test/Transforms/IndVarSimplify/exitcnt-const-arstart-const-opt.ll
>> +++ test/Transforms/IndVarSimplify/exitcnt-const-arstart-const-opt.ll
>> @@ -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 }
>> <D1112.2.patch>_______________________________________________
>> llvm-commits mailing list
>> llvm-commits at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>
>
> <bad2.ll>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20130712/ccb02c51/attachment.html>
More information about the llvm-commits
mailing list