diff options
author | Stefan Pintilie <stefanp@ca.ibm.com> | 2018-10-23 17:11:36 +0000 |
---|---|---|
committer | Stefan Pintilie <stefanp@ca.ibm.com> | 2018-10-23 17:11:36 +0000 |
commit | 927e8bf316b3c66df509c396e19f0e1de1b98e79 (patch) | |
tree | abc98ee2bfe57a5edabc418e712e01141f517dbd /llvm/lib | |
parent | 07076cfdf63dc0599cc5f1910b825404f53a8053 (diff) | |
download | bcm5719-llvm-927e8bf316b3c66df509c396e19f0e1de1b98e79.tar.gz bcm5719-llvm-927e8bf316b3c66df509c396e19f0e1de1b98e79.zip |
[Power9] Add __float128 support in the backend for bitcast to a i128
Add support to allow bit-casting from f128 to i128 and then
extracting 64 bits from the result.
Differential Revision: https://reviews.llvm.org/D49507
llvm-svn: 345053
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Target/PowerPC/PPCISelLowering.cpp | 58 | ||||
-rw-r--r-- | llvm/lib/Target/PowerPC/PPCISelLowering.h | 1 | ||||
-rw-r--r-- | llvm/lib/Target/PowerPC/PPCInstrVSX.td | 9 |
3 files changed, 68 insertions, 0 deletions
diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp index 1fd5018d05c..ca60f318278 100644 --- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp @@ -1070,6 +1070,8 @@ PPCTargetLowering::PPCTargetLowering(const PPCTargetMachine &TM, setTargetDAGCombine(ISD::ZERO_EXTEND); setTargetDAGCombine(ISD::ANY_EXTEND); + setTargetDAGCombine(ISD::TRUNCATE); + if (Subtarget.useCRBits()) { setTargetDAGCombine(ISD::TRUNCATE); setTargetDAGCombine(ISD::SETCC); @@ -9634,6 +9636,9 @@ void PPCTargetLowering::ReplaceNodeResults(SDNode *N, return; Results.push_back(LowerFP_TO_INT(SDValue(N, 0), DAG, dl)); return; + case ISD::BITCAST: + // Don't handle bitcast here. + return; } } @@ -12479,6 +12484,7 @@ SDValue PPCTargetLowering::PerformDAGCombine(SDNode *N, case ISD::ANY_EXTEND: return DAGCombineExtBoolTrunc(N, DCI); case ISD::TRUNCATE: + return combineTRUNCATE(N, DCI); case ISD::SETCC: case ISD::SELECT_CC: return DAGCombineTruncBoolExt(N, DCI); @@ -14253,6 +14259,58 @@ SDValue PPCTargetLowering::combineADD(SDNode *N, DAGCombinerInfo &DCI) const { return SDValue(); } +// Detect TRUNCATE operations on bitcasts of float128 values. +// What we are looking for here is the situtation where we extract a subset +// of bits from a 128 bit float. +// This can be of two forms: +// 1) BITCAST of f128 feeding TRUNCATE +// 2) BITCAST of f128 feeding SRL (a shift) feeding TRUNCATE +// The reason this is required is because we do not have a legal i128 type +// and so we want to prevent having to store the f128 and then reload part +// of it. +SDValue PPCTargetLowering::combineTRUNCATE(SDNode *N, + DAGCombinerInfo &DCI) const { + // If we are using CRBits then try that first. + if (Subtarget.useCRBits()) { + // Check if CRBits did anything and return that if it did. + if (SDValue CRTruncValue = DAGCombineTruncBoolExt(N, DCI)) + return CRTruncValue; + } + + SDLoc dl(N); + SDValue Op0 = N->getOperand(0); + + // Looking for a truncate of i128 to i64. + if (Op0.getValueType() != MVT::i128 || N->getValueType(0) != MVT::i64) + return SDValue(); + + int EltToExtract = DCI.DAG.getDataLayout().isBigEndian() ? 1 : 0; + + // SRL feeding TRUNCATE. + if (Op0.getOpcode() == ISD::SRL) { + ConstantSDNode *ConstNode = dyn_cast<ConstantSDNode>(Op0.getOperand(1)); + // The right shift has to be by 64 bits. + if (!ConstNode || ConstNode->getZExtValue() != 64) + return SDValue(); + + // Switch the element number to extract. + EltToExtract = EltToExtract ? 0 : 1; + // Update Op0 past the SRL. + Op0 = Op0.getOperand(0); + } + + // BITCAST feeding a TRUNCATE possibly via SRL. + if (Op0.getOpcode() == ISD::BITCAST && + Op0.getValueType() == MVT::i128 && + Op0.getOperand(0).getValueType() == MVT::f128) { + SDValue Bitcast = DCI.DAG.getBitcast(MVT::v2i64, Op0.getOperand(0)); + return DCI.DAG.getNode( + ISD::EXTRACT_VECTOR_ELT, dl, MVT::i64, Bitcast, + DCI.DAG.getTargetConstant(EltToExtract, dl, MVT::i32)); + } + return SDValue(); +} + bool PPCTargetLowering::mayBeEmittedAsTailCall(const CallInst *CI) const { // Only duplicate to increase tail-calls for the 64bit SysV ABIs. if (!Subtarget.isSVR4ABI() || !Subtarget.isPPC64()) diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.h b/llvm/lib/Target/PowerPC/PPCISelLowering.h index 9709d6bb09e..959831cb1c0 100644 --- a/llvm/lib/Target/PowerPC/PPCISelLowering.h +++ b/llvm/lib/Target/PowerPC/PPCISelLowering.h @@ -1093,6 +1093,7 @@ namespace llvm { SDValue combineSRA(SDNode *N, DAGCombinerInfo &DCI) const; SDValue combineSRL(SDNode *N, DAGCombinerInfo &DCI) const; SDValue combineADD(SDNode *N, DAGCombinerInfo &DCI) const; + SDValue combineTRUNCATE(SDNode *N, DAGCombinerInfo &DCI) const; /// ConvertSETCCToSubtract - looks at SETCC that compares ints. It replaces /// SETCC with integer subtraction when (1) there is a legal way of doing it diff --git a/llvm/lib/Target/PowerPC/PPCInstrVSX.td b/llvm/lib/Target/PowerPC/PPCInstrVSX.td index b1cfbc7b664..7a3141abc1b 100644 --- a/llvm/lib/Target/PowerPC/PPCInstrVSX.td +++ b/llvm/lib/Target/PowerPC/PPCInstrVSX.td @@ -1040,6 +1040,15 @@ def : Pat<(v2f64 (bitconvert v1i128:$A)), def : Pat<(v1i128 (bitconvert v2f64:$A)), (COPY_TO_REGCLASS $A, VRRC)>; +def : Pat<(v2i64 (bitconvert f128:$A)), + (COPY_TO_REGCLASS $A, VRRC)>; +def : Pat<(v4i32 (bitconvert f128:$A)), + (COPY_TO_REGCLASS $A, VRRC)>; +def : Pat<(v8i16 (bitconvert f128:$A)), + (COPY_TO_REGCLASS $A, VRRC)>; +def : Pat<(v16i8 (bitconvert f128:$A)), + (COPY_TO_REGCLASS $A, VRRC)>; + def : Pat<(v2f64 (PPCsvec2fp v4i32:$C, 0)), (v2f64 (XVCVSXWDP (v2i64 (XXMRGHW $C, $C))))>; def : Pat<(v2f64 (PPCsvec2fp v4i32:$C, 1)), |