_test:
authorChris Lattner <sabre@nondot.org>
Mon, 12 Sep 2005 06:04:47 +0000 (06:04 +0000)
committerChris Lattner <sabre@nondot.org>
Mon, 12 Sep 2005 06:04:47 +0000 (06:04 +0000)
        li r2, 0
LBB_test_1:     ; no_exit.2
        li r5, 0
        stw r5, 0(r3)
        addi r2, r2, 1
        addi r3, r3, 4
        cmpwi cr0, r2, 701
        blt cr0, LBB_test_1     ; no_exit.2
LBB_test_2:     ; loopexit.2.loopexit
        addi r2, r2, 1
        stw r2, 0(r4)
        blr
[zion ~/llvm]$ cat > ~/xx
Uses of IV's outside of the loop should use hte post-incremented version
of the IV, not the preincremented version.  This helps many loops (e.g. in sixtrack)
which used to generate code like this (this is the code from the
dont-hoist-simple-loop-constants.ll testcase):

_test:
        li r2, 0                 **** IV starts at 0
LBB_test_1:     ; no_exit.2
        or r5, r2, r2            **** Copy for loop exit
        li r2, 0
        stw r2, 0(r3)
        addi r3, r3, 4
        addi r2, r5, 1
        addi r6, r5, 2           **** IV+2
        cmpwi cr0, r6, 701
        blt cr0, LBB_test_1     ; no_exit.2
LBB_test_2:     ; loopexit.2.loopexit
        addi r2, r5, 2       ****  IV+2
        stw r2, 0(r4)
        blr

And now generated code like this:

_test:
        li r2, 1               *** IV starts at 1
LBB_test_1:     ; no_exit.2
        li r5, 0
        stw r5, 0(r3)
        addi r2, r2, 1
        addi r3, r3, 4
        cmpwi cr0, r2, 701     *** IV.postinc + 0
        blt cr0, LBB_test_1
LBB_test_2:     ; loopexit.2.loopexit
        stw r2, 0(r4)          *** IV.postinc + 0
        blr

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@23313 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/Scalar/LoopStrengthReduce.cpp

index f8b208e47517960a8360d6493dffc37a8ced05cd..29043a152cfe96902c80f426bb1a6f87d513748e 100644 (file)
@@ -52,7 +52,7 @@ namespace {
     // isUseOfPostIncrementedValue - True if this should use the
     // post-incremented version of this IV, not the preincremented version.
     // This can only be set in special cases, such as the terminating setcc
-    // instruction for a loop.
+    // instruction for a loop or uses dominated by the loop.
     bool isUseOfPostIncrementedValue;
     
     IVStrideUse(const SCEVHandle &Offs, Instruction *U, Value *O)
@@ -351,8 +351,17 @@ bool LoopStrengthReduce::AddUsersIfInteresting(Instruction *I, Loop *L,
 
     if (AddUserToIVUsers) {
       // Okay, we found a user that we cannot reduce.  Analyze the instruction
-      // and decide what to do with it.
-      IVUsesByStride[Stride].addUser(Start, User, I);
+      // and decide what to do with it.  If we are a use inside of the loop, use
+      // the value before incrementation, otherwise use it after incrementation.
+      if (L->contains(User->getParent())) {
+        IVUsesByStride[Stride].addUser(Start, User, I);
+      } else {
+        // The value used will be incremented by the stride more than we are
+        // expecting, so subtract this off.
+        SCEVHandle NewStart = SCEV::getMinusSCEV(Start, Stride);
+        IVUsesByStride[Stride].addUser(NewStart, User, I);
+        IVUsesByStride[Stride].Users.back().isUseOfPostIncrementedValue = true;
+      }
     }
   }
   return true;
@@ -387,7 +396,8 @@ namespace {
     // isUseOfPostIncrementedValue - True if this should use the
     // post-incremented version of this IV, not the preincremented version.
     // This can only be set in special cases, such as the terminating setcc
-    // instruction for a loop.
+    // instruction for a loop and uses outside the loop that are dominated by
+    // the loop.
     bool isUseOfPostIncrementedValue;
     
     BasedUser(IVStrideUse &IVSU)
@@ -842,7 +852,11 @@ void LoopStrengthReduce::StrengthReduceStridedIVUsers(const SCEVHandle &Stride,
       Value *RewriteOp = NewPHI;
       if (User.isUseOfPostIncrementedValue) {
         RewriteOp = IncV;
-        User.Inst->moveBefore(LatchBlock->getTerminator());
+
+        // If this user is in the loop, make sure it is the last thing in the
+        // loop to ensure it is dominated by the increment.
+        if (L->contains(User.Inst->getParent()))
+          User.Inst->moveBefore(LatchBlock->getTerminator());
       }
       SCEVHandle RewriteExpr = SCEVUnknown::get(RewriteOp);