diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2019-01-19 10:01:25 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2019-01-19 10:01:25 +0000 |
commit | d8e91e46262bc44006913e6796843909f1ac7bcd (patch) | |
tree | 7d0c143d9b38190e0fa0180805389da22cd834c5 /lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp | |
parent | b7eb8e35e481a74962664b63dfb09483b200209a (diff) |
Notes
Diffstat (limited to 'lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp')
-rw-r--r-- | lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp | 221 |
1 files changed, 150 insertions, 71 deletions
diff --git a/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp b/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp index 3a98a7a904cb..4923a529c21b 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp @@ -86,9 +86,10 @@ class VectorLegalizer { /// operations to legalize them. SDValue Expand(SDValue Op); - /// Implements expansion for FNEG; falls back to UnrollVectorOp if - /// FSUB isn't legal. - /// + /// Implements expansion for FP_TO_UINT; falls back to UnrollVectorOp if + /// FP_TO_SINT isn't legal. + SDValue ExpandFP_TO_UINT(SDValue Op); + /// Implements expansion for UINT_TO_FLOAT; falls back to UnrollVectorOp if /// SINT_TO_FLOAT and SHR on vectors isn't legal. SDValue ExpandUINT_TO_FLOAT(SDValue Op); @@ -116,6 +117,12 @@ class VectorLegalizer { /// the remaining lanes, finally bitcasting to the proper type. SDValue ExpandZERO_EXTEND_VECTOR_INREG(SDValue Op); + /// Implement expand-based legalization of ABS vector operations. + /// If following expanding is legal/custom then do it: + /// (ABS x) --> (XOR (ADD x, (SRA x, sizeof(x)-1)), (SRA x, sizeof(x)-1)) + /// else unroll the operation. + SDValue ExpandABS(SDValue Op); + /// Expand bswap of vectors into a shuffle if legal. SDValue ExpandBSWAP(SDValue Op); @@ -128,8 +135,13 @@ class VectorLegalizer { SDValue ExpandFNEG(SDValue Op); SDValue ExpandFSUB(SDValue Op); SDValue ExpandBITREVERSE(SDValue Op); + SDValue ExpandCTPOP(SDValue Op); SDValue ExpandCTLZ(SDValue Op); - SDValue ExpandCTTZ_ZERO_UNDEF(SDValue Op); + SDValue ExpandCTTZ(SDValue Op); + SDValue ExpandFunnelShift(SDValue Op); + SDValue ExpandROT(SDValue Op); + SDValue ExpandFMINNUM_FMAXNUM(SDValue Op); + SDValue ExpandAddSubSat(SDValue Op); SDValue ExpandStrictFPOp(SDValue Op); /// Implements vector promotion. @@ -226,7 +238,6 @@ SDValue VectorLegalizer::LegalizeOp(SDValue Op) { SDValue Result = SDValue(DAG.UpdateNodeOperands(Op.getNode(), Ops), Op.getResNo()); - bool HasVectorValue = false; if (Op.getOpcode() == ISD::LOAD) { LoadSDNode *LD = cast<LoadSDNode>(Op.getNode()); ISD::LoadExtType ExtType = LD->getExtensionType(); @@ -240,16 +251,12 @@ SDValue VectorLegalizer::LegalizeOp(SDValue Op) { return TranslateLegalizeResults(Op, Result); case TargetLowering::Custom: if (SDValue Lowered = TLI.LowerOperation(Result, DAG)) { - if (Lowered == Result) - return TranslateLegalizeResults(Op, Lowered); - Changed = true; - if (Lowered->getNumValues() != Op->getNumValues()) { - // This expanded to something other than the load. Assume the - // lowering code took care of any chain values, and just handle the - // returned value. - assert(Result.getValue(1).use_empty() && - "There are still live users of the old chain!"); - return LegalizeOp(Lowered); + assert(Lowered->getNumValues() == Op->getNumValues() && + "Unexpected number of results"); + if (Lowered != Result) { + // Make sure the new code is also legal. + Lowered = LegalizeOp(Lowered); + Changed = true; } return TranslateLegalizeResults(Op, Lowered); } @@ -272,7 +279,11 @@ SDValue VectorLegalizer::LegalizeOp(SDValue Op) { return TranslateLegalizeResults(Op, Result); case TargetLowering::Custom: { SDValue Lowered = TLI.LowerOperation(Result, DAG); - Changed = Lowered != Result; + if (Lowered != Result) { + // Make sure the new code is also legal. + Lowered = LegalizeOp(Lowered); + Changed = true; + } return TranslateLegalizeResults(Op, Lowered); } case TargetLowering::Expand: @@ -280,9 +291,9 @@ SDValue VectorLegalizer::LegalizeOp(SDValue Op) { return LegalizeOp(ExpandStore(Op)); } } - } else if (Op.getOpcode() == ISD::MSCATTER || Op.getOpcode() == ISD::MSTORE) - HasVectorValue = true; + } + bool HasVectorValue = false; for (SDNode::value_iterator J = Node->value_begin(), E = Node->value_end(); J != E; ++J) @@ -298,6 +309,7 @@ SDValue VectorLegalizer::LegalizeOp(SDValue Op) { case ISD::STRICT_FSUB: case ISD::STRICT_FMUL: case ISD::STRICT_FDIV: + case ISD::STRICT_FREM: case ISD::STRICT_FSQRT: case ISD::STRICT_FMA: case ISD::STRICT_FPOW: @@ -311,6 +323,12 @@ SDValue VectorLegalizer::LegalizeOp(SDValue Op) { case ISD::STRICT_FLOG2: case ISD::STRICT_FRINT: case ISD::STRICT_FNEARBYINT: + case ISD::STRICT_FMAXNUM: + case ISD::STRICT_FMINNUM: + case ISD::STRICT_FCEIL: + case ISD::STRICT_FFLOOR: + case ISD::STRICT_FROUND: + case ISD::STRICT_FTRUNC: // These pseudo-ops get legalized as if they were their non-strict // equivalent. For instance, if ISD::FSQRT is legal then ISD::STRICT_FSQRT // is also legal, but if ISD::FSQRT requires expansion then so does @@ -321,6 +339,8 @@ SDValue VectorLegalizer::LegalizeOp(SDValue Op) { case ISD::ADD: case ISD::SUB: case ISD::MUL: + case ISD::MULHS: + case ISD::MULHU: case ISD::SDIV: case ISD::UDIV: case ISD::SREM: @@ -338,8 +358,11 @@ SDValue VectorLegalizer::LegalizeOp(SDValue Op) { case ISD::SHL: case ISD::SRA: case ISD::SRL: + case ISD::FSHL: + case ISD::FSHR: case ISD::ROTL: case ISD::ROTR: + case ISD::ABS: case ISD::BSWAP: case ISD::BITREVERSE: case ISD::CTLZ: @@ -361,8 +384,10 @@ SDValue VectorLegalizer::LegalizeOp(SDValue Op) { case ISD::FABS: case ISD::FMINNUM: case ISD::FMAXNUM: - case ISD::FMINNAN: - case ISD::FMAXNAN: + case ISD::FMINNUM_IEEE: + case ISD::FMAXNUM_IEEE: + case ISD::FMINIMUM: + case ISD::FMAXIMUM: case ISD::FCOPYSIGN: case ISD::FSQRT: case ISD::FSIN: @@ -394,8 +419,18 @@ SDValue VectorLegalizer::LegalizeOp(SDValue Op) { case ISD::SMUL_LOHI: case ISD::UMUL_LOHI: case ISD::FCANONICALIZE: + case ISD::SADDSAT: + case ISD::UADDSAT: + case ISD::SSUBSAT: + case ISD::USUBSAT: Action = TLI.getOperationAction(Node->getOpcode(), Node->getValueType(0)); break; + case ISD::SMULFIX: { + unsigned Scale = Node->getConstantOperandVal(2); + Action = TLI.getFixedPointOperationAction(Node->getOpcode(), + Node->getValueType(0), Scale); + break; + } case ISD::FP_ROUND_INREG: Action = TLI.getOperationAction(Node->getOpcode(), cast<VTSDNode>(Node->getOperand(1))->getVT()); @@ -405,14 +440,6 @@ SDValue VectorLegalizer::LegalizeOp(SDValue Op) { Action = TLI.getOperationAction(Node->getOpcode(), Node->getOperand(0).getValueType()); break; - case ISD::MSCATTER: - Action = TLI.getOperationAction(Node->getOpcode(), - cast<MaskedScatterSDNode>(Node)->getValue().getValueType()); - break; - case ISD::MSTORE: - Action = TLI.getOperationAction(Node->getOpcode(), - cast<MaskedStoreSDNode>(Node)->getValue().getValueType()); - break; } LLVM_DEBUG(dbgs() << "\nLegalizing vector op: "; Node->dump(&DAG)); @@ -720,6 +747,8 @@ SDValue VectorLegalizer::Expand(SDValue Op) { return ExpandVSELECT(Op); case ISD::SELECT: return ExpandSELECT(Op); + case ISD::FP_TO_UINT: + return ExpandFP_TO_UINT(Op); case ISD::UINT_TO_FP: return ExpandUINT_TO_FLOAT(Op); case ISD::FNEG: @@ -728,17 +757,37 @@ SDValue VectorLegalizer::Expand(SDValue Op) { return ExpandFSUB(Op); case ISD::SETCC: return UnrollVSETCC(Op); + case ISD::ABS: + return ExpandABS(Op); case ISD::BITREVERSE: return ExpandBITREVERSE(Op); + case ISD::CTPOP: + return ExpandCTPOP(Op); case ISD::CTLZ: case ISD::CTLZ_ZERO_UNDEF: return ExpandCTLZ(Op); + case ISD::CTTZ: case ISD::CTTZ_ZERO_UNDEF: - return ExpandCTTZ_ZERO_UNDEF(Op); + return ExpandCTTZ(Op); + case ISD::FSHL: + case ISD::FSHR: + return ExpandFunnelShift(Op); + case ISD::ROTL: + case ISD::ROTR: + return ExpandROT(Op); + case ISD::FMINNUM: + case ISD::FMAXNUM: + return ExpandFMINNUM_FMAXNUM(Op); + case ISD::USUBSAT: + case ISD::SSUBSAT: + case ISD::UADDSAT: + case ISD::SADDSAT: + return ExpandAddSubSat(Op); case ISD::STRICT_FADD: case ISD::STRICT_FSUB: case ISD::STRICT_FMUL: case ISD::STRICT_FDIV: + case ISD::STRICT_FREM: case ISD::STRICT_FSQRT: case ISD::STRICT_FMA: case ISD::STRICT_FPOW: @@ -752,6 +801,12 @@ SDValue VectorLegalizer::Expand(SDValue Op) { case ISD::STRICT_FLOG2: case ISD::STRICT_FRINT: case ISD::STRICT_FNEARBYINT: + case ISD::STRICT_FMAXNUM: + case ISD::STRICT_FMINNUM: + case ISD::STRICT_FCEIL: + case ISD::STRICT_FFLOOR: + case ISD::STRICT_FROUND: + case ISD::STRICT_FTRUNC: return ExpandStrictFPOp(Op); default: return DAG.UnrollVectorOp(Op.getNode()); @@ -866,7 +921,7 @@ SDValue VectorLegalizer::ExpandSIGN_EXTEND_VECTOR_INREG(SDValue Op) { // First build an any-extend node which can be legalized above when we // recurse through it. - Op = DAG.getAnyExtendVectorInReg(Src, DL, VT); + Op = DAG.getNode(ISD::ANY_EXTEND_VECTOR_INREG, DL, VT, Src); // Now we need sign extend. Do this by shifting the elements. Even if these // aren't legal operations, they have a better chance of being legalized @@ -1024,10 +1079,35 @@ SDValue VectorLegalizer::ExpandVSELECT(SDValue Op) { return DAG.getNode(ISD::BITCAST, DL, Op.getValueType(), Val); } +SDValue VectorLegalizer::ExpandABS(SDValue Op) { + // Attempt to expand using TargetLowering. + SDValue Result; + if (TLI.expandABS(Op.getNode(), Result, DAG)) + return Result; + + // Otherwise go ahead and unroll. + return DAG.UnrollVectorOp(Op.getNode()); +} + +SDValue VectorLegalizer::ExpandFP_TO_UINT(SDValue Op) { + // Attempt to expand using TargetLowering. + SDValue Result; + if (TLI.expandFP_TO_UINT(Op.getNode(), Result, DAG)) + return Result; + + // Otherwise go ahead and unroll. + return DAG.UnrollVectorOp(Op.getNode()); +} + SDValue VectorLegalizer::ExpandUINT_TO_FLOAT(SDValue Op) { EVT VT = Op.getOperand(0).getValueType(); SDLoc DL(Op); + // Attempt to expand using TargetLowering. + SDValue Result; + if (TLI.expandUINT_TO_FP(Op.getNode(), Result, DAG)) + return Result; + // Make sure that the SINT_TO_FP and SRL instructions are available. if (TLI.getOperationAction(ISD::SINT_TO_FP, VT) == TargetLowering::Expand || TLI.getOperationAction(ISD::SRL, VT) == TargetLowering::Expand) @@ -1086,56 +1166,55 @@ SDValue VectorLegalizer::ExpandFSUB(SDValue Op) { return DAG.UnrollVectorOp(Op.getNode()); } +SDValue VectorLegalizer::ExpandCTPOP(SDValue Op) { + SDValue Result; + if (TLI.expandCTPOP(Op.getNode(), Result, DAG)) + return Result; + + return DAG.UnrollVectorOp(Op.getNode()); +} + SDValue VectorLegalizer::ExpandCTLZ(SDValue Op) { - EVT VT = Op.getValueType(); - unsigned NumBitsPerElt = VT.getScalarSizeInBits(); + SDValue Result; + if (TLI.expandCTLZ(Op.getNode(), Result, DAG)) + return Result; - // If the non-ZERO_UNDEF version is supported we can use that instead. - if (Op.getOpcode() == ISD::CTLZ_ZERO_UNDEF && - TLI.isOperationLegalOrCustom(ISD::CTLZ, VT)) { - SDLoc DL(Op); - return DAG.getNode(ISD::CTLZ, DL, Op.getValueType(), Op.getOperand(0)); - } + return DAG.UnrollVectorOp(Op.getNode()); +} - // If CTPOP is available we can lower with a CTPOP based method: - // u16 ctlz(u16 x) { - // x |= (x >> 1); - // x |= (x >> 2); - // x |= (x >> 4); - // x |= (x >> 8); - // return ctpop(~x); - // } - // Ref: "Hacker's Delight" by Henry Warren - if (isPowerOf2_32(NumBitsPerElt) && - TLI.isOperationLegalOrCustom(ISD::CTPOP, VT) && - TLI.isOperationLegalOrCustom(ISD::SRL, VT) && - TLI.isOperationLegalOrCustomOrPromote(ISD::OR, VT) && - TLI.isOperationLegalOrCustomOrPromote(ISD::XOR, VT)) { - SDLoc DL(Op); - SDValue Res = Op.getOperand(0); - EVT ShiftTy = TLI.getShiftAmountTy(VT, DAG.getDataLayout()); +SDValue VectorLegalizer::ExpandCTTZ(SDValue Op) { + SDValue Result; + if (TLI.expandCTTZ(Op.getNode(), Result, DAG)) + return Result; - for (unsigned i = 1; i != NumBitsPerElt; i *= 2) - Res = DAG.getNode( - ISD::OR, DL, VT, Res, - DAG.getNode(ISD::SRL, DL, VT, Res, DAG.getConstant(i, DL, ShiftTy))); + return DAG.UnrollVectorOp(Op.getNode()); +} - Res = DAG.getNOT(DL, Res, VT); - return DAG.getNode(ISD::CTPOP, DL, VT, Res); - } +SDValue VectorLegalizer::ExpandFunnelShift(SDValue Op) { + SDValue Result; + if (TLI.expandFunnelShift(Op.getNode(), Result, DAG)) + return Result; - // Otherwise go ahead and unroll. return DAG.UnrollVectorOp(Op.getNode()); } -SDValue VectorLegalizer::ExpandCTTZ_ZERO_UNDEF(SDValue Op) { - // If the non-ZERO_UNDEF version is supported we can use that instead. - if (TLI.isOperationLegalOrCustom(ISD::CTTZ, Op.getValueType())) { - SDLoc DL(Op); - return DAG.getNode(ISD::CTTZ, DL, Op.getValueType(), Op.getOperand(0)); - } +SDValue VectorLegalizer::ExpandROT(SDValue Op) { + SDValue Result; + if (TLI.expandROT(Op.getNode(), Result, DAG)) + return Result; - // Otherwise go ahead and unroll. + return DAG.UnrollVectorOp(Op.getNode()); +} + +SDValue VectorLegalizer::ExpandFMINNUM_FMAXNUM(SDValue Op) { + if (SDValue Expanded = TLI.expandFMINNUM_FMAXNUM(Op.getNode(), DAG)) + return Expanded; + return DAG.UnrollVectorOp(Op.getNode()); +} + +SDValue VectorLegalizer::ExpandAddSubSat(SDValue Op) { + if (SDValue Expanded = TLI.expandAddSubSat(Op.getNode(), DAG)) + return Expanded; return DAG.UnrollVectorOp(Op.getNode()); } @@ -1183,7 +1262,7 @@ SDValue VectorLegalizer::ExpandStrictFPOp(SDValue Op) { AddLegalizedOperand(Op.getValue(0), Result); AddLegalizedOperand(Op.getValue(1), NewChain); - return NewChain; + return Op.getResNo() ? NewChain : Result; } SDValue VectorLegalizer::UnrollVSETCC(SDValue Op) { |