From 2db0e9ebb600a2e6b8f651f66a1ef50e0d3c3c6b Mon Sep 17 00:00:00 2001 From: Eli Friedman Date: Fri, 25 May 2012 00:09:29 +0000 Subject: [PATCH] Simplify code for calling a function where CanLowerReturn fails, fixing a small bug in the process. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@157446 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Target/TargetLowering.h | 3 +- .../SelectionDAG/SelectionDAGBuilder.cpp | 36 +++++----------- lib/CodeGen/SelectionDAG/TargetLowering.cpp | 10 +---- lib/Target/X86/X86FastISel.cpp | 3 +- test/CodeGen/X86/bigstructret.ll | 41 ++++++++++++++++--- 5 files changed, 48 insertions(+), 45 deletions(-) diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h index 29abc191dda..c6056eb0d71 100644 --- a/include/llvm/Target/TargetLowering.h +++ b/include/llvm/Target/TargetLowering.h @@ -2049,8 +2049,7 @@ private: /// the offsets, if the return value is being lowered to memory. void GetReturnInfo(Type* ReturnType, Attributes attr, SmallVectorImpl &Outs, - const TargetLowering &TLI, - SmallVectorImpl *Offsets = 0); + const TargetLowering &TLI); } // end llvm namespace diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index f1b4d809207..b5fec7baba0 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -5149,9 +5149,8 @@ void SelectionDAGBuilder::LowerCallTo(ImmutableCallSite CS, SDValue Callee, // Check whether the function can return without sret-demotion. SmallVector Outs; - SmallVector Offsets; GetReturnInfo(RetTy, CS.getAttributes().getRetAttributes(), - Outs, TLI, &Offsets); + Outs, TLI); bool CanLowerReturn = TLI.CanLowerReturn(CS.getCallingConv(), DAG.getMachineFunction(), @@ -5264,7 +5263,13 @@ void SelectionDAGBuilder::LowerCallTo(ImmutableCallSite CS, SDValue Callee, ComputeValueVTs(TLI, PtrRetTy, PVTs); assert(PVTs.size() == 1 && "Pointers should fit in one register"); EVT PtrVT = PVTs[0]; - unsigned NumValues = Outs.size(); + + SmallVector RetTys; + SmallVector Offsets; + RetTy = FTy->getReturnType(); + ComputeValueVTs(TLI, RetTy, RetTys, &Offsets); + + unsigned NumValues = RetTys.size(); SmallVector Values(NumValues); SmallVector Chains(NumValues); @@ -5272,8 +5277,7 @@ void SelectionDAGBuilder::LowerCallTo(ImmutableCallSite CS, SDValue Callee, SDValue Add = DAG.getNode(ISD::ADD, getCurDebugLoc(), PtrVT, DemoteStackSlot, DAG.getConstant(Offsets[i], PtrVT)); - SDValue L = DAG.getLoad(Outs[i].VT, getCurDebugLoc(), Result.second, - Add, + SDValue L = DAG.getLoad(RetTys[i], getCurDebugLoc(), Result.second, Add, MachinePointerInfo::getFixedStack(DemoteStackIdx, Offsets[i]), false, false, false, 1); Values[i] = L; @@ -5284,30 +5288,10 @@ void SelectionDAGBuilder::LowerCallTo(ImmutableCallSite CS, SDValue Callee, 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(), &Values[CurReg], NumRegs, - RegisterVT, VT, AssertOp); - ReturnValues.push_back(ReturnValue); - CurReg += NumRegs; - } - setValue(CS.getInstruction(), DAG.getNode(ISD::MERGE_VALUES, getCurDebugLoc(), DAG.getVTList(&RetTys[0], RetTys.size()), - &ReturnValues[0], ReturnValues.size())); + &Values[0], Values.size())); } // Assign order to nodes here. If the call does not produce a result, it won't diff --git a/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/lib/CodeGen/SelectionDAG/TargetLowering.cpp index 5c9dc472370..56b17198cd9 100644 --- a/lib/CodeGen/SelectionDAG/TargetLowering.cpp +++ b/lib/CodeGen/SelectionDAG/TargetLowering.cpp @@ -997,13 +997,11 @@ unsigned TargetLowering::getVectorTypeBreakdown(LLVMContext &Context, EVT VT, /// TODO: Move this out of TargetLowering.cpp. void llvm::GetReturnInfo(Type* ReturnType, Attributes attr, SmallVectorImpl &Outs, - const TargetLowering &TLI, - SmallVectorImpl *Offsets) { + const TargetLowering &TLI) { SmallVector ValueVTs; ComputeValueVTs(TLI, ReturnType, ValueVTs); unsigned NumValues = ValueVTs.size(); if (NumValues == 0) return; - unsigned Offset = 0; for (unsigned j = 0, f = NumValues; j != f; ++j) { EVT VT = ValueVTs[j]; @@ -1026,8 +1024,6 @@ void llvm::GetReturnInfo(Type* ReturnType, Attributes attr, 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(); @@ -1042,10 +1038,6 @@ void llvm::GetReturnInfo(Type* ReturnType, Attributes attr, for (unsigned i = 0; i < NumParts; ++i) { Outs.push_back(ISD::OutputArg(Flags, PartVT, /*isFixed=*/true)); - if (Offsets) { - Offsets->push_back(Offset); - Offset += PartSize; - } } } } diff --git a/lib/Target/X86/X86FastISel.cpp b/lib/Target/X86/X86FastISel.cpp index 1b62357275b..07d0e7647a2 100644 --- a/lib/Target/X86/X86FastISel.cpp +++ b/lib/Target/X86/X86FastISel.cpp @@ -1549,9 +1549,8 @@ bool X86FastISel::DoSelectCall(const Instruction *I, const char *MemIntName) { // Check whether the function can return without sret-demotion. SmallVector Outs; - SmallVector Offsets; GetReturnInfo(I->getType(), CS.getAttributes().getRetAttributes(), - Outs, TLI, &Offsets); + Outs, TLI); bool CanLowerReturn = TLI.CanLowerReturn(CS.getCallingConv(), *FuncInfo.MF, FTy->isVarArg(), Outs, FTy->getContext()); diff --git a/test/CodeGen/X86/bigstructret.ll b/test/CodeGen/X86/bigstructret.ll index 633995d5d78..eacbf325220 100644 --- a/test/CodeGen/X86/bigstructret.ll +++ b/test/CodeGen/X86/bigstructret.ll @@ -1,12 +1,15 @@ -; RUN: llc < %s -march=x86 -o %t -; RUN: grep "movl .24601, 12(%ecx)" %t -; RUN: grep "movl .48, 8(%ecx)" %t -; RUN: grep "movl .24, 4(%ecx)" %t -; RUN: grep "movl .12, (%ecx)" %t +; RUN: llc < %s -march=x86 | FileCheck %s %0 = type { i32, i32, i32, i32 } +%1 = type { i1, i1, i1, i32 } -define internal fastcc %0 @ReturnBigStruct() nounwind readnone { +; CHECK: ReturnBigStruct +; CHECK: movl $24601, 12(%ecx) +; CHECK: movl $48, 8(%ecx) +; CHECK: movl $24, 4(%ecx) +; CHECK: movl $12, (%ecx) + +define fastcc %0 @ReturnBigStruct() nounwind readnone { entry: %0 = insertvalue %0 zeroinitializer, i32 12, 0 %1 = insertvalue %0 %0, i32 24, 1 @@ -15,3 +18,29 @@ entry: ret %0 %3 } +; CHECK: ReturnBigStruct2 +; CHECK: movl $48, 4(%ecx) +; CHECK: movb $1, 2(%ecx) +; CHECK: movb $1, 1(%ecx) +; CHECK: movb $0, (%ecx) + +define fastcc %1 @ReturnBigStruct2() nounwind readnone { +entry: + %0 = insertvalue %1 zeroinitializer, i1 false, 0 + %1 = insertvalue %1 %0, i1 true, 1 + %2 = insertvalue %1 %1, i1 true, 2 + %3 = insertvalue %1 %2, i32 48, 3 + ret %1 %3 +} + +; CHECK: CallBigStruct2 +; CHECK: leal 16(%esp), {{.*}} +; CHECK: call{{.*}}ReturnBigStruct2 +; CHECK: subl $4, %esp +; CHECK: movl 20(%esp), %eax +define fastcc i32 @CallBigStruct2() nounwind readnone { +entry: + %0 = call %1 @ReturnBigStruct2() + %1 = extractvalue %1 %0, 3 + ret i32 %1 +} -- 2.34.1