[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