From b613f8842e77483311483b628c68e3c4e857cc77 Mon Sep 17 00:00:00 2001 From: Tim Northover Date: Tue, 10 Feb 2015 19:49:18 +0000 Subject: [PATCH] DeadArgElim: arguments affect all returned sub-values by default. Unless we meet an insertvalue on a path from some value to a return, that value will be live if *any* of the return's components are live, so all of those components must be added to the MaybeLiveUses. Previously we were deleting arguments if sub-value 0 turned out to be dead. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@228731 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../IPO/DeadArgumentElimination.cpp | 20 +++++++++++++++---- test/Transforms/DeadArgElim/aggregates.ll | 17 ++++++++++++++++ 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/lib/Transforms/IPO/DeadArgumentElimination.cpp b/lib/Transforms/IPO/DeadArgumentElimination.cpp index 50698bb26c8..596204dac62 100644 --- a/lib/Transforms/IPO/DeadArgumentElimination.cpp +++ b/lib/Transforms/IPO/DeadArgumentElimination.cpp @@ -146,7 +146,7 @@ namespace { private: Liveness MarkIfNotLive(RetOrArg Use, UseVector &MaybeLiveUses); Liveness SurveyUse(const Use *U, UseVector &MaybeLiveUses, - unsigned RetValNum = 0); + unsigned RetValNum = -1U); Liveness SurveyUses(const Value *V, UseVector &MaybeLiveUses); void SurveyFunction(const Function &F); @@ -443,9 +443,21 @@ DAE::Liveness DAE::SurveyUse(const Use *U, // function's return value is live. We use RetValNum here, for the case // that U is really a use of an insertvalue instruction that uses the // original Use. - RetOrArg Use = CreateRet(RI->getParent()->getParent(), RetValNum); - // We might be live, depending on the liveness of Use. - return MarkIfNotLive(Use, MaybeLiveUses); + const Function *F = RI->getParent()->getParent(); + if (RetValNum != -1U) { + RetOrArg Use = CreateRet(F, RetValNum); + // We might be live, depending on the liveness of Use. + return MarkIfNotLive(Use, MaybeLiveUses); + } else { + DAE::Liveness Result; + for (unsigned i = 0; i < NumRetVals(F); ++i) { + RetOrArg Use = CreateRet(F, i); + // We might be live, depending on the liveness of Use. All Results + // should be the same since they depend only on F. + Result = MarkIfNotLive(Use, MaybeLiveUses); + } + return Result; + } } if (const InsertValueInst *IV = dyn_cast(V)) { if (U->getOperandNo() != InsertValueInst::getAggregateOperandIndex() diff --git a/test/Transforms/DeadArgElim/aggregates.ll b/test/Transforms/DeadArgElim/aggregates.ll index 153289947c1..84370834e11 100644 --- a/test/Transforms/DeadArgElim/aggregates.ll +++ b/test/Transforms/DeadArgElim/aggregates.ll @@ -113,3 +113,20 @@ define void @test_can_shrink_arrays() { ret void } + +; Case 5: %in gets passed directly to the return. It should mark be marked as +; used if *any* of the return values are, not just if value 0 is. + +; CHECK-LABEL: define internal i32 @ret_applies_to_all({ i32, i32 } %in) +; CHECK: [[RET:%.*]] = extractvalue { i32, i32 } %in, 1 +; CHECK: ret i32 [[RET]] + +define internal {i32, i32} @ret_applies_to_all({i32, i32} %in) { + ret {i32, i32} %in +} + +define i32 @test_ret_applies_to_all() { + %val = call {i32, i32} @ret_applies_to_all({i32, i32} {i32 42, i32 43}) + %ret = extractvalue {i32, i32} %val, 1 + ret i32 %ret +}