From 00fee65fd21f9615d1a604b8b7d42cd16a3f6b47 Mon Sep 17 00:00:00 2001 From: Duncan Sands Date: Thu, 14 Feb 2008 17:28:50 +0000 Subject: [PATCH] In TargetLowering::LowerCallTo, don't assert that the return value is zero-extended if it isn't sign-extended. It may also be any-extended. Also, if a floating point value was returned in a larger floating point type, pass 1 as the second operand to FP_ROUND, which tells it that all the precision is in the original type. I think this is right but I could be wrong. Finally, when doing libcalls, set isZExt on a parameter if it is "unsigned". Currently isSExt is set when signed, and nothing is set otherwise. This should be right for all calls to standard library routines. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@47122 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Target/TargetLowering.h | 4 +-- lib/CodeGen/SelectionDAG/LegalizeDAG.cpp | 11 +++++--- lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp | 26 ++++++++++++------- lib/CodeGen/SelectionDAG/TargetLowering.cpp | 4 +-- lib/Target/ARM/ARMISelLowering.cpp | 2 +- lib/Target/Alpha/AlphaISelLowering.cpp | 14 +++++++--- lib/Target/Alpha/AlphaISelLowering.h | 2 +- lib/Target/IA64/IA64ISelLowering.cpp | 4 +-- lib/Target/IA64/IA64ISelLowering.h | 7 ++--- lib/Target/Sparc/SparcISelDAGToDAG.cpp | 22 ++++++++++------ lib/Target/X86/X86ISelLowering.cpp | 4 +-- 11 files changed, 62 insertions(+), 38 deletions(-) diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h index ef8a4474097..0d03cdad1dc 100644 --- a/include/llvm/Target/TargetLowering.h +++ b/include/llvm/Target/TargetLowering.h @@ -924,8 +924,8 @@ public: }; typedef std::vector ArgListTy; virtual std::pair - LowerCallTo(SDOperand Chain, const Type *RetTy, bool RetTyIsSigned, - bool isVarArg, unsigned CallingConv, bool isTailCall, + LowerCallTo(SDOperand Chain, const Type *RetTy, bool RetSExt, bool RetZExt, + bool isVarArg, unsigned CallingConv, bool isTailCall, SDOperand Callee, ArgListTy &Args, SelectionDAG &DAG); diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp index f0f3d1ca7b9..a0dad4d88b0 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp @@ -2862,7 +2862,8 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) { } std::pair CallResult = - TLI.LowerCallTo(Tmp1, Type::VoidTy, false, false, CallingConv::C, false, + TLI.LowerCallTo(Tmp1, Type::VoidTy, + false, false, false, CallingConv::C, false, DAG.getExternalSymbol(FnName, IntPtr), Args, DAG); Result = CallResult.second; break; @@ -3963,7 +3964,8 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) { Tmp1 = LegalizeOp(Node->getOperand(0)); TargetLowering::ArgListTy Args; std::pair CallResult = - TLI.LowerCallTo(Tmp1, Type::VoidTy, false, false, CallingConv::C, false, + TLI.LowerCallTo(Tmp1, Type::VoidTy, + false, false, false, CallingConv::C, false, DAG.getExternalSymbol("abort", TLI.getPointerTy()), Args, DAG); Result = CallResult.second; @@ -5153,6 +5155,7 @@ SDOperand SelectionDAGLegalize::ExpandLibCall(const char *Name, SDNode *Node, const Type *ArgTy = MVT::getTypeForValueType(ArgVT); Entry.Node = Node->getOperand(i); Entry.Ty = ArgTy; Entry.isSExt = isSigned; + Entry.isZExt = !isSigned; Args.push_back(Entry); } SDOperand Callee = DAG.getExternalSymbol(Name, TLI.getPointerTy()); @@ -5160,8 +5163,8 @@ SDOperand SelectionDAGLegalize::ExpandLibCall(const char *Name, SDNode *Node, // Splice the libcall in wherever FindInputOutputChains tells us to. const Type *RetTy = MVT::getTypeForValueType(Node->getValueType(0)); std::pair CallInfo = - TLI.LowerCallTo(InChain, RetTy, isSigned, false, CallingConv::C, false, - Callee, Args, DAG); + TLI.LowerCallTo(InChain, RetTy, isSigned, !isSigned, false, CallingConv::C, + false, Callee, Args, DAG); // Legalize the call sequence, starting with the chain. This will advance // the LastCALLSEQ_END to the legalized version of the CALLSEQ_END node that diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index e767c280d42..b3d7fbfcf99 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -3092,6 +3092,7 @@ void SelectionDAGLowering::LowerCallTo(CallSite CS, SDOperand Callee, std::pair Result = TLI.LowerCallTo(getRoot(), CS.getType(), CS.paramHasAttr(0, ParamAttr::SExt), + CS.paramHasAttr(0, ParamAttr::ZExt), FTy->isVarArg(), CS.getCallingConv(), IsTailCall, Callee, Args, DAG); if (CS.getType() != Type::VoidTy) @@ -3951,9 +3952,8 @@ void SelectionDAGLowering::visitMalloc(MallocInst &I) { Args.push_back(Entry); std::pair Result = - TLI.LowerCallTo(getRoot(), I.getType(), false, false, CallingConv::C, true, - DAG.getExternalSymbol("malloc", IntPtr), - Args, DAG); + TLI.LowerCallTo(getRoot(), I.getType(), false, false, false, CallingConv::C, + true, DAG.getExternalSymbol("malloc", IntPtr), Args, DAG); setValue(&I, Result.first); // Pointers always fit in registers DAG.setRoot(Result.second); } @@ -3966,7 +3966,8 @@ void SelectionDAGLowering::visitFree(FreeInst &I) { Args.push_back(Entry); MVT::ValueType IntPtr = TLI.getPointerTy(); std::pair Result = - TLI.LowerCallTo(getRoot(), Type::VoidTy, false, false, CallingConv::C, true, + TLI.LowerCallTo(getRoot(), Type::VoidTy, false, false, false, + CallingConv::C, true, DAG.getExternalSymbol("free", IntPtr), Args, DAG); DAG.setRoot(Result.second); } @@ -4126,9 +4127,9 @@ TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) { /// lowered by the target to something concrete. FIXME: When all targets are /// migrated to using ISD::CALL, this hook should be integrated into SDISel. std::pair -TargetLowering::LowerCallTo(SDOperand Chain, const Type *RetTy, - bool RetTyIsSigned, bool isVarArg, - unsigned CallingConv, bool isTailCall, +TargetLowering::LowerCallTo(SDOperand Chain, const Type *RetTy, + bool RetSExt, bool RetZExt, bool isVarArg, + unsigned CallingConv, bool isTailCall, SDOperand Callee, ArgListTy &Args, SelectionDAG &DAG) { SmallVector Ops; @@ -4209,13 +4210,18 @@ TargetLowering::LowerCallTo(SDOperand Chain, const Type *RetTy, // Gather up the call result into a single value. if (RetTy != Type::VoidTy) { - ISD::NodeType AssertOp = ISD::AssertSext; - if (!RetTyIsSigned) + ISD::NodeType AssertOp = ISD::DELETED_NODE; + + if (RetSExt) + AssertOp = ISD::AssertSext; + else if (RetZExt) AssertOp = ISD::AssertZext; + SmallVector Results(NumRegs); for (unsigned i = 0; i != NumRegs; ++i) Results[i] = Res.getValue(i); - Res = getCopyFromParts(DAG, &Results[0], NumRegs, RegisterVT, VT, AssertOp); + Res = getCopyFromParts(DAG, &Results[0], NumRegs, RegisterVT, VT, + AssertOp, true); } return std::make_pair(Res, Chain); diff --git a/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/lib/CodeGen/SelectionDAG/TargetLowering.cpp index e58c2f76ff1..eb0370aaf6d 100644 --- a/lib/CodeGen/SelectionDAG/TargetLowering.cpp +++ b/lib/CodeGen/SelectionDAG/TargetLowering.cpp @@ -264,8 +264,8 @@ SDOperand TargetLowering::LowerMEMCPYCall(SDOperand Chain, Entry.Node = Source; Args.push_back(Entry); Entry.Node = Count; Args.push_back(Entry); std::pair CallResult = - LowerCallTo(Chain, Type::VoidTy, false, false, CallingConv::C, false, - DAG.getExternalSymbol("memcpy", IntPtr), Args, DAG); + LowerCallTo(Chain, Type::VoidTy, false, false, false, CallingConv::C, + false, DAG.getExternalSymbol("memcpy", IntPtr), Args, DAG); return CallResult.second; } diff --git a/lib/Target/ARM/ARMISelLowering.cpp b/lib/Target/ARM/ARMISelLowering.cpp index 066d8e3ede2..98165a27c54 100644 --- a/lib/Target/ARM/ARMISelLowering.cpp +++ b/lib/Target/ARM/ARMISelLowering.cpp @@ -742,7 +742,7 @@ ARMTargetLowering::LowerToTLSGeneralDynamicModel(GlobalAddressSDNode *GA, Entry.Ty = (const Type *) Type::Int32Ty; Args.push_back(Entry); std::pair CallResult = - LowerCallTo(Chain, (const Type *) Type::Int32Ty, false, false, + LowerCallTo(Chain, (const Type *) Type::Int32Ty, false, false, false, CallingConv::C, false, DAG.getExternalSymbol("__tls_get_addr", PtrVT), Args, DAG); return CallResult.first; diff --git a/lib/Target/Alpha/AlphaISelLowering.cpp b/lib/Target/Alpha/AlphaISelLowering.cpp index 774dad3e44a..028f8851038 100644 --- a/lib/Target/Alpha/AlphaISelLowering.cpp +++ b/lib/Target/Alpha/AlphaISelLowering.cpp @@ -319,7 +319,7 @@ static SDOperand LowerRET(SDOperand Op, SelectionDAG &DAG) { std::pair AlphaTargetLowering::LowerCallTo(SDOperand Chain, const Type *RetTy, - bool RetTyIsSigned, bool isVarArg, + bool RetSExt, bool RetZExt, bool isVarArg, unsigned CallingConv, bool isTailCall, SDOperand Callee, ArgListTy &Args, SelectionDAG &DAG) { @@ -378,8 +378,16 @@ AlphaTargetLowering::LowerCallTo(SDOperand Chain, const Type *RetTy, SDOperand RetVal = TheCall; if (RetTyVT != ActualRetTyVT) { - RetVal = DAG.getNode(RetTyIsSigned ? ISD::AssertSext : ISD::AssertZext, - MVT::i64, RetVal, DAG.getValueType(RetTyVT)); + ISD::NodeType AssertKind = ISD::DELETED_NODE; + if (RetSExt) + AssertKind = ISD::AssertSext; + else if (RetZExt) + AssertKind = ISD::AssertZext; + + if (AssertKind != ISD::DELETED_NODE) + RetVal = DAG.getNode(AssertKind, MVT::i64, RetVal, + DAG.getValueType(RetTyVT)); + RetVal = DAG.getNode(ISD::TRUNCATE, RetTyVT, RetVal); } diff --git a/lib/Target/Alpha/AlphaISelLowering.h b/lib/Target/Alpha/AlphaISelLowering.h index e0b4b70b947..a118d99462f 100644 --- a/lib/Target/Alpha/AlphaISelLowering.h +++ b/lib/Target/Alpha/AlphaISelLowering.h @@ -77,7 +77,7 @@ namespace llvm { /// LowerCallTo - This hook lowers an abstract call to a function into an /// actual call. virtual std::pair - LowerCallTo(SDOperand Chain, const Type *RetTy, bool RetTyIsSigned, + LowerCallTo(SDOperand Chain, const Type *RetTy, bool RetSExt, bool RetZExt, bool isVarArg, unsigned CC, bool isTailCall, SDOperand Callee, ArgListTy &Args, SelectionDAG &DAG); diff --git a/lib/Target/IA64/IA64ISelLowering.cpp b/lib/Target/IA64/IA64ISelLowering.cpp index 9d74ee16d12..6b9cf1592bb 100644 --- a/lib/Target/IA64/IA64ISelLowering.cpp +++ b/lib/Target/IA64/IA64ISelLowering.cpp @@ -298,8 +298,8 @@ IA64TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) { } std::pair -IA64TargetLowering::LowerCallTo(SDOperand Chain, - const Type *RetTy, bool RetTyIsSigned, +IA64TargetLowering::LowerCallTo(SDOperand Chain, const Type *RetTy, + bool RetSExt, bool RetZExt, bool isVarArg, unsigned CallingConv, bool isTailCall, SDOperand Callee, ArgListTy &Args, SelectionDAG &DAG) { diff --git a/lib/Target/IA64/IA64ISelLowering.h b/lib/Target/IA64/IA64ISelLowering.h index 20724d24fb0..7c9c5c3a10f 100644 --- a/lib/Target/IA64/IA64ISelLowering.h +++ b/lib/Target/IA64/IA64ISelLowering.h @@ -58,10 +58,11 @@ namespace llvm { /// LowerCallTo - This hook lowers an abstract call to a function into an /// actual call. virtual std::pair - LowerCallTo(SDOperand Chain, const Type *RetTy, bool RetTyIsSigned, - bool isVarArg, unsigned CC, bool isTailCall, + LowerCallTo(SDOperand Chain, const Type *RetTy, + bool RetSExt, bool RetZExt, bool isVarArg, + unsigned CC, bool isTailCall, SDOperand Callee, ArgListTy &Args, SelectionDAG &DAG); - + /// LowerOperation - for custom lowering specific ops /// (currently, only "ret void") virtual SDOperand LowerOperation(SDOperand Op, SelectionDAG &DAG); diff --git a/lib/Target/Sparc/SparcISelDAGToDAG.cpp b/lib/Target/Sparc/SparcISelDAGToDAG.cpp index e8943621d3c..8dd81b76d3b 100644 --- a/lib/Target/Sparc/SparcISelDAGToDAG.cpp +++ b/lib/Target/Sparc/SparcISelDAGToDAG.cpp @@ -119,8 +119,9 @@ namespace { virtual std::vector LowerArguments(Function &F, SelectionDAG &DAG); virtual std::pair - LowerCallTo(SDOperand Chain, const Type *RetTy, bool RetTyIsSigned, - bool isVarArg, unsigned CC, bool isTailCall, SDOperand Callee, + LowerCallTo(SDOperand Chain, const Type *RetTy, + bool RetSExt, bool RetZExt, bool isVarArg, + unsigned CC, bool isTailCall, SDOperand Callee, ArgListTy &Args, SelectionDAG &DAG); virtual MachineBasicBlock *EmitInstrWithCustomInserter(MachineInstr *MI, MachineBasicBlock *MBB); @@ -481,8 +482,8 @@ SparcTargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) { std::pair SparcTargetLowering::LowerCallTo(SDOperand Chain, const Type *RetTy, - bool RetTyIsSigned, bool isVarArg, unsigned CC, - bool isTailCall, SDOperand Callee, + bool RetSExt, bool RetZExt, bool isVarArg, + unsigned CC, bool isTailCall, SDOperand Callee, ArgListTy &Args, SelectionDAG &DAG) { // Count the size of the outgoing arguments. unsigned ArgsSize = 0; @@ -646,11 +647,16 @@ SparcTargetLowering::LowerCallTo(SDOperand Chain, const Type *RetTy, Chain = RetVal.getValue(1); // Add a note to keep track of whether it is sign or zero extended. - ISD::NodeType AssertKind = ISD::AssertZext; - if (RetTyIsSigned) + ISD::NodeType AssertKind = ISD::DELETED_NODE; + if (RetSExt) AssertKind = ISD::AssertSext; - RetVal = DAG.getNode(AssertKind, MVT::i32, RetVal, - DAG.getValueType(RetTyVT)); + else if (RetZExt) + AssertKind = ISD::AssertZext; + + if (AssertKind != ISD::DELETED_NODE) + RetVal = DAG.getNode(AssertKind, MVT::i32, RetVal, + DAG.getValueType(RetTyVT)); + RetVal = DAG.getNode(ISD::TRUNCATE, RetTyVT, RetVal); break; } diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index e2c3ae0ff9b..8ec8a5a46f5 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -4519,8 +4519,8 @@ SDOperand X86TargetLowering::LowerMEMSET(SDOperand Op, SelectionDAG &DAG) { Entry.Node = Op.getOperand(3); Args.push_back(Entry); std::pair CallResult = - LowerCallTo(Chain, Type::VoidTy, false, false, CallingConv::C, false, - DAG.getExternalSymbol("memset", IntPtr), Args, DAG); + LowerCallTo(Chain, Type::VoidTy, false, false, false, CallingConv::C, + false, DAG.getExternalSymbol("memset", IntPtr), Args, DAG); return CallResult.second; }