mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-24 11:42:57 +01:00
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. llvm-svn: 47122
This commit is contained in:
parent
1ef1013b6c
commit
0056f1e823
@ -924,8 +924,8 @@ public:
|
|||||||
};
|
};
|
||||||
typedef std::vector<ArgListEntry> ArgListTy;
|
typedef std::vector<ArgListEntry> ArgListTy;
|
||||||
virtual std::pair<SDOperand, SDOperand>
|
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 CallingConv, bool isTailCall,
|
bool isVarArg, unsigned CallingConv, bool isTailCall,
|
||||||
SDOperand Callee, ArgListTy &Args, SelectionDAG &DAG);
|
SDOperand Callee, ArgListTy &Args, SelectionDAG &DAG);
|
||||||
|
|
||||||
|
|
||||||
|
@ -2862,7 +2862,8 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::pair<SDOperand,SDOperand> CallResult =
|
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);
|
DAG.getExternalSymbol(FnName, IntPtr), Args, DAG);
|
||||||
Result = CallResult.second;
|
Result = CallResult.second;
|
||||||
break;
|
break;
|
||||||
@ -3963,7 +3964,8 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
|
|||||||
Tmp1 = LegalizeOp(Node->getOperand(0));
|
Tmp1 = LegalizeOp(Node->getOperand(0));
|
||||||
TargetLowering::ArgListTy Args;
|
TargetLowering::ArgListTy Args;
|
||||||
std::pair<SDOperand,SDOperand> CallResult =
|
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()),
|
DAG.getExternalSymbol("abort", TLI.getPointerTy()),
|
||||||
Args, DAG);
|
Args, DAG);
|
||||||
Result = CallResult.second;
|
Result = CallResult.second;
|
||||||
@ -5153,6 +5155,7 @@ SDOperand SelectionDAGLegalize::ExpandLibCall(const char *Name, SDNode *Node,
|
|||||||
const Type *ArgTy = MVT::getTypeForValueType(ArgVT);
|
const Type *ArgTy = MVT::getTypeForValueType(ArgVT);
|
||||||
Entry.Node = Node->getOperand(i); Entry.Ty = ArgTy;
|
Entry.Node = Node->getOperand(i); Entry.Ty = ArgTy;
|
||||||
Entry.isSExt = isSigned;
|
Entry.isSExt = isSigned;
|
||||||
|
Entry.isZExt = !isSigned;
|
||||||
Args.push_back(Entry);
|
Args.push_back(Entry);
|
||||||
}
|
}
|
||||||
SDOperand Callee = DAG.getExternalSymbol(Name, TLI.getPointerTy());
|
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.
|
// Splice the libcall in wherever FindInputOutputChains tells us to.
|
||||||
const Type *RetTy = MVT::getTypeForValueType(Node->getValueType(0));
|
const Type *RetTy = MVT::getTypeForValueType(Node->getValueType(0));
|
||||||
std::pair<SDOperand,SDOperand> CallInfo =
|
std::pair<SDOperand,SDOperand> CallInfo =
|
||||||
TLI.LowerCallTo(InChain, RetTy, isSigned, false, CallingConv::C, false,
|
TLI.LowerCallTo(InChain, RetTy, isSigned, !isSigned, false, CallingConv::C,
|
||||||
Callee, Args, DAG);
|
false, Callee, Args, DAG);
|
||||||
|
|
||||||
// Legalize the call sequence, starting with the chain. This will advance
|
// Legalize the call sequence, starting with the chain. This will advance
|
||||||
// the LastCALLSEQ_END to the legalized version of the CALLSEQ_END node that
|
// the LastCALLSEQ_END to the legalized version of the CALLSEQ_END node that
|
||||||
|
@ -3092,6 +3092,7 @@ void SelectionDAGLowering::LowerCallTo(CallSite CS, SDOperand Callee,
|
|||||||
std::pair<SDOperand,SDOperand> Result =
|
std::pair<SDOperand,SDOperand> Result =
|
||||||
TLI.LowerCallTo(getRoot(), CS.getType(),
|
TLI.LowerCallTo(getRoot(), CS.getType(),
|
||||||
CS.paramHasAttr(0, ParamAttr::SExt),
|
CS.paramHasAttr(0, ParamAttr::SExt),
|
||||||
|
CS.paramHasAttr(0, ParamAttr::ZExt),
|
||||||
FTy->isVarArg(), CS.getCallingConv(), IsTailCall,
|
FTy->isVarArg(), CS.getCallingConv(), IsTailCall,
|
||||||
Callee, Args, DAG);
|
Callee, Args, DAG);
|
||||||
if (CS.getType() != Type::VoidTy)
|
if (CS.getType() != Type::VoidTy)
|
||||||
@ -3951,9 +3952,8 @@ void SelectionDAGLowering::visitMalloc(MallocInst &I) {
|
|||||||
Args.push_back(Entry);
|
Args.push_back(Entry);
|
||||||
|
|
||||||
std::pair<SDOperand,SDOperand> Result =
|
std::pair<SDOperand,SDOperand> Result =
|
||||||
TLI.LowerCallTo(getRoot(), I.getType(), false, false, CallingConv::C, true,
|
TLI.LowerCallTo(getRoot(), I.getType(), false, false, false, CallingConv::C,
|
||||||
DAG.getExternalSymbol("malloc", IntPtr),
|
true, DAG.getExternalSymbol("malloc", IntPtr), Args, DAG);
|
||||||
Args, DAG);
|
|
||||||
setValue(&I, Result.first); // Pointers always fit in registers
|
setValue(&I, Result.first); // Pointers always fit in registers
|
||||||
DAG.setRoot(Result.second);
|
DAG.setRoot(Result.second);
|
||||||
}
|
}
|
||||||
@ -3966,7 +3966,8 @@ void SelectionDAGLowering::visitFree(FreeInst &I) {
|
|||||||
Args.push_back(Entry);
|
Args.push_back(Entry);
|
||||||
MVT::ValueType IntPtr = TLI.getPointerTy();
|
MVT::ValueType IntPtr = TLI.getPointerTy();
|
||||||
std::pair<SDOperand,SDOperand> Result =
|
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.getExternalSymbol("free", IntPtr), Args, DAG);
|
||||||
DAG.setRoot(Result.second);
|
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
|
/// lowered by the target to something concrete. FIXME: When all targets are
|
||||||
/// migrated to using ISD::CALL, this hook should be integrated into SDISel.
|
/// migrated to using ISD::CALL, this hook should be integrated into SDISel.
|
||||||
std::pair<SDOperand, SDOperand>
|
std::pair<SDOperand, SDOperand>
|
||||||
TargetLowering::LowerCallTo(SDOperand Chain, const Type *RetTy,
|
TargetLowering::LowerCallTo(SDOperand Chain, const Type *RetTy,
|
||||||
bool RetTyIsSigned, bool isVarArg,
|
bool RetSExt, bool RetZExt, bool isVarArg,
|
||||||
unsigned CallingConv, bool isTailCall,
|
unsigned CallingConv, bool isTailCall,
|
||||||
SDOperand Callee,
|
SDOperand Callee,
|
||||||
ArgListTy &Args, SelectionDAG &DAG) {
|
ArgListTy &Args, SelectionDAG &DAG) {
|
||||||
SmallVector<SDOperand, 32> Ops;
|
SmallVector<SDOperand, 32> Ops;
|
||||||
@ -4209,13 +4210,18 @@ TargetLowering::LowerCallTo(SDOperand Chain, const Type *RetTy,
|
|||||||
|
|
||||||
// Gather up the call result into a single value.
|
// Gather up the call result into a single value.
|
||||||
if (RetTy != Type::VoidTy) {
|
if (RetTy != Type::VoidTy) {
|
||||||
ISD::NodeType AssertOp = ISD::AssertSext;
|
ISD::NodeType AssertOp = ISD::DELETED_NODE;
|
||||||
if (!RetTyIsSigned)
|
|
||||||
|
if (RetSExt)
|
||||||
|
AssertOp = ISD::AssertSext;
|
||||||
|
else if (RetZExt)
|
||||||
AssertOp = ISD::AssertZext;
|
AssertOp = ISD::AssertZext;
|
||||||
|
|
||||||
SmallVector<SDOperand, 4> Results(NumRegs);
|
SmallVector<SDOperand, 4> Results(NumRegs);
|
||||||
for (unsigned i = 0; i != NumRegs; ++i)
|
for (unsigned i = 0; i != NumRegs; ++i)
|
||||||
Results[i] = Res.getValue(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);
|
return std::make_pair(Res, Chain);
|
||||||
|
@ -264,8 +264,8 @@ SDOperand TargetLowering::LowerMEMCPYCall(SDOperand Chain,
|
|||||||
Entry.Node = Source; Args.push_back(Entry);
|
Entry.Node = Source; Args.push_back(Entry);
|
||||||
Entry.Node = Count; Args.push_back(Entry);
|
Entry.Node = Count; Args.push_back(Entry);
|
||||||
std::pair<SDOperand,SDOperand> CallResult =
|
std::pair<SDOperand,SDOperand> CallResult =
|
||||||
LowerCallTo(Chain, Type::VoidTy, false, false, CallingConv::C, false,
|
LowerCallTo(Chain, Type::VoidTy, false, false, false, CallingConv::C,
|
||||||
DAG.getExternalSymbol("memcpy", IntPtr), Args, DAG);
|
false, DAG.getExternalSymbol("memcpy", IntPtr), Args, DAG);
|
||||||
return CallResult.second;
|
return CallResult.second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -742,7 +742,7 @@ ARMTargetLowering::LowerToTLSGeneralDynamicModel(GlobalAddressSDNode *GA,
|
|||||||
Entry.Ty = (const Type *) Type::Int32Ty;
|
Entry.Ty = (const Type *) Type::Int32Ty;
|
||||||
Args.push_back(Entry);
|
Args.push_back(Entry);
|
||||||
std::pair<SDOperand, SDOperand> CallResult =
|
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,
|
CallingConv::C, false,
|
||||||
DAG.getExternalSymbol("__tls_get_addr", PtrVT), Args, DAG);
|
DAG.getExternalSymbol("__tls_get_addr", PtrVT), Args, DAG);
|
||||||
return CallResult.first;
|
return CallResult.first;
|
||||||
|
@ -319,7 +319,7 @@ static SDOperand LowerRET(SDOperand Op, SelectionDAG &DAG) {
|
|||||||
|
|
||||||
std::pair<SDOperand, SDOperand>
|
std::pair<SDOperand, SDOperand>
|
||||||
AlphaTargetLowering::LowerCallTo(SDOperand Chain, const Type *RetTy,
|
AlphaTargetLowering::LowerCallTo(SDOperand Chain, const Type *RetTy,
|
||||||
bool RetTyIsSigned, bool isVarArg,
|
bool RetSExt, bool RetZExt, bool isVarArg,
|
||||||
unsigned CallingConv, bool isTailCall,
|
unsigned CallingConv, bool isTailCall,
|
||||||
SDOperand Callee, ArgListTy &Args,
|
SDOperand Callee, ArgListTy &Args,
|
||||||
SelectionDAG &DAG) {
|
SelectionDAG &DAG) {
|
||||||
@ -378,8 +378,16 @@ AlphaTargetLowering::LowerCallTo(SDOperand Chain, const Type *RetTy,
|
|||||||
SDOperand RetVal = TheCall;
|
SDOperand RetVal = TheCall;
|
||||||
|
|
||||||
if (RetTyVT != ActualRetTyVT) {
|
if (RetTyVT != ActualRetTyVT) {
|
||||||
RetVal = DAG.getNode(RetTyIsSigned ? ISD::AssertSext : ISD::AssertZext,
|
ISD::NodeType AssertKind = ISD::DELETED_NODE;
|
||||||
MVT::i64, RetVal, DAG.getValueType(RetTyVT));
|
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);
|
RetVal = DAG.getNode(ISD::TRUNCATE, RetTyVT, RetVal);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,7 +77,7 @@ namespace llvm {
|
|||||||
/// LowerCallTo - This hook lowers an abstract call to a function into an
|
/// LowerCallTo - This hook lowers an abstract call to a function into an
|
||||||
/// actual call.
|
/// actual call.
|
||||||
virtual std::pair<SDOperand, SDOperand>
|
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,
|
bool isVarArg, unsigned CC, bool isTailCall, SDOperand Callee,
|
||||||
ArgListTy &Args, SelectionDAG &DAG);
|
ArgListTy &Args, SelectionDAG &DAG);
|
||||||
|
|
||||||
|
@ -298,8 +298,8 @@ IA64TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::pair<SDOperand, SDOperand>
|
std::pair<SDOperand, SDOperand>
|
||||||
IA64TargetLowering::LowerCallTo(SDOperand Chain,
|
IA64TargetLowering::LowerCallTo(SDOperand Chain, const Type *RetTy,
|
||||||
const Type *RetTy, bool RetTyIsSigned,
|
bool RetSExt, bool RetZExt,
|
||||||
bool isVarArg, unsigned CallingConv,
|
bool isVarArg, unsigned CallingConv,
|
||||||
bool isTailCall, SDOperand Callee,
|
bool isTailCall, SDOperand Callee,
|
||||||
ArgListTy &Args, SelectionDAG &DAG) {
|
ArgListTy &Args, SelectionDAG &DAG) {
|
||||||
|
@ -58,10 +58,11 @@ namespace llvm {
|
|||||||
/// LowerCallTo - This hook lowers an abstract call to a function into an
|
/// LowerCallTo - This hook lowers an abstract call to a function into an
|
||||||
/// actual call.
|
/// actual call.
|
||||||
virtual std::pair<SDOperand, SDOperand>
|
virtual std::pair<SDOperand, SDOperand>
|
||||||
LowerCallTo(SDOperand Chain, const Type *RetTy, bool RetTyIsSigned,
|
LowerCallTo(SDOperand Chain, const Type *RetTy,
|
||||||
bool isVarArg, unsigned CC, bool isTailCall,
|
bool RetSExt, bool RetZExt, bool isVarArg,
|
||||||
|
unsigned CC, bool isTailCall,
|
||||||
SDOperand Callee, ArgListTy &Args, SelectionDAG &DAG);
|
SDOperand Callee, ArgListTy &Args, SelectionDAG &DAG);
|
||||||
|
|
||||||
/// LowerOperation - for custom lowering specific ops
|
/// LowerOperation - for custom lowering specific ops
|
||||||
/// (currently, only "ret void")
|
/// (currently, only "ret void")
|
||||||
virtual SDOperand LowerOperation(SDOperand Op, SelectionDAG &DAG);
|
virtual SDOperand LowerOperation(SDOperand Op, SelectionDAG &DAG);
|
||||||
|
@ -119,8 +119,9 @@ namespace {
|
|||||||
virtual std::vector<SDOperand>
|
virtual std::vector<SDOperand>
|
||||||
LowerArguments(Function &F, SelectionDAG &DAG);
|
LowerArguments(Function &F, SelectionDAG &DAG);
|
||||||
virtual std::pair<SDOperand, SDOperand>
|
virtual std::pair<SDOperand, SDOperand>
|
||||||
LowerCallTo(SDOperand Chain, const Type *RetTy, bool RetTyIsSigned,
|
LowerCallTo(SDOperand Chain, const Type *RetTy,
|
||||||
bool isVarArg, unsigned CC, bool isTailCall, SDOperand Callee,
|
bool RetSExt, bool RetZExt, bool isVarArg,
|
||||||
|
unsigned CC, bool isTailCall, SDOperand Callee,
|
||||||
ArgListTy &Args, SelectionDAG &DAG);
|
ArgListTy &Args, SelectionDAG &DAG);
|
||||||
virtual MachineBasicBlock *EmitInstrWithCustomInserter(MachineInstr *MI,
|
virtual MachineBasicBlock *EmitInstrWithCustomInserter(MachineInstr *MI,
|
||||||
MachineBasicBlock *MBB);
|
MachineBasicBlock *MBB);
|
||||||
@ -481,8 +482,8 @@ SparcTargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) {
|
|||||||
|
|
||||||
std::pair<SDOperand, SDOperand>
|
std::pair<SDOperand, SDOperand>
|
||||||
SparcTargetLowering::LowerCallTo(SDOperand Chain, const Type *RetTy,
|
SparcTargetLowering::LowerCallTo(SDOperand Chain, const Type *RetTy,
|
||||||
bool RetTyIsSigned, bool isVarArg, unsigned CC,
|
bool RetSExt, bool RetZExt, bool isVarArg,
|
||||||
bool isTailCall, SDOperand Callee,
|
unsigned CC, bool isTailCall, SDOperand Callee,
|
||||||
ArgListTy &Args, SelectionDAG &DAG) {
|
ArgListTy &Args, SelectionDAG &DAG) {
|
||||||
// Count the size of the outgoing arguments.
|
// Count the size of the outgoing arguments.
|
||||||
unsigned ArgsSize = 0;
|
unsigned ArgsSize = 0;
|
||||||
@ -646,11 +647,16 @@ SparcTargetLowering::LowerCallTo(SDOperand Chain, const Type *RetTy,
|
|||||||
Chain = RetVal.getValue(1);
|
Chain = RetVal.getValue(1);
|
||||||
|
|
||||||
// Add a note to keep track of whether it is sign or zero extended.
|
// Add a note to keep track of whether it is sign or zero extended.
|
||||||
ISD::NodeType AssertKind = ISD::AssertZext;
|
ISD::NodeType AssertKind = ISD::DELETED_NODE;
|
||||||
if (RetTyIsSigned)
|
if (RetSExt)
|
||||||
AssertKind = ISD::AssertSext;
|
AssertKind = ISD::AssertSext;
|
||||||
RetVal = DAG.getNode(AssertKind, MVT::i32, RetVal,
|
else if (RetZExt)
|
||||||
DAG.getValueType(RetTyVT));
|
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);
|
RetVal = DAG.getNode(ISD::TRUNCATE, RetTyVT, RetVal);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -4519,8 +4519,8 @@ SDOperand X86TargetLowering::LowerMEMSET(SDOperand Op, SelectionDAG &DAG) {
|
|||||||
Entry.Node = Op.getOperand(3);
|
Entry.Node = Op.getOperand(3);
|
||||||
Args.push_back(Entry);
|
Args.push_back(Entry);
|
||||||
std::pair<SDOperand,SDOperand> CallResult =
|
std::pair<SDOperand,SDOperand> CallResult =
|
||||||
LowerCallTo(Chain, Type::VoidTy, false, false, CallingConv::C, false,
|
LowerCallTo(Chain, Type::VoidTy, false, false, false, CallingConv::C,
|
||||||
DAG.getExternalSymbol("memset", IntPtr), Args, DAG);
|
false, DAG.getExternalSymbol("memset", IntPtr), Args, DAG);
|
||||||
return CallResult.second;
|
return CallResult.second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user