fix rdar://7590304, an infinite loop in instcombine. In the invoke
authorChris Lattner <sabre@nondot.org>
Mon, 1 Feb 2010 18:04:58 +0000 (18:04 +0000)
committerChris Lattner <sabre@nondot.org>
Mon, 1 Feb 2010 18:04:58 +0000 (18:04 +0000)
case, instcombine can't zap the invoke for fear of changing the CFG.
However, we have to do something to prevent the next iteration of
instcombine from inserting another store -> undef before the invoke
thereby getting into infinite iteration between dead store elim and
store insertion.

Just zap the callee to null, which will prevent the next iteration
from doing anything.

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

lib/Transforms/InstCombine/InstCombineCalls.cpp
test/Transforms/InstCombine/crash.ll

index 47c37c46587d4fd0634154fcf7c5d06c770bbad1..9c420c838739e0c7b0607d6c1513aee599608616 100644 (file)
@@ -703,8 +703,13 @@ Instruction *InstCombiner::visitCallSite(CallSite CS) {
       // This allows ValueHandlers and custom metadata to adjust itself.
       if (!OldCall->getType()->isVoidTy())
         OldCall->replaceAllUsesWith(UndefValue::get(OldCall->getType()));
-      if (isa<CallInst>(OldCall))   // Not worth removing an invoke here.
+      if (isa<CallInst>(OldCall))
         return EraseInstFromFunction(*OldCall);
+      
+      // We cannot remove an invoke, because it would change the CFG, just
+      // change the callee to a null pointer.
+      cast<InvokeInst>(OldCall)->setOperand(0,
+                                    Constant::getNullValue(CalleeF->getType()));
       return 0;
     }
 
index 732a88262178db21d7fa840cfe88bf15f3dd9cb7..a4e6a62d9e6e0dca7511b89f4e87607b75a4a19d 100644 (file)
@@ -204,3 +204,25 @@ declare i32 @llvm.eh.selector(i8*, i8*, ...) nounwind
 declare void @_ZSt9terminatev()
 
 declare void @_Unwind_Resume_or_Rethrow(i8*)
+
+
+
+; rdar://7590304
+define i8* @test10(i8* %self, i8* %tmp3) {
+entry:
+  store i1 true, i1* undef
+  store i1 true, i1* undef
+  invoke arm_apcscc void @test10a()
+          to label %invoke.cont unwind label %try.handler ; <i8*> [#uses=0]
+
+invoke.cont:                                      ; preds = %entry
+  unreachable
+
+try.handler:                                      ; preds = %entry
+  ret i8* %self
+}
+
+define void @test10a() {
+  ret void
+}
+