[llvm-commits] [llvm] r154157 - in /llvm/trunk: lib/Transforms/Utils/CloneFunction.cpp test/Transforms/Inline/inline_cleanup.ll

Chandler Carruth chandlerc at gmail.com
Thu Apr 5 18:11:52 PDT 2012


Author: chandlerc
Date: Thu Apr  5 20:11:52 2012
New Revision: 154157

URL: http://llvm.org/viewvc/llvm-project?rev=154157&view=rev
Log:
Sink the return instruction collection until after we're done deleting
dead code, including dead return instructions in some cases. Otherwise,
we end up having a bogus poniter to a return instruction that blows up
much further down the road.

It turns out that this pattern is both simpler to code, easier to update
in the face of enhancements to the inliner cleanup, and likely cheaper
given that it won't add dead instructions to the list.

Thanks to John Regehr's numerous test cases for teasing this out.

Modified:
    llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp
    llvm/trunk/test/Transforms/Inline/inline_cleanup.ll

Modified: llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp?rev=154157&r1=154156&r2=154157&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp (original)
+++ llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp Thu Apr  5 20:11:52 2012
@@ -200,7 +200,6 @@
     const Function *OldFunc;
     ValueToValueMapTy &VMap;
     bool ModuleLevelChanges;
-    SmallVectorImpl<ReturnInst*> &Returns;
     const char *NameSuffix;
     ClonedCodeInfo *CodeInfo;
     const TargetData *TD;
@@ -208,13 +207,12 @@
     PruningFunctionCloner(Function *newFunc, const Function *oldFunc,
                           ValueToValueMapTy &valueMap,
                           bool moduleLevelChanges,
-                          SmallVectorImpl<ReturnInst*> &returns,
                           const char *nameSuffix, 
                           ClonedCodeInfo *codeInfo,
                           const TargetData *td)
     : NewFunc(newFunc), OldFunc(oldFunc),
       VMap(valueMap), ModuleLevelChanges(moduleLevelChanges),
-      Returns(returns), NameSuffix(nameSuffix), CodeInfo(codeInfo), TD(td) {
+      NameSuffix(nameSuffix), CodeInfo(codeInfo), TD(td) {
     }
 
     /// CloneBlock - The specified block is found to be reachable, clone it and
@@ -352,9 +350,6 @@
     CodeInfo->ContainsDynamicAllocas |= hasStaticAllocas && 
       BB != &BB->getParent()->front();
   }
-  
-  if (ReturnInst *RI = dyn_cast<ReturnInst>(NewBB->getTerminator()))
-    Returns.push_back(RI);
 }
 
 /// CloneAndPruneFunctionInto - This works exactly like CloneFunctionInto,
@@ -381,7 +376,7 @@
 #endif
 
   PruningFunctionCloner PFC(NewFunc, OldFunc, VMap, ModuleLevelChanges,
-                            Returns, NameSuffix, CodeInfo, TD);
+                            NameSuffix, CodeInfo, TD);
 
   // Clone the entry block, and anything recursively reachable from it.
   std::vector<const BasicBlock*> CloneWorklist;
@@ -537,6 +532,13 @@
     // and we still want to prune the dead code as early as possible.
     ConstantFoldTerminator(I);
 
+    // Track all of the newly-inserted returns.
+    if (ReturnInst *RI = dyn_cast<ReturnInst>(I->getTerminator())) {
+      Returns.push_back(RI);
+      ++I;
+      continue;
+    }
+
     BranchInst *BI = dyn_cast<BranchInst>(I->getTerminator());
     if (!BI || BI->isConditional()) { ++I; continue; }
     

Modified: llvm/trunk/test/Transforms/Inline/inline_cleanup.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/Inline/inline_cleanup.ll?rev=154157&r1=154156&r2=154157&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/Inline/inline_cleanup.ll (original)
+++ llvm/trunk/test/Transforms/Inline/inline_cleanup.ll Thu Apr  5 20:11:52 2012
@@ -136,3 +136,40 @@
   call void @inner2(i32 0, i32 -1, i32 %z, i1 %b)
   ret void
 }
+
+define void @PR12470_inner(i16 signext %p1) nounwind uwtable {
+entry:
+  br i1 undef, label %cond.true, label %cond.false
+
+cond.true:
+  br label %cond.end
+
+cond.false:
+  %conv = sext i16 %p1 to i32
+  br label %cond.end
+
+cond.end:
+  %cond = phi i32 [ undef, %cond.true ], [ 0, %cond.false ]
+  %tobool = icmp eq i32 %cond, 0
+  br i1 %tobool, label %if.end5, label %if.then
+
+if.then:
+  ret void
+
+if.end5:
+  ret void
+}
+
+define void @PR12470_outer() {
+; This previously crashed during inliner cleanup and folding inner return
+; instructions. Check that we don't crash and we produce a function with a single
+; crash.
+; CHECK: define void @PR12470_outer
+; CHECK: ret void
+; CHECK-NOT: ret void
+; CHECK: }
+
+entry:
+  call void @PR12470_inner(i16 signext 1)
+  ret void
+}





More information about the llvm-commits mailing list