diff options
author | Lei Huang <lei@ca.ibm.com> | 2018-05-08 17:36:40 +0000 |
---|---|---|
committer | Lei Huang <lei@ca.ibm.com> | 2018-05-08 17:36:40 +0000 |
commit | c29229a6441b8818578247053af1686c72d46732 (patch) | |
tree | 09fea204011962ea8124d9d54aed41928f5ff201 /llvm/lib/Target/PowerPC/PPCISelLowering.cpp | |
parent | 2550ca1e93a6caae1a46f160087f06dea669d7d9 (diff) | |
download | bcm5719-llvm-c29229a6441b8818578247053af1686c72d46732.tar.gz bcm5719-llvm-c29229a6441b8818578247053af1686c72d46732.zip |
[PowerPC] Unify handling for conversion of FP_TO_INT feeding a store
Existing DAG combine only handles conversions for FP_TO_SINT:
"{f32, f64} x { i32, i16 }"
This patch simplifies the code to handle:
"{ FP_TO_SINT, FP_TO_UINT } x { f64, f32 } x { i64, i32, i16, i8 }"
Differential Revision: https://reviews.llvm.org/D46102
llvm-svn: 331778
Diffstat (limited to 'llvm/lib/Target/PowerPC/PPCISelLowering.cpp')
-rw-r--r-- | llvm/lib/Target/PowerPC/PPCISelLowering.cpp | 129 |
1 files changed, 77 insertions, 52 deletions
diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp index cfe77f4e3e3..bbf0caea10c 100644 --- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp @@ -1158,6 +1158,10 @@ const char *PPCTargetLowering::getTargetNodeName(unsigned Opcode) const { case PPCISD::FCTIWZ: return "PPCISD::FCTIWZ"; case PPCISD::FCTIDUZ: return "PPCISD::FCTIDUZ"; case PPCISD::FCTIWUZ: return "PPCISD::FCTIWUZ"; + case PPCISD::FP_TO_UINT_IN_VSR: + return "PPCISD::FP_TO_UINT_IN_VSR,"; + case PPCISD::FP_TO_SINT_IN_VSR: + return "PPCISD::FP_TO_SINT_IN_VSR"; case PPCISD::FRE: return "PPCISD::FRE"; case PPCISD::FRSQRTE: return "PPCISD::FRSQRTE"; case PPCISD::STFIWX: return "PPCISD::STFIWX"; @@ -1211,6 +1215,8 @@ const char *PPCTargetLowering::getTargetNodeName(unsigned Opcode) const { case PPCISD::SExtVElems: return "PPCISD::SExtVElems"; case PPCISD::LXVD2X: return "PPCISD::LXVD2X"; case PPCISD::STXVD2X: return "PPCISD::STXVD2X"; + case PPCISD::ST_VSR_SCAL_INT: + return "PPCISD::ST_VSR_SCAL_INT"; case PPCISD::COND_BRANCH: return "PPCISD::COND_BRANCH"; case PPCISD::BDNZ: return "PPCISD::BDNZ"; case PPCISD::BDZ: return "PPCISD::BDZ"; @@ -12224,6 +12230,64 @@ SDValue PPCTargetLowering::expandVSXStoreForLE(SDNode *N, return Store; } +// Handle DAG combine for STORE (FP_TO_INT F). +SDValue PPCTargetLowering::combineStoreFPToInt(SDNode *N, + DAGCombinerInfo &DCI) const { + + SelectionDAG &DAG = DCI.DAG; + SDLoc dl(N); + unsigned Opcode = N->getOperand(1).getOpcode(); + + assert((Opcode == ISD::FP_TO_SINT || Opcode == ISD::FP_TO_UINT) + && "Not a FP_TO_INT Instruction!"); + + SDValue Val = N->getOperand(1).getOperand(0); + EVT Op1VT = N->getOperand(1).getValueType(); + EVT ResVT = Val.getValueType(); + + // Floating point types smaller than 32 bits are not legal on Power. + if (ResVT.getScalarSizeInBits() < 32) + return SDValue(); + + // Only perform combine for conversion to i64/i32 or power9 i16/i8. + bool ValidTypeForStoreFltAsInt = + (Op1VT == MVT::i32 || Op1VT == MVT::i64 || + (Subtarget.hasP9Vector() && (Op1VT == MVT::i16 || Op1VT == MVT::i8))); + + if (ResVT == MVT::ppcf128 || !Subtarget.hasP8Altivec() || + cast<StoreSDNode>(N)->isTruncatingStore() || !ValidTypeForStoreFltAsInt) + return SDValue(); + + // Extend f32 values to f64 + if (ResVT.getScalarSizeInBits() == 32) { + Val = DAG.getNode(ISD::FP_EXTEND, dl, MVT::f64, Val); + DCI.AddToWorklist(Val.getNode()); + } + + // Set signed or unsigned conversion opcode. + unsigned ConvOpcode = (Opcode == ISD::FP_TO_SINT) ? + PPCISD::FP_TO_SINT_IN_VSR : + PPCISD::FP_TO_UINT_IN_VSR; + + Val = DAG.getNode(ConvOpcode, + dl, ResVT == MVT::f128 ? MVT::f128 : MVT::f64, Val); + DCI.AddToWorklist(Val.getNode()); + + // Set number of bytes being converted. + unsigned ByteSize = Op1VT.getScalarSizeInBits() / 8; + SDValue Ops[] = { N->getOperand(0), Val, N->getOperand(2), + DAG.getIntPtrConstant(ByteSize, dl, false), + DAG.getValueType(Op1VT) }; + + Val = DAG.getMemIntrinsicNode(PPCISD::ST_VSR_SCAL_INT, dl, + DAG.getVTList(MVT::Other), Ops, + cast<StoreSDNode>(N)->getMemoryVT(), + cast<StoreSDNode>(N)->getMemOperand()); + + DCI.AddToWorklist(Val.getNode()); + return Val; +} + SDValue PPCTargetLowering::PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const { SelectionDAG &DAG = DCI.DAG; @@ -12263,60 +12327,22 @@ SDValue PPCTargetLowering::PerformDAGCombine(SDNode *N, case ISD::UINT_TO_FP: return combineFPToIntToFP(N, DCI); case ISD::STORE: { + EVT Op1VT = N->getOperand(1).getValueType(); - bool ValidTypeForStoreFltAsInt = (Op1VT == MVT::i32) || - (Subtarget.hasP9Vector() && (Op1VT == MVT::i8 || Op1VT == MVT::i16)); - - // Turn STORE (FP_TO_SINT F) -> STFIWX(FCTIWZ(F)). - if (Subtarget.hasSTFIWX() && !cast<StoreSDNode>(N)->isTruncatingStore() && - N->getOperand(1).getOpcode() == ISD::FP_TO_SINT && - ValidTypeForStoreFltAsInt && - N->getOperand(1).getOperand(0).getValueType() != MVT::ppcf128) { - SDValue Val = N->getOperand(1).getOperand(0); - if (Val.getValueType() == MVT::f32) { - Val = DAG.getNode(ISD::FP_EXTEND, dl, MVT::f64, Val); - DCI.AddToWorklist(Val.getNode()); - } - Val = DAG.getNode(PPCISD::FCTIWZ, dl, MVT::f64, Val); - DCI.AddToWorklist(Val.getNode()); - - if (Op1VT == MVT::i32) { - SDValue Ops[] = { - N->getOperand(0), Val, N->getOperand(2), - DAG.getValueType(N->getOperand(1).getValueType()) - }; - - Val = DAG.getMemIntrinsicNode(PPCISD::STFIWX, dl, - DAG.getVTList(MVT::Other), Ops, - cast<StoreSDNode>(N)->getMemoryVT(), - cast<StoreSDNode>(N)->getMemOperand()); - } else { - unsigned WidthInBytes = - N->getOperand(1).getValueType() == MVT::i8 ? 1 : 2; - SDValue WidthConst = DAG.getIntPtrConstant(WidthInBytes, dl, false); - - SDValue Ops[] = { - N->getOperand(0), Val, N->getOperand(2), WidthConst, - DAG.getValueType(N->getOperand(1).getValueType()) - }; - Val = DAG.getMemIntrinsicNode(PPCISD::STXSIX, dl, - DAG.getVTList(MVT::Other), Ops, - cast<StoreSDNode>(N)->getMemoryVT(), - cast<StoreSDNode>(N)->getMemOperand()); - } + unsigned Opcode = N->getOperand(1).getOpcode(); - DCI.AddToWorklist(Val.getNode()); - return Val; + if (Opcode == ISD::FP_TO_SINT || Opcode == ISD::FP_TO_UINT) { + SDValue Val= combineStoreFPToInt(N, DCI); + if (Val) + return Val; } // Turn STORE (BSWAP) -> sthbrx/stwbrx. - if (cast<StoreSDNode>(N)->isUnindexed() && - N->getOperand(1).getOpcode() == ISD::BSWAP && + if (cast<StoreSDNode>(N)->isUnindexed() && Opcode == ISD::BSWAP && N->getOperand(1).getNode()->hasOneUse() && - (N->getOperand(1).getValueType() == MVT::i32 || - N->getOperand(1).getValueType() == MVT::i16 || - (Subtarget.hasLDBRX() && Subtarget.isPPC64() && - N->getOperand(1).getValueType() == MVT::i64))) { + (Op1VT == MVT::i32 || Op1VT == MVT::i16 || + (Subtarget.hasLDBRX() && Subtarget.isPPC64() && Op1VT == MVT::i64))) { + // STBRX can only handle simple types. EVT mVT = cast<StoreSDNode>(N)->getMemoryVT(); if (mVT.isExtended()) @@ -12349,9 +12375,8 @@ SDValue PPCTargetLowering::PerformDAGCombine(SDNode *N, // STORE Constant:i32<0> -> STORE<trunc to i32> Constant:i64<0> // So it can increase the chance of CSE constant construction. - EVT VT = N->getOperand(1).getValueType(); if (Subtarget.isPPC64() && !DCI.isBeforeLegalize() && - isa<ConstantSDNode>(N->getOperand(1)) && VT == MVT::i32) { + isa<ConstantSDNode>(N->getOperand(1)) && Op1VT == MVT::i32) { // Need to sign-extended to 64-bits to handle negative values. EVT MemVT = cast<StoreSDNode>(N)->getMemoryVT(); uint64_t Val64 = SignExtend64(N->getConstantOperandVal(1), @@ -12369,8 +12394,8 @@ SDValue PPCTargetLowering::PerformDAGCombine(SDNode *N, // For little endian, VSX stores require generating xxswapd/lxvd2x. // Not needed on ISA 3.0 based CPUs since we have a non-permuting store. - if (VT.isSimple()) { - MVT StoreVT = VT.getSimpleVT(); + if (Op1VT.isSimple()) { + MVT StoreVT = Op1VT.getSimpleVT(); if (Subtarget.needsSwapsForVSXMemOps() && (StoreVT == MVT::v2f64 || StoreVT == MVT::v2i64 || StoreVT == MVT::v4f32 || StoreVT == MVT::v4i32)) |