[llvm] r186107 - indvars: Improve LFTR by eliminating truncation when comparing against a constant.

Andrew Trick atrick at apple.com
Thu Jul 11 10:09:00 PDT 2013


Author: atrick
Date: Thu Jul 11 12:08:59 2013
New Revision: 186107

URL: http://llvm.org/viewvc/llvm-project?rev=186107&view=rev
Log:
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.

Added:
    llvm/trunk/test/Transforms/IndVarSimplify/exitcnt-const-arstart-const-opt.ll
Modified:
    llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp

Modified: llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp?rev=186107&r1=186106&r2=186107&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp Thu Jul 11 12:08:59 2013
@@ -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");

Added: llvm/trunk/test/Transforms/IndVarSimplify/exitcnt-const-arstart-const-opt.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/IndVarSimplify/exitcnt-const-arstart-const-opt.ll?rev=186107&view=auto
==============================================================================
--- llvm/trunk/test/Transforms/IndVarSimplify/exitcnt-const-arstart-const-opt.ll (added)
+++ llvm/trunk/test/Transforms/IndVarSimplify/exitcnt-const-arstart-const-opt.ll Thu Jul 11 12:08:59 2013
@@ -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 }





More information about the llvm-commits mailing list