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
This commit is contained in:
Duncan Sands 2008-02-14 17:28:50 +00:00
parent e179584f9b
commit 00fee65fd2
11 changed files with 62 additions and 38 deletions

View File

@ -924,8 +924,8 @@ public:
};
typedef std::vector<ArgListEntry> ArgListTy;
virtual std::pair<SDOperand, SDOperand>
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);

View File

@ -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

View File

@ -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);

View File

@ -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;
}

View File

@ -742,7 +742,7 @@ ARMTargetLowering::LowerToTLSGeneralDynamicModel(GlobalAddressSDNode *GA,
Entry.Ty = (const Type *) Type::Int32Ty;
Args.push_back(Entry);
std::pair<SDOperand, SDOperand> 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;

View File

@ -319,7 +319,7 @@ static SDOperand LowerRET(SDOperand Op, SelectionDAG &DAG) {
std::pair<SDOperand, SDOperand>
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);
}

View File

@ -77,7 +77,7 @@ namespace llvm {
/// LowerCallTo - This hook lowers an abstract call to a function into an
/// actual call.
virtual std::pair<SDOperand, SDOperand>
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);

View File

@ -298,8 +298,8 @@ IA64TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) {
}
std::pair<SDOperand, SDOperand>
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) {

View File

@ -58,10 +58,11 @@ namespace llvm {
/// LowerCallTo - This hook lowers an abstract call to a function into an
/// actual call.
virtual std::pair<SDOperand, SDOperand>
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);

View File

@ -119,8 +119,9 @@ namespace {
virtual std::vector<SDOperand>
LowerArguments(Function &F, SelectionDAG &DAG);
virtual std::pair<SDOperand, SDOperand>
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<SDOperand, SDOperand>
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;
}

View File

@ -4519,8 +4519,8 @@ SDOperand X86TargetLowering::LowerMEMSET(SDOperand Op, SelectionDAG &DAG) {
Entry.Node = Op.getOperand(3);
Args.push_back(Entry);
std::pair<SDOperand,SDOperand> 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;
}