From 93ae407ec3d300805d42a6e2f81ab8c4538eb494 Mon Sep 17 00:00:00 2001 From: Kenneth Uildriks Date: Sat, 16 Jan 2010 23:37:33 +0000 Subject: [PATCH] When checking for sret-demotion, it needs to use legal types. When using the return value of an sret-demoted call, it needs to use possibly illegal types that match the declared Type of the callee. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@93667 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../SelectionDAG/SelectionDAGBuilder.cpp | 52 +++++++++++++++---- test/CodeGen/X86/bigstructret2.ll | 12 +++++ 2 files changed, 53 insertions(+), 11 deletions(-) create mode 100644 test/CodeGen/X86/bigstructret2.ll diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index 5e3a3b5e0d0..a3fb34576ac 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -800,18 +800,19 @@ SDValue SelectionDAGBuilder::getValue(const Value *V) { SDNodeOrder, Chain, NULL); } -/// Get the EVTs and ArgFlags collections that represent the return type -/// of the given function. This does not require a DAG or a return value, and -/// is suitable for use before any DAGs for the function are constructed. +/// Get the EVTs and ArgFlags collections that represent the legalized return +/// type of the given function. This does not require a DAG or a return value, +/// and is suitable for use before any DAGs for the function are constructed. static void getReturnInfo(const Type* ReturnType, Attributes attr, SmallVectorImpl &OutVTs, SmallVectorImpl &OutFlags, TargetLowering &TLI, SmallVectorImpl *Offsets = 0) { SmallVector ValueVTs; - ComputeValueVTs(TLI, ReturnType, ValueVTs, Offsets); + ComputeValueVTs(TLI, ReturnType, ValueVTs); unsigned NumValues = ValueVTs.size(); - if ( NumValues == 0 ) return; + if (NumValues == 0) return; + unsigned Offset = 0; for (unsigned j = 0, f = NumValues; j != f; ++j) { EVT VT = ValueVTs[j]; @@ -834,6 +835,9 @@ static void getReturnInfo(const Type* ReturnType, unsigned NumParts = TLI.getNumRegisters(ReturnType->getContext(), VT); EVT PartVT = TLI.getRegisterType(ReturnType->getContext(), VT); + unsigned PartSize = TLI.getTargetData()->getTypeAllocSize( + PartVT.getTypeForEVT(ReturnType->getContext())); + // 'inreg' on function refers to return value ISD::ArgFlagsTy Flags = ISD::ArgFlagsTy(); if (attr & Attribute::InReg) @@ -848,6 +852,11 @@ static void getReturnInfo(const Type* ReturnType, for (unsigned i = 0; i < NumParts; ++i) { OutVTs.push_back(PartVT); OutFlags.push_back(Flags); + if (Offsets) + { + Offsets->push_back(Offset); + Offset += PartSize; + } } } } @@ -5098,16 +5107,37 @@ void SelectionDAGBuilder::LowerCallTo(CallSite CS, SDValue Callee, SDValue Chain = DAG.getNode(ISD::TokenFactor, getCurDebugLoc(), MVT::Other, &Chains[0], NumValues); PendingLoads.push_back(Chain); + + // Collect the legal value parts into potentially illegal values + // that correspond to the original function's return values. + SmallVector RetTys; + RetTy = FTy->getReturnType(); + ComputeValueVTs(TLI, RetTy, RetTys); + ISD::NodeType AssertOp = ISD::DELETED_NODE; + SmallVector ReturnValues; + unsigned CurReg = 0; + for (unsigned I = 0, E = RetTys.size(); I != E; ++I) { + EVT VT = RetTys[I]; + EVT RegisterVT = TLI.getRegisterType(RetTy->getContext(), VT); + unsigned NumRegs = TLI.getNumRegisters(RetTy->getContext(), VT); + + SDValue ReturnValue = + getCopyFromParts(DAG, getCurDebugLoc(), SDNodeOrder, &Values[CurReg], NumRegs, + RegisterVT, VT, AssertOp); + ReturnValues.push_back(ReturnValue); + if (DisableScheduling) + DAG.AssignOrdering(ReturnValue.getNode(), SDNodeOrder); + CurReg += NumRegs; + } + SDValue Res = DAG.getNode(ISD::MERGE_VALUES, getCurDebugLoc(), + DAG.getVTList(&RetTys[0], RetTys.size()), + &ReturnValues[0], ReturnValues.size()); - SDValue MV = DAG.getNode(ISD::MERGE_VALUES, - getCurDebugLoc(), - DAG.getVTList(&OutVTs[0], NumValues), - &Values[0], NumValues); - setValue(CS.getInstruction(), MV); + setValue(CS.getInstruction(), Res); if (DisableScheduling) { DAG.AssignOrdering(Chain.getNode(), SDNodeOrder); - DAG.AssignOrdering(MV.getNode(), SDNodeOrder); + DAG.AssignOrdering(Res.getNode(), SDNodeOrder); } } diff --git a/test/CodeGen/X86/bigstructret2.ll b/test/CodeGen/X86/bigstructret2.ll new file mode 100644 index 00000000000..46e0fd21764 --- /dev/null +++ b/test/CodeGen/X86/bigstructret2.ll @@ -0,0 +1,12 @@ +; RUN: llc < %s -march=x86 -o %t + +%0 = type { i64, i64 } + +declare fastcc %0 @ReturnBigStruct() nounwind readnone + +define void @test(%0* %p) { + %1 = call fastcc %0 @ReturnBigStruct() + store %0 %1, %0* %p + ret void +} + -- 2.34.1