summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDuncan Sands <baldrick@free.fr>2008-02-14 17:28:50 +0000
committerDuncan Sands <baldrick@free.fr>2008-02-14 17:28:50 +0000
commit00fee65fd21f9615d1a604b8b7d42cd16a3f6b47 (patch)
tree6f4bfac1aa91b133348dc8e71727c95cb34d95f1
parente179584f9b740cf3a36bde70f8cab40de59b8081 (diff)
downloadllvm-00fee65fd21f9615d1a604b8b7d42cd16a3f6b47.tar.gz
llvm-00fee65fd21f9615d1a604b8b7d42cd16a3f6b47.tar.bz2
llvm-00fee65fd21f9615d1a604b8b7d42cd16a3f6b47.tar.xz
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
-rw-r--r--include/llvm/Target/TargetLowering.h4
-rw-r--r--lib/CodeGen/SelectionDAG/LegalizeDAG.cpp11
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp26
-rw-r--r--lib/CodeGen/SelectionDAG/TargetLowering.cpp4
-rw-r--r--lib/Target/ARM/ARMISelLowering.cpp2
-rw-r--r--lib/Target/Alpha/AlphaISelLowering.cpp14
-rw-r--r--lib/Target/Alpha/AlphaISelLowering.h2
-rw-r--r--lib/Target/IA64/IA64ISelLowering.cpp4
-rw-r--r--lib/Target/IA64/IA64ISelLowering.h7
-rw-r--r--lib/Target/Sparc/SparcISelDAGToDAG.cpp22
-rw-r--r--lib/Target/X86/X86ISelLowering.cpp4
11 files changed, 62 insertions, 38 deletions
diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h
index ef8a447409..0d03cdad1d 100644
--- a/include/llvm/Target/TargetLowering.h
+++ b/include/llvm/Target/TargetLowering.h
@@ -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);
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;
}
diff --git a/lib/Target/ARM/ARMISelLowering.cpp b/lib/Target/ARM/ARMISelLowering.cpp
index 066d8e3ede..98165a27c5 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<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;
diff --git a/lib/Target/Alpha/AlphaISelLowering.cpp b/lib/Target/Alpha/AlphaISelLowering.cpp
index 774dad3e44..028f885103 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<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);
}
diff --git a/lib/Target/Alpha/AlphaISelLowering.h b/lib/Target/Alpha/AlphaISelLowering.h
index e0b4b70b94..a118d99462 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<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);
diff --git a/lib/Target/IA64/IA64ISelLowering.cpp b/lib/Target/IA64/IA64ISelLowering.cpp
index 9d74ee16d1..6b9cf1592b 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<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) {
diff --git a/lib/Target/IA64/IA64ISelLowering.h b/lib/Target/IA64/IA64ISelLowering.h
index 20724d24fb..7c9c5c3a10 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<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);
diff --git a/lib/Target/Sparc/SparcISelDAGToDAG.cpp b/lib/Target/Sparc/SparcISelDAGToDAG.cpp
index e8943621d3..8dd81b76d3 100644
--- a/lib/Target/Sparc/SparcISelDAGToDAG.cpp
+++ b/lib/Target/Sparc/SparcISelDAGToDAG.cpp
@@ -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;
}
diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp
index e2c3ae0ff9..8ec8a5a46f 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<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;
}