Fix PR3807 by inserting 'insertelement' instructions in the normal dest of
authorChris Lattner <sabre@nondot.org>
Wed, 18 Mar 2009 00:31:45 +0000 (00:31 +0000)
committerChris Lattner <sabre@nondot.org>
Wed, 18 Mar 2009 00:31:45 +0000 (00:31 +0000)
an invoke instead of after the invoke (in its block), which is invalid.

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

lib/Transforms/IPO/DeadArgumentElimination.cpp
test/Transforms/DeadArgElim/2009-03-17-MRE-Invoke.ll [new file with mode: 0644]

index dd5fce69fe15f7f397fae2966af7e2323189780e..9f2b2a733ee8f858a4f39cf8182eec24ee029a7b 100644 (file)
@@ -798,9 +798,13 @@ bool DAE::RemoveDeadStuffFromFunction(Function *F) {
         // Replace by null for now.
         Call->replaceAllUsesWith(Constant::getNullValue(Call->getType()));
       } else {
-        assert(isa<StructType>(RetTy) && "Return type changed, but not into a"
-                                         "void. The old return type must have"
-                                         "been a struct!");
+        assert(isa<StructType>(RetTy) &&
+               "Return type changed, but not into a void. The old return type"
+               " must have been a struct!");
+        Instruction *InsertPt = Call;
+        if (InvokeInst *II = dyn_cast<InvokeInst>(Call))
+          InsertPt = II->getNormalDest()->begin();
+          
         // We used to return a struct. Instead of doing smart stuff with all the
         // uses of this struct, we will just rebuild it using
         // extract/insertvalue chaining and let instcombine clean that up.
@@ -813,12 +817,13 @@ bool DAE::RemoveDeadStuffFromFunction(Function *F) {
             if (RetTypes.size() > 1)
               // We are still returning a struct, so extract the value from our
               // return value
-              V = ExtractValueInst::Create(New, NewRetIdxs[i], "newret", Call);
+              V = ExtractValueInst::Create(New, NewRetIdxs[i], "newret",
+                                           InsertPt);
             else
               // We are now returning a single element, so just insert that
               V = New;
             // Insert the value at the old position
-            RetVal = InsertValueInst::Create(RetVal, V, i, "oldret", Call);
+            RetVal = InsertValueInst::Create(RetVal, V, i, "oldret", InsertPt);
           }
         // Now, replace all uses of the old call instruction with the return
         // struct we built
diff --git a/test/Transforms/DeadArgElim/2009-03-17-MRE-Invoke.ll b/test/Transforms/DeadArgElim/2009-03-17-MRE-Invoke.ll
new file mode 100644 (file)
index 0000000..6ccaa9f
--- /dev/null
@@ -0,0 +1,15 @@
+; RUN: llvm-as < %s | opt -deadargelim | llvm-dis
+; PR3807
+
+define internal { i32, i32 } @foo() {
+  ret {i32,i32} {i32 42, i32 4}
+}
+
+define i32 @bar() {
+  %x = invoke {i32,i32} @foo() to label %T unwind label %T2
+T:
+  %y = extractvalue {i32,i32} %x, 1
+  ret i32 %y
+T2:
+  unreachable
+}