[llvm-commits] [llvm] r53461 - in /llvm/trunk: include/llvm/CodeGen/RuntimeLibcalls.h lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp lib/CodeGen/SelectionDAG/LegalizeTypes.h lib/CodeGen/SelectionDAG/TargetLowering.cpp

Duncan Sands baldrick at free.fr
Fri Jul 11 10:00:14 PDT 2008


Author: baldrick
Date: Fri Jul 11 12:00:14 2008
New Revision: 53461

URL: http://llvm.org/viewvc/llvm-project?rev=53461&view=rev
Log:
It is pointless to turn a UINT_TO_FP into an
SINT_TO_FP libcall plus additional operations:
it might as well be a direct UINT_TO_FP libcall.
So only turn it into an SINT_TO_FP if the target
has special handling for SINT_TO_FP.

Modified:
    llvm/trunk/include/llvm/CodeGen/RuntimeLibcalls.h
    llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
    llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h
    llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp

Modified: llvm/trunk/include/llvm/CodeGen/RuntimeLibcalls.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/RuntimeLibcalls.h?rev=53461&r1=53460&r2=53461&view=diff

==============================================================================
--- llvm/trunk/include/llvm/CodeGen/RuntimeLibcalls.h (original)
+++ llvm/trunk/include/llvm/CodeGen/RuntimeLibcalls.h Fri Jul 11 12:00:14 2008
@@ -137,8 +137,16 @@
     SINTTOFP_I128_PPCF128,
     UINTTOFP_I32_F32,
     UINTTOFP_I32_F64,
+    UINTTOFP_I32_F80,
+    UINTTOFP_I32_PPCF128,
     UINTTOFP_I64_F32,
     UINTTOFP_I64_F64,
+    UINTTOFP_I64_F80,
+    UINTTOFP_I64_PPCF128,
+    UINTTOFP_I128_F32,
+    UINTTOFP_I128_F64,
+    UINTTOFP_I128_F80,
+    UINTTOFP_I128_PPCF128,
 
     // COMPARISON
     OEQ_F32,

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp?rev=53461&r1=53460&r2=53461&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp Fri Jul 11 12:00:14 2008
@@ -1727,12 +1727,8 @@
 
     case ISD::TRUNCATE:        Res = ExpandIntOp_TRUNCATE(N); break;
 
-    case ISD::SINT_TO_FP:
-      Res = ExpandIntOp_SINT_TO_FP(N->getOperand(0), N->getValueType(0));
-      break;
-    case ISD::UINT_TO_FP:
-      Res = ExpandIntOp_UINT_TO_FP(N->getOperand(0), N->getValueType(0));
-      break;
+    case ISD::SINT_TO_FP:      Res = ExpandIntOp_SINT_TO_FP(N); break;
+    case ISD::UINT_TO_FP:      Res = ExpandIntOp_UINT_TO_FP(N); break;
 
     case ISD::BR_CC:     Res = ExpandIntOp_BR_CC(N); break;
     case ISD::SELECT_CC: Res = ExpandIntOp_SELECT_CC(N); break;
@@ -1770,99 +1766,134 @@
   return DAG.getNode(ISD::TRUNCATE, N->getValueType(0), InL);
 }
 
-SDOperand DAGTypeLegalizer::ExpandIntOp_SINT_TO_FP(SDOperand Source,
-                                                   MVT DestTy) {
-  // We know the destination is legal, but that the input needs to be expanded.
-  MVT SourceVT = Source.getValueType();
-
-  // Check to see if the target has a custom way to lower this.  If so, use it.
-  // This can trigger when called from ExpandIntOp_UINT_TO_FP.
-  switch (TLI.getOperationAction(ISD::SINT_TO_FP, SourceVT)) {
-  default: assert(0 && "This action not implemented for this operation!");
-  case TargetLowering::Legal:
-  case TargetLowering::Expand:
-    break;   // This case is handled below.
-  case TargetLowering::Custom:
-    SDOperand NV = TLI.LowerOperation(DAG.getNode(ISD::SINT_TO_FP, DestTy,
-                                                  Source), DAG);
-    if (NV.Val) return NV;
-    break;   // The target lowered this.
-  }
+SDOperand DAGTypeLegalizer::ExpandIntOp_SINT_TO_FP(SDNode *N) {
+  SDOperand Op = N->getOperand(0);
+  MVT SrcVT = Op.getValueType();
+  MVT DstVT = N->getValueType(0);
 
   RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
-  if (SourceVT == MVT::i32) {
-    if (DestTy == MVT::f32)
+  if (SrcVT == MVT::i32) {
+    if (DstVT == MVT::f32)
       LC = RTLIB::SINTTOFP_I32_F32;
-    else if (DestTy == MVT::f64)
+    else if (DstVT == MVT::f64)
       LC = RTLIB::SINTTOFP_I32_F64;
-    else if (DestTy == MVT::f80)
+    else if (DstVT == MVT::f80)
       LC = RTLIB::SINTTOFP_I32_F80;
-    else if (DestTy == MVT::ppcf128)
+    else if (DstVT == MVT::ppcf128)
       LC = RTLIB::SINTTOFP_I32_PPCF128;
-  } else if (SourceVT == MVT::i64) {
-    if (DestTy == MVT::f32)
+  } else if (SrcVT == MVT::i64) {
+    if (DstVT == MVT::f32)
       LC = RTLIB::SINTTOFP_I64_F32;
-    else if (DestTy == MVT::f64)
+    else if (DstVT == MVT::f64)
       LC = RTLIB::SINTTOFP_I64_F64;
-    else if (DestTy == MVT::f80)
+    else if (DstVT == MVT::f80)
       LC = RTLIB::SINTTOFP_I64_F80;
-    else if (DestTy == MVT::ppcf128)
+    else if (DstVT == MVT::ppcf128)
       LC = RTLIB::SINTTOFP_I64_PPCF128;
-  } else if (SourceVT == MVT::i128) {
-    if (DestTy == MVT::f32)
+  } else if (SrcVT == MVT::i128) {
+    if (DstVT == MVT::f32)
       LC = RTLIB::SINTTOFP_I128_F32;
-    else if (DestTy == MVT::f64)
+    else if (DstVT == MVT::f64)
       LC = RTLIB::SINTTOFP_I128_F64;
-    else if (DestTy == MVT::f80)
+    else if (DstVT == MVT::f80)
       LC = RTLIB::SINTTOFP_I128_F80;
-    else if (DestTy == MVT::ppcf128)
+    else if (DstVT == MVT::ppcf128)
       LC = RTLIB::SINTTOFP_I128_PPCF128;
   }
   assert(LC != RTLIB::UNKNOWN_LIBCALL &&
          "Don't know how to expand this SINT_TO_FP!");
 
-  return MakeLibCall(LC, DestTy, &Source, 1, true);
+  return MakeLibCall(LC, DstVT, &Op, 1, true);
 }
 
-SDOperand DAGTypeLegalizer::ExpandIntOp_UINT_TO_FP(SDOperand Source,
-                                                     MVT DestTy) {
-  // We know the destination is legal, but that the input needs to be expanded.
-  assert(getTypeAction(Source.getValueType()) == ExpandInteger &&
-         "This is not an expansion!");
-
-  // If this is unsigned, and not supported, first perform the conversion to
-  // signed, then adjust the result if the sign bit is set.
-  SDOperand SignedConv = ExpandIntOp_SINT_TO_FP(Source, DestTy);
-
-  // The 64-bit value loaded will be incorrectly if the 'sign bit' of the
-  // incoming integer is set.  To handle this, we dynamically test to see if
-  // it is set, and, if so, add a fudge factor.
-  SDOperand Lo, Hi;
-  GetExpandedInteger(Source, Lo, Hi);
+SDOperand DAGTypeLegalizer::ExpandIntOp_UINT_TO_FP(SDNode *N) {
+  SDOperand Op = N->getOperand(0);
+  MVT SrcVT = Op.getValueType();
+  MVT DstVT = N->getValueType(0);
+
+  if (TLI.getOperationAction(ISD::SINT_TO_FP, SrcVT) == TargetLowering::Custom){
+    // Do a signed conversion then adjust the result.
+    SDOperand SignedConv = DAG.getNode(ISD::SINT_TO_FP, DstVT, Op);
+    SignedConv = TLI.LowerOperation(SignedConv, DAG);
+
+    // The result of the signed conversion needs adjusting if the 'sign bit' of
+    // the incoming integer was set.  To handle this, we dynamically test to see
+    // if it is set, and, if so, add a fudge factor.
+
+    const uint64_t F32TwoE32  = 0x4F800000ULL;
+    const uint64_t F32TwoE64  = 0x5F800000ULL;
+    const uint64_t F32TwoE128 = 0x7F800000ULL;
+
+    APInt FF(32, 0);
+    if (SrcVT == MVT::i32)
+      FF = APInt(32, F32TwoE32);
+    else if (SrcVT == MVT::i64)
+      FF = APInt(32, F32TwoE64);
+    else if (SrcVT == MVT::i128)
+      FF = APInt(32, F32TwoE128);
+    else
+      assert(false && "Unsupported UINT_TO_FP!");
+
+    // Check whether the sign bit is set.
+    SDOperand Lo, Hi;
+    GetExpandedInteger(Op, Lo, Hi);
+    SDOperand SignSet = DAG.getSetCC(TLI.getSetCCResultType(Hi), Hi,
+                                     DAG.getConstant(0, Hi.getValueType()),
+                                     ISD::SETLT);
+
+    // Build a 64 bit pair (0, FF) in the constant pool, with FF in the lo bits.
+    SDOperand FudgePtr = DAG.getConstantPool(ConstantInt::get(FF.zext(64)),
+                                             TLI.getPointerTy());
+
+    // Get a pointer to FF if the sign bit was set, or to 0 otherwise.
+    SDOperand Zero = DAG.getIntPtrConstant(0);
+    SDOperand Four = DAG.getIntPtrConstant(4);
+    if (TLI.isBigEndian()) std::swap(Zero, Four);
+    SDOperand Offset = DAG.getNode(ISD::SELECT, Zero.getValueType(), SignSet,
+                                   Zero, Four);
+    FudgePtr = DAG.getNode(ISD::ADD, TLI.getPointerTy(), FudgePtr, Offset);
+
+    // Load the value out, extending it from f32 to the destination float type.
+    // FIXME: Avoid the extend by constructing the right constant pool?
+    SDOperand Fudge = DAG.getExtLoad(ISD::EXTLOAD, DstVT, DAG.getEntryNode(),
+                                     FudgePtr, NULL, 0, MVT::f32);
+    return DAG.getNode(ISD::FADD, DstVT, SignedConv, Fudge);
+  }
 
-  SDOperand SignSet = DAG.getSetCC(TLI.getSetCCResultType(Hi), Hi,
-                                   DAG.getConstant(0, Hi.getValueType()),
-                                   ISD::SETLT);
-  SDOperand Zero = DAG.getIntPtrConstant(0), Four = DAG.getIntPtrConstant(4);
-  SDOperand CstOffset = DAG.getNode(ISD::SELECT, Zero.getValueType(),
-                                    SignSet, Four, Zero);
-  uint64_t FF = 0x5f800000ULL;
-  if (TLI.isLittleEndian()) FF <<= 32;
-  Constant *FudgeFactor = ConstantInt::get((Type*)Type::Int64Ty, FF);
-
-  SDOperand CPIdx = DAG.getConstantPool(FudgeFactor, TLI.getPointerTy());
-  CPIdx = DAG.getNode(ISD::ADD, TLI.getPointerTy(), CPIdx, CstOffset);
-  SDOperand FudgeInReg;
-  if (DestTy == MVT::f32)
-    FudgeInReg = DAG.getLoad(MVT::f32, DAG.getEntryNode(), CPIdx, NULL, 0);
-  else if (DestTy.bitsGT(MVT::f32))
-    // FIXME: Avoid the extend by construction the right constantpool?
-    FudgeInReg = DAG.getExtLoad(ISD::EXTLOAD, DestTy, DAG.getEntryNode(),
-                                CPIdx, NULL, 0, MVT::f32);
-  else
-    assert(0 && "Unexpected conversion");
+  // Otherwise, use a libcall.
+  RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
+  if (SrcVT == MVT::i32) {
+    if (DstVT == MVT::f32)
+      LC = RTLIB::UINTTOFP_I32_F32;
+    else if (DstVT == MVT::f64)
+      LC = RTLIB::UINTTOFP_I32_F64;
+    else if (DstVT == MVT::f80)
+      LC = RTLIB::UINTTOFP_I32_F80;
+    else if (DstVT == MVT::ppcf128)
+      LC = RTLIB::UINTTOFP_I32_PPCF128;
+  } else if (SrcVT == MVT::i64) {
+    if (DstVT == MVT::f32)
+      LC = RTLIB::UINTTOFP_I64_F32;
+    else if (DstVT == MVT::f64)
+      LC = RTLIB::UINTTOFP_I64_F64;
+    else if (DstVT == MVT::f80)
+      LC = RTLIB::UINTTOFP_I64_F80;
+    else if (DstVT == MVT::ppcf128)
+      LC = RTLIB::UINTTOFP_I64_PPCF128;
+  } else if (SrcVT == MVT::i128) {
+    if (DstVT == MVT::f32)
+      LC = RTLIB::UINTTOFP_I128_F32;
+    else if (DstVT == MVT::f64)
+      LC = RTLIB::UINTTOFP_I128_F64;
+    else if (DstVT == MVT::f80)
+      LC = RTLIB::UINTTOFP_I128_F80;
+    else if (DstVT == MVT::ppcf128)
+      LC = RTLIB::UINTTOFP_I128_PPCF128;
+  }
+  assert(LC != RTLIB::UNKNOWN_LIBCALL &&
+         "Don't know how to expand this UINT_TO_FP!");
 
-  return DAG.getNode(ISD::FADD, DestTy, SignedConv, FudgeInReg);
+  return MakeLibCall(LC, DstVT, &Op, 1, true);
 }
 
 SDOperand DAGTypeLegalizer::ExpandIntOp_BR_CC(SDNode *N) {

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h?rev=53461&r1=53460&r2=53461&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h Fri Jul 11 12:00:14 2008
@@ -299,10 +299,10 @@
   SDOperand ExpandIntOp_EXTRACT_ELEMENT(SDNode *N);
   SDOperand ExpandIntOp_SELECT_CC(SDNode *N);
   SDOperand ExpandIntOp_SETCC(SDNode *N);
-  SDOperand ExpandIntOp_SINT_TO_FP(SDOperand Source, MVT DestTy);
+  SDOperand ExpandIntOp_SINT_TO_FP(SDNode *N);
   SDOperand ExpandIntOp_STORE(StoreSDNode *N, unsigned OpNo);
   SDOperand ExpandIntOp_TRUNCATE(SDNode *N);
-  SDOperand ExpandIntOp_UINT_TO_FP(SDOperand Source, MVT DestTy);
+  SDOperand ExpandIntOp_UINT_TO_FP(SDNode *N);
 
   void IntegerExpandSetCCOperands(SDOperand &NewLHS, SDOperand &NewRHS,
                                   ISD::CondCode &CCCode);

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp?rev=53461&r1=53460&r2=53461&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp Fri Jul 11 12:00:14 2008
@@ -135,8 +135,16 @@
   Names[RTLIB::SINTTOFP_I128_PPCF128] = "__floattitf";
   Names[RTLIB::UINTTOFP_I32_F32] = "__floatunsisf";
   Names[RTLIB::UINTTOFP_I32_F64] = "__floatunsidf";
+  Names[RTLIB::UINTTOFP_I32_F80] = "__floatunsixf";
+  Names[RTLIB::UINTTOFP_I32_PPCF128] = "__floatunsitf";
   Names[RTLIB::UINTTOFP_I64_F32] = "__floatundisf";
   Names[RTLIB::UINTTOFP_I64_F64] = "__floatundidf";
+  Names[RTLIB::UINTTOFP_I64_F80] = "__floatundixf";
+  Names[RTLIB::UINTTOFP_I64_PPCF128] = "__floatunditf";
+  Names[RTLIB::UINTTOFP_I128_F32] = "__floatuntisf";
+  Names[RTLIB::UINTTOFP_I128_F64] = "__floatuntidf";
+  Names[RTLIB::UINTTOFP_I128_F80] = "__floatuntixf";
+  Names[RTLIB::UINTTOFP_I128_PPCF128] = "__floatuntitf";
   Names[RTLIB::OEQ_F32] = "__eqsf2";
   Names[RTLIB::OEQ_F64] = "__eqdf2";
   Names[RTLIB::UNE_F32] = "__nesf2";





More information about the llvm-commits mailing list