[llvm-commits] [llvm] r139186 - in /llvm/trunk: lib/Analysis/ScalarEvolution.cpp test/Analysis/ScalarEvolution/SolveQuadraticEquation.ll

Nick Lewycky nicholas at mxc.ca
Tue Sep 6 14:42:18 PDT 2011


Author: nicholas
Date: Tue Sep  6 16:42:18 2011
New Revision: 139186

URL: http://llvm.org/viewvc/llvm-project?rev=139186&view=rev
Log:
This transform only handles two-operand AddRec's. Prevent it from trying to
handle anything more complex. Fixes PR10383 again!

Modified:
    llvm/trunk/lib/Analysis/ScalarEvolution.cpp
    llvm/trunk/test/Analysis/ScalarEvolution/SolveQuadraticEquation.ll

Modified: llvm/trunk/lib/Analysis/ScalarEvolution.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ScalarEvolution.cpp?rev=139186&r1=139185&r2=139186&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/ScalarEvolution.cpp (original)
+++ llvm/trunk/lib/Analysis/ScalarEvolution.cpp Tue Sep  6 16:42:18 2011
@@ -1974,7 +1974,8 @@
     // multiplied together.  If so, we can fold them.
     for (unsigned OtherIdx = Idx+1;
          OtherIdx < Ops.size() && isa<SCEVAddRecExpr>(Ops[OtherIdx]);
-         ++OtherIdx)
+         ++OtherIdx) {
+      bool Retry = false;
       if (AddRecLoop == cast<SCEVAddRecExpr>(Ops[OtherIdx])->getLoop()) {
         // {A,+,B}<L> * {C,+,D}<L>  -->  {A*C,+,A*D + B*C + B*D,+,2*B*D}<L>
         //
@@ -1985,7 +1986,7 @@
         // Rearranging, X = x, Y = y+z, Z = 2z.
         //
         // x = A*C, y = (A*D + B*C), z = B*D.
-        // Therefore X = A*C, Y = (A*D + B*C) + B*D and Z = 2*B*D.
+        // Therefore X = A*C, Y = A*D + B*C + B*D and Z = 2*B*D.
         for (; OtherIdx != Ops.size() && isa<SCEVAddRecExpr>(Ops[OtherIdx]);
              ++OtherIdx)
           if (const SCEVAddRecExpr *OtherAddRec =
@@ -2002,19 +2003,28 @@
               const SCEV *NewSecondOrderStep =
                   getMulExpr(BD, getConstant(BD->getType(), 2));
 
-              SmallVector<const SCEV *, 3> AddRecOps;
-              AddRecOps.push_back(NewStart);
-              AddRecOps.push_back(NewStep);
-              AddRecOps.push_back(NewSecondOrderStep);
-              const SCEV *NewAddRec = getAddRecExpr(AddRecOps,
-                                                    AddRec->getLoop(),
-                                                    SCEV::FlagAnyWrap);
-              if (Ops.size() == 2) return NewAddRec;
-              Ops[Idx] = AddRec = cast<SCEVAddRecExpr>(NewAddRec);
-              Ops.erase(Ops.begin() + OtherIdx); --OtherIdx;
+              // This can happen when AddRec or OtherAddRec have >3 operands.
+              // TODO: support these add-recs.
+              if (isLoopInvariant(NewStart, AddRecLoop) &&
+                  isLoopInvariant(NewStep, AddRecLoop) &&
+                  isLoopInvariant(NewSecondOrderStep, AddRecLoop)) {
+                SmallVector<const SCEV *, 3> AddRecOps;
+                AddRecOps.push_back(NewStart);
+                AddRecOps.push_back(NewStep);
+                AddRecOps.push_back(NewSecondOrderStep);
+                const SCEV *NewAddRec = getAddRecExpr(AddRecOps,
+                                                      AddRec->getLoop(),
+                                                      SCEV::FlagAnyWrap);
+                if (Ops.size() == 2) return NewAddRec;
+                Ops[Idx] = AddRec = cast<SCEVAddRecExpr>(NewAddRec);
+                Ops.erase(Ops.begin() + OtherIdx); --OtherIdx;
+                Retry = true;
+              }
             }
-        return getMulExpr(Ops);
+        if (Retry)
+          return getMulExpr(Ops);
       }
+    }
 
     // Otherwise couldn't fold anything into this recurrence.  Move onto the
     // next one.

Modified: llvm/trunk/test/Analysis/ScalarEvolution/SolveQuadraticEquation.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/ScalarEvolution/SolveQuadraticEquation.ll?rev=139186&r1=139185&r2=139186&view=diff
==============================================================================
--- llvm/trunk/test/Analysis/ScalarEvolution/SolveQuadraticEquation.ll (original)
+++ llvm/trunk/test/Analysis/ScalarEvolution/SolveQuadraticEquation.ll Tue Sep  6 16:42:18 2011
@@ -35,7 +35,7 @@
 
 
 ; PR10383
-; This used to crash.
+; These next two used to crash.
 
 define void @test2(i1 %cmp, i64 %n) {
 entry:
@@ -61,3 +61,22 @@
   ret void
 }
 ; CHECK: Determining loop execution counts for: @test2
+
+define i32 @test3() {
+if.then466:
+  br i1 undef, label %for.cond539.preheader, label %for.inc479
+
+for.inc479:
+  %a2.07 = phi i32 [ %add495, %for.inc479 ], [ 0, %if.then466 ]
+  %j.36 = phi i32 [ %inc497, %for.inc479 ], [ undef, %if.then466 ]
+  %mul484 = mul nsw i32 %j.36, %j.36
+  %mul491 = mul i32 %j.36, %j.36
+  %mul493 = mul i32 %mul491, %mul484
+  %add495 = add nsw i32 %mul493, %a2.07
+  %inc497 = add nsw i32 %j.36, 1
+  br i1 undef, label %for.cond539.preheader, label %for.inc479
+
+for.cond539.preheader:
+  unreachable
+}
+; CHECK: Determining loop execution counts for: @test3





More information about the llvm-commits mailing list