diff options
author | Duncan Sands <baldrick@free.fr> | 2008-02-14 17:28:50 +0000 |
---|---|---|
committer | Duncan Sands <baldrick@free.fr> | 2008-02-14 17:28:50 +0000 |
commit | 00fee65fd21f9615d1a604b8b7d42cd16a3f6b47 (patch) | |
tree | 6f4bfac1aa91b133348dc8e71727c95cb34d95f1 /lib/CodeGen | |
parent | e179584f9b740cf3a36bde70f8cab40de59b8081 (diff) |
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
Diffstat (limited to 'lib/CodeGen')
-rw-r--r-- | lib/CodeGen/SelectionDAG/LegalizeDAG.cpp | 11 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp | 26 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/TargetLowering.cpp | 4 |
3 files changed, 25 insertions, 16 deletions
diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp index f0f3d1ca7b..a0dad4d88b 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp @@ -2862,7 +2862,8 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) { } std::pair<SDOperand,SDOperand> 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<SDOperand,SDOperand> 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<SDOperand,SDOperand> 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 e767c280d4..b3d7fbfcf9 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<SDOperand,SDOperand> 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<SDOperand,SDOperand> 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<SDOperand,SDOperand> 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<SDOperand, SDOperand> -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<SDOperand, 32> 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<SDOperand, 4> 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 e58c2f76ff..eb0370aaf6 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<SDOperand,SDOperand> 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; } |