summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorCraig Topper <craig.topper@intel.com>2018-03-20 18:49:28 +0000
committerCraig Topper <craig.topper@intel.com>2018-03-20 18:49:28 +0000
commitc2dbd677bd790ff750acff632dfc81c2d3895f8c (patch)
tree9f41e24e24eb435f5fa037a4d4738cc27a80bd38 /llvm/lib
parenteb0c510ecde667cd911682cc1e855f73f341d134 (diff)
downloadbcm5719-llvm-c2dbd677bd790ff750acff632dfc81c2d3895f8c.tar.gz
bcm5719-llvm-c2dbd677bd790ff750acff632dfc81c2d3895f8c.zip
[PowerPC][LegalizeFloatTypes] Move the PPC hacks for (i32 fp_to_sint/fp_to_uint (ppcf128 X)) out of LegalizeFloatTypes and into PPC specific code
I'm not entirely sure these hacks are still needed. If you remove the hacks completely, the name of the library call that gets generated doesn't match the grep the test previously had. So the test wasn't really checking anything. If the hack is still needed it belongs in PPC specific code. I believe the FP_TO_SINT code here is the only place in the tree where a FP_ROUND_INREG node is created today. And I don't think its even being used correctly because the legalization returned a BUILD_PAIR with the same value twice. That doesn't seem right to me. By moving the code entirely to PPC we can avoid creating the FP_ROUND_INREG at all. I replaced the grep in the existing test with full checks generated by hacking update_llc_test_check.py to support ppc32 just long enough to generate it. Differential Revision: https://reviews.llvm.org/D44061 llvm-svn: 328017
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp37
-rw-r--r--llvm/lib/Target/PowerPC/PPCISelLowering.cpp66
2 files changed, 44 insertions, 59 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp
index e28a3aa47ca..3f17d4d605e 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp
@@ -1658,18 +1658,6 @@ SDValue DAGTypeLegalizer::ExpandFloatOp_FP_TO_SINT(SDNode *N) {
EVT RVT = N->getValueType(0);
SDLoc dl(N);
- // Expand ppcf128 to i32 by hand for the benefit of llvm-gcc bootstrap on
- // PPC (the libcall is not available). FIXME: Do this in a less hacky way.
- if (RVT == MVT::i32) {
- assert(N->getOperand(0).getValueType() == MVT::ppcf128 &&
- "Logic only correct for ppcf128!");
- SDValue Res = DAG.getNode(ISD::FP_ROUND_INREG, dl, MVT::ppcf128,
- N->getOperand(0), DAG.getValueType(MVT::f64));
- Res = DAG.getNode(ISD::FP_ROUND, dl, MVT::f64, Res,
- DAG.getIntPtrConstant(1, dl));
- return DAG.getNode(ISD::FP_TO_SINT, dl, MVT::i32, Res);
- }
-
RTLIB::Libcall LC = RTLIB::getFPTOSINT(N->getOperand(0).getValueType(), RVT);
assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported FP_TO_SINT!");
return TLI.makeLibCall(DAG, LC, RVT, N->getOperand(0), false, dl).first;
@@ -1679,31 +1667,6 @@ SDValue DAGTypeLegalizer::ExpandFloatOp_FP_TO_UINT(SDNode *N) {
EVT RVT = N->getValueType(0);
SDLoc dl(N);
- // Expand ppcf128 to i32 by hand for the benefit of llvm-gcc bootstrap on
- // PPC (the libcall is not available). FIXME: Do this in a less hacky way.
- if (RVT == MVT::i32) {
- assert(N->getOperand(0).getValueType() == MVT::ppcf128 &&
- "Logic only correct for ppcf128!");
- const uint64_t TwoE31[] = {0x41e0000000000000LL, 0};
- APFloat APF = APFloat(APFloat::PPCDoubleDouble(), APInt(128, TwoE31));
- SDValue Tmp = DAG.getConstantFP(APF, dl, MVT::ppcf128);
- // X>=2^31 ? (int)(X-2^31)+0x80000000 : (int)X
- // FIXME: generated code sucks.
- // TODO: Are there fast-math-flags to propagate to this FSUB?
- return DAG.getSelectCC(dl, N->getOperand(0), Tmp,
- DAG.getNode(ISD::ADD, dl, MVT::i32,
- DAG.getNode(ISD::FP_TO_SINT, dl, MVT::i32,
- DAG.getNode(ISD::FSUB, dl,
- MVT::ppcf128,
- N->getOperand(0),
- Tmp)),
- DAG.getConstant(0x80000000, dl,
- MVT::i32)),
- DAG.getNode(ISD::FP_TO_SINT, dl,
- MVT::i32, N->getOperand(0)),
- ISD::SETGE);
- }
-
RTLIB::Libcall LC = RTLIB::getFPTOUINT(N->getOperand(0).getValueType(), RVT);
assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported FP_TO_UINT!");
return TLI.makeLibCall(DAG, LC, N->getValueType(0), N->getOperand(0),
diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
index 82f0334daa1..bf6e28c5020 100644
--- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
+++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
@@ -201,9 +201,10 @@ PPCTargetLowering::PPCTargetLowering(const PPCTargetMachine &TM,
addRegisterClass(MVT::i1, &PPC::CRBITRCRegClass);
}
- // This is used in the ppcf128->int sequence. Note it has different semantics
- // from FP_ROUND: that rounds to nearest, this rounds to zero.
- setOperationAction(ISD::FP_ROUND_INREG, MVT::ppcf128, Custom);
+ // Expand ppcf128 to i32 by hand for the benefit of llvm-gcc bootstrap on
+ // PPC (the libcall is not available).
+ setOperationAction(ISD::FP_TO_SINT, MVT::ppcf128, Custom);
+ setOperationAction(ISD::FP_TO_UINT, MVT::ppcf128, Custom);
// We do not currently implement these libm ops for PowerPC.
setOperationAction(ISD::FFLOOR, MVT::ppcf128, Expand);
@@ -6915,6 +6916,46 @@ SDValue PPCTargetLowering::LowerFP_TO_INTDirectMove(SDValue Op,
SDValue PPCTargetLowering::LowerFP_TO_INT(SDValue Op, SelectionDAG &DAG,
const SDLoc &dl) const {
+ // Expand ppcf128 to i32 by hand for the benefit of llvm-gcc bootstrap on
+ // PPC (the libcall is not available).
+ if (Op.getOperand(0).getValueType() == MVT::ppcf128) {
+ if (Op.getValueType() == MVT::i32) {
+ if (Op.getOpcode() == ISD::FP_TO_SINT) {
+ SDValue Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, dl,
+ MVT::f64, Op.getOperand(0),
+ DAG.getIntPtrConstant(0, dl));
+ SDValue Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, dl,
+ MVT::f64, Op.getOperand(0),
+ DAG.getIntPtrConstant(1, dl));
+
+ // Add the two halves of the long double in round-to-zero mode.
+ SDValue Res = DAG.getNode(PPCISD::FADDRTZ, dl, MVT::f64, Lo, Hi);
+
+ // Now use a smaller FP_TO_SINT.
+ return DAG.getNode(ISD::FP_TO_SINT, dl, MVT::i32, Res);
+ }
+ if (Op.getOpcode() == ISD::FP_TO_UINT) {
+ const uint64_t TwoE31[] = {0x41e0000000000000LL, 0};
+ APFloat APF = APFloat(APFloat::PPCDoubleDouble(), APInt(128, TwoE31));
+ SDValue Tmp = DAG.getConstantFP(APF, dl, MVT::ppcf128);
+ // X>=2^31 ? (int)(X-2^31)+0x80000000 : (int)X
+ // FIXME: generated code sucks.
+ // TODO: Are there fast-math-flags to propagate to this FSUB?
+ SDValue True = DAG.getNode(ISD::FSUB, dl, MVT::ppcf128,
+ Op.getOperand(0), Tmp);
+ True = DAG.getNode(ISD::FP_TO_SINT, dl, MVT::i32, True);
+ True = DAG.getNode(ISD::ADD, dl, MVT::i32, True,
+ DAG.getConstant(0x80000000, dl, MVT::i32));
+ SDValue False = DAG.getNode(ISD::FP_TO_SINT, dl, MVT::i32,
+ Op.getOperand(0));
+ return DAG.getSelectCC(dl, Op.getOperand(0), Tmp, True, False,
+ ISD::SETGE);
+ }
+ }
+
+ return SDValue();
+ }
+
if (Subtarget.hasDirectMove() && Subtarget.isPPC64())
return LowerFP_TO_INTDirectMove(Op, DAG, dl);
@@ -9444,25 +9485,6 @@ void PPCTargetLowering::ReplaceNodeResults(SDNode *N,
}
return;
}
- case ISD::FP_ROUND_INREG: {
- assert(N->getValueType(0) == MVT::ppcf128);
- assert(N->getOperand(0).getValueType() == MVT::ppcf128);
- SDValue Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, dl,
- MVT::f64, N->getOperand(0),
- DAG.getIntPtrConstant(0, dl));
- SDValue Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, dl,
- MVT::f64, N->getOperand(0),
- DAG.getIntPtrConstant(1, dl));
-
- // Add the two halves of the long double in round-to-zero mode.
- SDValue FPreg = DAG.getNode(PPCISD::FADDRTZ, dl, MVT::f64, Lo, Hi);
-
- // We know the low half is about to be thrown away, so just use something
- // convenient.
- Results.push_back(DAG.getNode(ISD::BUILD_PAIR, dl, MVT::ppcf128,
- FPreg, FPreg));
- return;
- }
case ISD::FP_TO_SINT:
case ISD::FP_TO_UINT:
// LowerFP_TO_INT() can only handle f32 and f64.
OpenPOWER on IntegriCloud