Index: lib/Transforms/Scalar/SCCP.cpp =================================================================== --- lib/Transforms/Scalar/SCCP.cpp +++ lib/Transforms/Scalar/SCCP.cpp @@ -294,12 +294,25 @@ return TrackedRetVals; } + /// getTrackedMultipleRetVals - Get the inferred return value map for + /// functions which return multiple values. + const DenseMap, LatticeVal> & + getTrackedMultipleRetVals() { + return TrackedMultipleRetVals; + } + /// getTrackedGlobals - Get and return the set of inferred initializers for /// global variables. const DenseMap &getTrackedGlobals() { return TrackedGlobals; } + /// getMRVFunctionsTracked - Get the set of functions which return multiple + /// values tracked by the pass. + const SmallPtrSet getMRVFunctionsTracked() { + return MRVFunctionsTracked; + } + void markOverdefined(Value *V) { assert(!V->getType()->isStructTy() && "Should use other method"); markOverdefined(ValueState[V], V); @@ -1690,6 +1703,19 @@ return false; } +static void findReturnsToZap(Function &F, + SmallPtrSet AddressTakenFunctions, + SmallVector &ReturnsToZap) { + // We can only do this if we know that nothing else can call the function. + if (!F.hasLocalLinkage() || AddressTakenFunctions.count(&F)) + return; + + for (BasicBlock &BB : F) + if (ReturnInst *RI = dyn_cast(BB.getTerminator())) + if (!isa(RI->getOperand(0))) + ReturnsToZap.push_back(RI); +} + static bool runIPSCCP(Module &M, const DataLayout &DL, const TargetLibraryInfo *TLI) { SCCPSolver Solver(DL, TLI); @@ -1866,21 +1892,29 @@ // whether other functions are optimizable. SmallVector ReturnsToZap; - // TODO: Process multiple value ret instructions also. const DenseMap &RV = Solver.getTrackedRetVals(); for (const auto &I : RV) { Function *F = I.first; if (I.second.isOverdefined() || F->getReturnType()->isVoidTy()) continue; + findReturnsToZap(*F, AddressTakenFunctions, ReturnsToZap); + } - // We can only do this if we know that nothing else can call the function. - if (!F->hasLocalLinkage() || AddressTakenFunctions.count(F)) - continue; - - for (BasicBlock &BB : *F) - if (ReturnInst *RI = dyn_cast(BB.getTerminator())) - if (!isa(RI->getOperand(0))) - ReturnsToZap.push_back(RI); + const DenseMap, LatticeVal> &MRV = + Solver.getTrackedMultipleRetVals(); + for (const auto &F : Solver.getMRVFunctionsTracked()) { + assert(F->getReturnType()->isStructTy() && + "The return type should be a struct"); + if (StructType *STy = dyn_cast(F->getReturnType())) { + for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) { + const auto &It = MRV.find(std::make_pair(F, i)); + assert(It != MRV.end()); + LatticeVal LV = It->second; + if (LV.isOverdefined()) + continue; + } + } + findReturnsToZap(*F, AddressTakenFunctions, ReturnsToZap); } // Zap all returns which we've identified as zap to change. Index: test/Transforms/SCCP/ipsccp-basic.ll =================================================================== --- test/Transforms/SCCP/ipsccp-basic.ll +++ test/Transforms/SCCP/ipsccp-basic.ll @@ -83,7 +83,7 @@ } ; CHECK-LABEL: define internal { i64, i64 } @test4a( -; CHECK-NEXT: ret { i64, i64 } { i64 5, i64 4 } +; CHECK-NEXT: ret { i64, i64 } undef ; CHECK-NEXT: } define i64 @test4b() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) { @@ -167,7 +167,7 @@ %mrv1 = insertvalue %T %mrv0, i32 %A, 1 ret %T %mrv1 ; CHECK-LABEL: @test7a( -; CHECK-NEXT: ret %T { i32 18, i32 17 } +; CHECK-NEXT: ret %T undef } define i32 @test7b() {