[llvm-commits] [llvm] r51063 - in /llvm/trunk: lib/Transforms/Scalar/TailDuplication.cpp test/Transforms/TailDup/2008-05-13-InfiniteLoop.ll

Dale Johannesen dalej at apple.com
Tue May 13 13:06:43 PDT 2008


Author: johannes
Date: Tue May 13 15:06:43 2008
New Revision: 51063

URL: http://llvm.org/viewvc/llvm-project?rev=51063&view=rev
Log:
Fix for PR 2323, infinite loop in tail dup.


Added:
    llvm/trunk/test/Transforms/TailDup/2008-05-13-InfiniteLoop.ll
Modified:
    llvm/trunk/lib/Transforms/Scalar/TailDuplication.cpp

Modified: llvm/trunk/lib/Transforms/Scalar/TailDuplication.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/TailDuplication.cpp?rev=51063&r1=51062&r2=51063&view=diff

==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/TailDuplication.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/TailDuplication.cpp Tue May 13 15:06:43 2008
@@ -32,6 +32,7 @@
 #include "llvm/Support/Compiler.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/ADT/Statistic.h"
+#include "llvm/ADT/SmallPtrSet.h"
 #include <map>
 using namespace llvm;
 
@@ -51,6 +52,7 @@
   private:
     inline bool shouldEliminateUnconditionalBranch(TerminatorInst *TI);
     inline void eliminateUnconditionalBranch(BranchInst *BI);
+    SmallPtrSet<BasicBlock*, 4> CycleDetector;
   };
 }
 
@@ -61,17 +63,21 @@
 FunctionPass *llvm::createTailDuplicationPass() { return new TailDup(); }
 
 /// runOnFunction - Top level algorithm - Loop over each unconditional branch in
-/// the function, eliminating it if it looks attractive enough.
-///
+/// the function, eliminating it if it looks attractive enough.  CycleDetector
+/// prevents infinite loops by checking that we aren't redirecting a branch to
+/// a place it already pointed to earlier; see PR 2323.
 bool TailDup::runOnFunction(Function &F) {
   bool Changed = false;
-  for (Function::iterator I = F.begin(), E = F.end(); I != E; )
+  CycleDetector.clear();
+  for (Function::iterator I = F.begin(), E = F.end(); I != E; ) {
     if (shouldEliminateUnconditionalBranch(I->getTerminator())) {
       eliminateUnconditionalBranch(cast<BranchInst>(I->getTerminator()));
       Changed = true;
     } else {
       ++I;
+      CycleDetector.clear();
     }
+  }
   return Changed;
 }
 
@@ -140,7 +146,7 @@
       if (TooMany-- == 0) return false;
   }
   
-  // Finally, if this unconditional branch is a fall-through, be careful about
+  // If this unconditional branch is a fall-through, be careful about
   // tail duplicating it.  In particular, we don't want to taildup it if the
   // original block will still be there after taildup is completed: doing so
   // would eliminate the fall-through, requiring unconditional branches.
@@ -170,6 +176,11 @@
     }
   }
 
+  // Finally, check that we haven't redirected to this target block earlier;
+  // there are cases where we loop forever if we don't check this (PR 2323).
+  if (!CycleDetector.insert(Dest))
+    return false;
+
   return true;
 }
 

Added: llvm/trunk/test/Transforms/TailDup/2008-05-13-InfiniteLoop.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/TailDup/2008-05-13-InfiniteLoop.ll?rev=51063&view=auto

==============================================================================
--- llvm/trunk/test/Transforms/TailDup/2008-05-13-InfiniteLoop.ll (added)
+++ llvm/trunk/test/Transforms/TailDup/2008-05-13-InfiniteLoop.ll Tue May 13 15:06:43 2008
@@ -0,0 +1,26 @@
+; RUN: llvm-as < %s | opt -tailduplicate | llc
+; PR2323
+
+define i32 @func_27(i32 %p_28) nounwind  {
+entry:
+  %tmp125 = trunc i32 %p_28 to i8   ; <i8> [#uses=1]
+  %tmp5.i = icmp eq i8 %tmp125, 0   ; <i1> [#uses=1]
+  br i1 %tmp5.i, label %bb8.i, label %bb.i
+
+bb.i:   ; preds = %entry
+  br label %bb39.i
+
+bb8.i:    ; preds = %entry
+  br label %bb11.i
+
+bb11.i:   ; preds = %bb39.i, %bb8.i
+  %tmp126 = trunc i32 %p_28 to i8   ; <i8> [#uses=1]
+  br label %bb39.i
+
+bb39.i:   ; preds = %bb11.i, %bb.i
+  %tmp127 = trunc i32 %p_28 to i8   ; <i8> [#uses=1]
+  br label %bb11.i
+
+func_29.exit:   ; No predecessors!
+  ret i32 undef
+}





More information about the llvm-commits mailing list