In TargetLowering::LowerCallTo, don't assert that
authorDuncan Sands <baldrick@free.fr>
Thu, 14 Feb 2008 17:28:50 +0000 (17:28 +0000)
committerDuncan Sands <baldrick@free.fr>
Thu, 14 Feb 2008 17:28:50 +0000 (17:28 +0000)
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
lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
lib/CodeGen/SelectionDAG/TargetLowering.cpp
lib/Target/ARM/ARMISelLowering.cpp
lib/Target/Alpha/AlphaISelLowering.cpp
lib/Target/Alpha/AlphaISelLowering.h
lib/Target/IA64/IA64ISelLowering.cpp
lib/Target/IA64/IA64ISelLowering.h
lib/Target/Sparc/SparcISelDAGToDAG.cpp
lib/Target/X86/X86ISelLowering.cpp

index ef8a4474097abed005e6845e1ffc85f929f27e9e..0d03cdad1dc037d1287020056b73528dfabd88d8 100644 (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);
 
 
index f0f3d1ca7b9291360d33636eb87d6cf20740be4d..a0dad4d88b0106b3aa99f79eda8d0f6ec8c872d9 100644 (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
index e767c280d42fbfe343f5754aa76f8c0a6a1e8d3b..b3d7fbfcf99acde60b9560345c6ee3ee8dfd57f8 100644 (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);
index e58c2f76ff1fd45eeaec1f2fb3dd928cdd0de782..eb0370aaf6d45e9a2ce7bd8b40aaec1901dd6d65 100644 (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;
 }
 
index 066d8e3ede2b1159b5f34b228b417f43914f26b3..98165a27c54bde00ef730f9e8a8f2414cb1d05e2 100644 (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;
index 774dad3e44a05eb34e18e85f8e1d608e1fe2ee9d..028f8851038b266381b7d587c38169353e165aa6 100644 (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);
   }
 
index e0b4b70b947a3da3908f46544db8c97c8d270738..a118d99462f73239e587a2f28a72e14e62e67f05 100644 (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);
 
index 9d74ee16d12b6b760ba5a6762b5df515ffb6b4d7..6b9cf1592bb5cc3004b60b723049001220e16267 100644 (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) {
index 20724d24fb0c2460257c2d70c2b85c0c0607031f..7c9c5c3a10fdfdfb2423ff8b98bf84a8c9c5b782 100644 (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);
index e8943621d3c743c1b2bd2a7483130196fffdb80b..8dd81b76d3bcb808d30d81519d3325531dcca3c8 100644 (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;
     }
index e2c3ae0ff9b21a34e453ec42d8bcfe988e6c447b..8ec8a5a46f5aa7281045e27ebf60114eba584e9f 100644 (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;
   }