From bda0765e0763cd7d9b0980328fc1d718a6773628 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Wed, 18 Mar 2009 00:31:45 +0000 Subject: [PATCH] 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 --- lib/Transforms/IPO/DeadArgumentElimination.cpp | 15 ++++++++++----- .../DeadArgElim/2009-03-17-MRE-Invoke.ll | 15 +++++++++++++++ 2 files changed, 25 insertions(+), 5 deletions(-) create mode 100644 test/Transforms/DeadArgElim/2009-03-17-MRE-Invoke.ll diff --git a/lib/Transforms/IPO/DeadArgumentElimination.cpp b/lib/Transforms/IPO/DeadArgumentElimination.cpp index dd5fce69fe1..9f2b2a733ee 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(RetTy) && "Return type changed, but not into a" - "void. The old return type must have" - "been a struct!"); + assert(isa(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(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 00000000000..6ccaa9fc005 --- /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 +}