aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2009-03-18 00:31:45 +0000
committerChris Lattner <sabre@nondot.org>2009-03-18 00:31:45 +0000
commitbda0765e0763cd7d9b0980328fc1d718a6773628 (patch)
tree00662c885f650072655098e5ed710756f4f43980
parent64ec298e689edb8e3eae5bdd4bb4ae6584519bdb (diff)
Fix PR3807 by inserting 'insertelement' instructions in the normal dest of
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
-rw-r--r--lib/Transforms/IPO/DeadArgumentElimination.cpp15
-rw-r--r--test/Transforms/DeadArgElim/2009-03-17-MRE-Invoke.ll15
2 files changed, 25 insertions, 5 deletions
diff --git a/lib/Transforms/IPO/DeadArgumentElimination.cpp b/lib/Transforms/IPO/DeadArgumentElimination.cpp
index dd5fce69fe..9f2b2a733e 100644
--- a/lib/Transforms/IPO/DeadArgumentElimination.cpp
+++ b/lib/Transforms/IPO/DeadArgumentElimination.cpp
@@ -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
index 0000000000..6ccaa9fc00
--- /dev/null
+++ b/test/Transforms/DeadArgElim/2009-03-17-MRE-Invoke.ll
@@ -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
+}