diff options
Diffstat (limited to 'llvm/lib/Target')
-rw-r--r-- | llvm/lib/Target/Hexagon/HexagonISelLowering.cpp | 61 | ||||
-rw-r--r-- | llvm/lib/Target/Hexagon/HexagonISelLowering.h | 2 | ||||
-rw-r--r-- | llvm/lib/Target/Hexagon/HexagonPatterns.td | 89 | ||||
-rw-r--r-- | llvm/lib/Target/Hexagon/HexagonPatternsHVX.td | 32 |
4 files changed, 135 insertions, 49 deletions
diff --git a/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp b/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp index 61cac288e48..a443a29e061 100644 --- a/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp +++ b/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp @@ -1501,11 +1501,15 @@ HexagonTargetLowering::HexagonTargetLowering(const TargetMachine &TM, setOperationAction(ISD::STORE, VT, Custom); } - for (MVT VT : {MVT::v2i16, MVT::v4i8, MVT::v2i32, MVT::v4i16, MVT::v2i32}) { - setCondCodeAction(ISD::SETLT, VT, Expand); + for (MVT VT : {MVT::v2i16, MVT::v4i8, MVT::v8i8, MVT::v2i32, MVT::v4i16, + MVT::v2i32}) { + setCondCodeAction(ISD::SETNE, VT, Expand); setCondCodeAction(ISD::SETLE, VT, Expand); - setCondCodeAction(ISD::SETULT, VT, Expand); + setCondCodeAction(ISD::SETGE, VT, Expand); + setCondCodeAction(ISD::SETLT, VT, Expand); setCondCodeAction(ISD::SETULE, VT, Expand); + setCondCodeAction(ISD::SETUGE, VT, Expand); + setCondCodeAction(ISD::SETULT, VT, Expand); } // Custom-lower bitcasts from i8 to v8i1. @@ -1560,6 +1564,8 @@ HexagonTargetLowering::HexagonTargetLowering(const TargetMachine &TM, setOperationAction(ISD::FSUB, MVT::f64, Legal); } + setTargetDAGCombine(ISD::VSELECT); + if (Subtarget.useHVXOps()) initializeHVXLowering(); @@ -1649,6 +1655,8 @@ const char* HexagonTargetLowering::getTargetNodeName(unsigned Opcode) const { case HexagonISD::VINSERTW0: return "HexagonISD::VINSERTW0"; case HexagonISD::VROR: return "HexagonISD::VROR"; case HexagonISD::READCYCLE: return "HexagonISD::READCYCLE"; + case HexagonISD::PTRUE: return "HexagonISD::PTRUE"; + case HexagonISD::PFALSE: return "HexagonISD::PFALSE"; case HexagonISD::VZERO: return "HexagonISD::VZERO"; case HexagonISD::VSPLATW: return "HexagonISD::VSPLATW"; case HexagonISD::D2P: return "HexagonISD::D2P"; @@ -2464,6 +2472,23 @@ HexagonTargetLowering::LowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG) const { return buildVector64(Ops, dl, VecTy, DAG); if (VecTy == MVT::v8i1 || VecTy == MVT::v4i1 || VecTy == MVT::v2i1) { + // Check if this is a special case or all-0 or all-1. + bool All0 = true, All1 = true; + for (SDValue P : Ops) { + auto *CN = dyn_cast<ConstantSDNode>(P.getNode()); + if (CN == nullptr) { + All0 = All1 = false; + break; + } + uint32_t C = CN->getZExtValue(); + All0 &= (C == 0); + All1 &= (C == 1); + } + if (All0) + return DAG.getNode(HexagonISD::PFALSE, dl, VecTy); + if (All1) + return DAG.getNode(HexagonISD::PTRUE, dl, VecTy); + // For each i1 element in the resulting predicate register, put 1 // shifted by the index of the element into a general-purpose register, // then or them together and transfer it back into a predicate register. @@ -2890,7 +2915,37 @@ HexagonTargetLowering::PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) if (isHvxOperation(Op)) { if (SDValue V = PerformHvxDAGCombine(N, DCI)) return V; + return SDValue(); + } + + const SDLoc &dl(Op); + unsigned Opc = Op.getOpcode(); + + if (Opc == HexagonISD::P2D) { + SDValue P = Op.getOperand(0); + switch (P.getOpcode()) { + case HexagonISD::PTRUE: + return DCI.DAG.getConstant(-1, dl, ty(Op)); + case HexagonISD::PFALSE: + return getZero(dl, ty(Op), DCI.DAG); + default: + break; + } + } else if (Opc == ISD::VSELECT) { + // This is pretty much duplicated in HexagonISelLoweringHVX... + // + // (vselect (xor x, ptrue), v0, v1) -> (vselect x, v1, v0) + SDValue Cond = Op.getOperand(0); + if (Cond->getOpcode() == ISD::XOR) { + SDValue C0 = Cond.getOperand(0), C1 = Cond.getOperand(1); + if (C1->getOpcode() == HexagonISD::PTRUE) { + SDValue VSel = DCI.DAG.getNode(ISD::VSELECT, dl, ty(Op), C0, + Op.getOperand(2), Op.getOperand(1)); + return VSel; + } + } } + return SDValue(); } diff --git a/llvm/lib/Target/Hexagon/HexagonISelLowering.h b/llvm/lib/Target/Hexagon/HexagonISelLowering.h index 4bc49dd508c..642ad1db19c 100644 --- a/llvm/lib/Target/Hexagon/HexagonISelLowering.h +++ b/llvm/lib/Target/Hexagon/HexagonISelLowering.h @@ -68,6 +68,8 @@ namespace HexagonISD { EH_RETURN, DCFETCH, READCYCLE, + PTRUE, + PFALSE, D2P, // Convert 8-byte value to 8-bit predicate register. [*] P2D, // Convert 8-bit predicate register to 8-byte value. [*] V2Q, // Convert HVX vector to a vector predicate reg. [*] diff --git a/llvm/lib/Target/Hexagon/HexagonPatterns.td b/llvm/lib/Target/Hexagon/HexagonPatterns.td index 9a0e0670188..bfdeec7c5cf 100644 --- a/llvm/lib/Target/Hexagon/HexagonPatterns.td +++ b/llvm/lib/Target/Hexagon/HexagonPatterns.td @@ -99,13 +99,21 @@ def HWI8: PatLeaf<(VecPI8 HvxWR:$R)>; def HWI16: PatLeaf<(VecPI16 HvxWR:$R)>; def HWI32: PatLeaf<(VecPI32 HvxWR:$R)>; +def SDTVecLeaf: + SDTypeProfile<1, 0, [SDTCisVec<0>]>; def SDTVecVecIntOp: SDTypeProfile<1, 3, [SDTCisVec<0>, SDTCisVec<1>, SDTCisSameAs<1,2>, SDTCisVT<3,i32>]>; +def HexagonPTRUE: SDNode<"HexagonISD::PTRUE", SDTVecLeaf>; +def HexagonPFALSE: SDNode<"HexagonISD::PFALSE", SDTVecLeaf>; def HexagonVALIGN: SDNode<"HexagonISD::VALIGN", SDTVecVecIntOp>; def HexagonVALIGNADDR: SDNode<"HexagonISD::VALIGNADDR", SDTIntUnaryOp>; +def ptrue: PatFrag<(ops), (HexagonPTRUE)>; +def pfalse: PatFrag<(ops), (HexagonPFALSE)>; +def pnot: PatFrag<(ops node:$Pu), (xor node:$Pu, ptrue)>; + def valign: PatFrag<(ops node:$Vt, node:$Vs, node:$Ru), (HexagonVALIGN node:$Vt, node:$Vs, node:$Ru)>; def valignaddr: PatFrag<(ops node:$Addr), (HexagonVALIGNADDR node:$Addr)>; @@ -320,6 +328,17 @@ multiclass SelMinMax_pats<PatFrag CmpOp, PatFrag Val, (InstB Val:$A, Val:$B)>; } +multiclass MinMax_pats<InstHexagon PickT, InstHexagon PickS, + PatFrag Sel, PatFrag CmpOp, + ValueType CmpType, PatFrag CmpPred> { + def: Pat<(Sel (CmpType (CmpOp CmpPred:$Vs, CmpPred:$Vt)), + CmpPred:$Vt, CmpPred:$Vs), + (PickT CmpPred:$Vs, CmpPred:$Vt)>; + def: Pat<(Sel (CmpType (CmpOp CmpPred:$Vs, CmpPred:$Vt)), + CmpPred:$Vs, CmpPred:$Vt), + (PickS CmpPred:$Vs, CmpPred:$Vt)>; +} + // Frags for commonly used SDNodes. def Add: pf2<add>; def And: pf2<and>; def Sra: pf2<sra>; @@ -497,7 +516,9 @@ def: Pat<(v2i16 (trunc V2I32:$Rs)), // def: Pat<(not I1:$Ps), (C2_not I1:$Ps)>; -def: Pat<(not V8I1:$Ps), (C2_not V8I1:$Ps)>; +def: Pat<(pnot V2I1:$Ps), (C2_not V2I1:$Ps)>; +def: Pat<(pnot V4I1:$Ps), (C2_not V4I1:$Ps)>; +def: Pat<(pnot V8I1:$Ps), (C2_not V8I1:$Ps)>; def: Pat<(add I1:$Ps, -1), (C2_not I1:$Ps)>; multiclass BoolOpR_RR_pat<InstHexagon MI, PatFrag Op> { @@ -823,6 +844,14 @@ def: Pat<(vselect V4I1:$Pu, V4I16:$Rs, V4I16:$Rt), def: Pat<(vselect V2I1:$Pu, V2I32:$Rs, V2I32:$Rt), (C2_vmux V2I1:$Pu, V2I32:$Rs, V2I32:$Rt)>; +def: Pat<(vselect (pnot V8I1:$Pu), V8I8:$Rs, V8I8:$Rt), + (C2_vmux V8I1:$Pu, V8I8:$Rt, V8I8:$Rs)>; +def: Pat<(vselect (pnot V4I1:$Pu), V4I16:$Rs, V4I16:$Rt), + (C2_vmux V4I1:$Pu, V4I16:$Rt, V4I16:$Rs)>; +def: Pat<(vselect (pnot V2I1:$Pu), V2I32:$Rs, V2I32:$Rt), + (C2_vmux V2I1:$Pu, V2I32:$Rt, V2I32:$Rs)>; + + // From LegalizeDAG.cpp: (Pu ? Pv : Pw) <=> (Pu & Pv) | (!Pu & Pw). def: Pat<(select I1:$Pu, I1:$Pv, I1:$Pw), (C2_or (C2_and I1:$Pu, I1:$Pv), @@ -855,32 +884,44 @@ let AddedComplexity = 200 in { } let AddedComplexity = 200 in { - defm: SelMinMax_pats<setge, I32, A2_max, A2_min>; - defm: SelMinMax_pats<setgt, I32, A2_max, A2_min>; - defm: SelMinMax_pats<setle, I32, A2_min, A2_max>; - defm: SelMinMax_pats<setlt, I32, A2_min, A2_max>; - defm: SelMinMax_pats<setuge, I32, A2_maxu, A2_minu>; - defm: SelMinMax_pats<setugt, I32, A2_maxu, A2_minu>; - defm: SelMinMax_pats<setule, I32, A2_minu, A2_maxu>; - defm: SelMinMax_pats<setult, I32, A2_minu, A2_maxu>; - - defm: SelMinMax_pats<setge, I64, A2_maxp, A2_minp>; - defm: SelMinMax_pats<setgt, I64, A2_maxp, A2_minp>; - defm: SelMinMax_pats<setle, I64, A2_minp, A2_maxp>; - defm: SelMinMax_pats<setlt, I64, A2_minp, A2_maxp>; - defm: SelMinMax_pats<setuge, I64, A2_maxup, A2_minup>; - defm: SelMinMax_pats<setugt, I64, A2_maxup, A2_minup>; - defm: SelMinMax_pats<setule, I64, A2_minup, A2_maxup>; - defm: SelMinMax_pats<setult, I64, A2_minup, A2_maxup>; + defm: MinMax_pats<A2_min, A2_max, select, setgt, i1, I32>; + defm: MinMax_pats<A2_min, A2_max, select, setge, i1, I32>; + defm: MinMax_pats<A2_max, A2_min, select, setlt, i1, I32>; + defm: MinMax_pats<A2_max, A2_min, select, setle, i1, I32>; + defm: MinMax_pats<A2_minu, A2_maxu, select, setugt, i1, I32>; + defm: MinMax_pats<A2_minu, A2_maxu, select, setuge, i1, I32>; + defm: MinMax_pats<A2_maxu, A2_minu, select, setult, i1, I32>; + defm: MinMax_pats<A2_maxu, A2_minu, select, setule, i1, I32>; + + defm: MinMax_pats<A2_minp, A2_maxp, select, setgt, i1, I64>; + defm: MinMax_pats<A2_minp, A2_maxp, select, setge, i1, I64>; + defm: MinMax_pats<A2_maxp, A2_minp, select, setlt, i1, I64>; + defm: MinMax_pats<A2_maxp, A2_minp, select, setle, i1, I64>; + defm: MinMax_pats<A2_minup, A2_maxup, select, setugt, i1, I64>; + defm: MinMax_pats<A2_minup, A2_maxup, select, setuge, i1, I64>; + defm: MinMax_pats<A2_maxup, A2_minup, select, setult, i1, I64>; + defm: MinMax_pats<A2_maxup, A2_minup, select, setule, i1, I64>; } let AddedComplexity = 100 in { - defm: SelMinMax_pats<setolt, F32, F2_sfmin, F2_sfmax>; - defm: SelMinMax_pats<setole, F32, F2_sfmin, F2_sfmax>; - defm: SelMinMax_pats<setogt, F32, F2_sfmax, F2_sfmin>; - defm: SelMinMax_pats<setoge, F32, F2_sfmax, F2_sfmin>; -} - + defm: MinMax_pats<F2_sfmin, F2_sfmax, select, setogt, i1, F32>; + defm: MinMax_pats<F2_sfmin, F2_sfmax, select, setoge, i1, F32>; + defm: MinMax_pats<F2_sfmax, F2_sfmin, select, setolt, i1, F32>; + defm: MinMax_pats<F2_sfmax, F2_sfmin, select, setole, i1, F32>; +} + +defm: MinMax_pats<A2_vminb, A2_vmaxb, vselect, setgt, v8i1, V8I8>; +defm: MinMax_pats<A2_vminb, A2_vmaxb, vselect, setge, v8i1, V8I8>; +defm: MinMax_pats<A2_vminh, A2_vmaxh, vselect, setgt, v4i1, V4I16>; +defm: MinMax_pats<A2_vminh, A2_vmaxh, vselect, setge, v4i1, V4I16>; +defm: MinMax_pats<A2_vminw, A2_vmaxw, vselect, setgt, v2i1, V2I32>; +defm: MinMax_pats<A2_vminw, A2_vmaxw, vselect, setge, v2i1, V2I32>; +defm: MinMax_pats<A2_vminub, A2_vmaxub, vselect, setugt, v8i1, V8I8>; +defm: MinMax_pats<A2_vminub, A2_vmaxub, vselect, setuge, v8i1, V8I8>; +defm: MinMax_pats<A2_vminuh, A2_vmaxuh, vselect, setugt, v4i1, V4I16>; +defm: MinMax_pats<A2_vminuh, A2_vmaxuh, vselect, setuge, v4i1, V4I16>; +defm: MinMax_pats<A2_vminuw, A2_vmaxuw, vselect, setugt, v2i1, V2I32>; +defm: MinMax_pats<A2_vminuw, A2_vmaxuw, vselect, setuge, v2i1, V2I32>; // --(7) Insert/extract -------------------------------------------------- // diff --git a/llvm/lib/Target/Hexagon/HexagonPatternsHVX.td b/llvm/lib/Target/Hexagon/HexagonPatternsHVX.td index 4f3d87263b5..32e2260de07 100644 --- a/llvm/lib/Target/Hexagon/HexagonPatternsHVX.td +++ b/llvm/lib/Target/Hexagon/HexagonPatternsHVX.td @@ -1,5 +1,3 @@ -def SDTVecLeaf: - SDTypeProfile<1, 0, [SDTCisVec<0>]>; def SDTVecBinOp: SDTypeProfile<1, 2, [SDTCisVec<0>, SDTCisVec<1>, SDTCisSameAs<1,2>]>; @@ -259,28 +257,18 @@ class Vneg1<ValueType VecTy> class Vnot<ValueType VecTy> : PatFrag<(ops node:$Vs), (xor $Vs, Vneg1<VecTy>)>; -multiclass VMinMax_pat<InstHexagon MinInst, InstHexagon MaxInst, PatFrag CmpOp, - ValueType CmpType, PatFrag CmpPred> { - def: Pat<(vselect (CmpType (CmpOp CmpPred:$Vs, CmpPred:$Vt)), - CmpPred:$Vt, CmpPred:$Vs), - (MinInst CmpPred:$Vs, CmpPred:$Vt)>; - def: Pat<(vselect (CmpType (CmpOp CmpPred:$Vs, CmpPred:$Vt)), - CmpPred:$Vs, CmpPred:$Vt), - (MaxInst CmpPred:$Vs, CmpPred:$Vt)>; -} - let Predicates = [UseHVX] in { let AddedComplexity = 220 in { - defm: VMinMax_pat<V6_vminb, V6_vmaxb, setgt, VecQ8, HVI8>; - defm: VMinMax_pat<V6_vminb, V6_vmaxb, setge, VecQ8, HVI8>; - defm: VMinMax_pat<V6_vminub, V6_vmaxub, setugt, VecQ8, HVI8>; - defm: VMinMax_pat<V6_vminub, V6_vmaxub, setuge, VecQ8, HVI8>; - defm: VMinMax_pat<V6_vminh, V6_vmaxh, setgt, VecQ16, HVI16>; - defm: VMinMax_pat<V6_vminh, V6_vmaxh, setge, VecQ16, HVI16>; - defm: VMinMax_pat<V6_vminuh, V6_vmaxuh, setugt, VecQ16, HVI16>; - defm: VMinMax_pat<V6_vminuh, V6_vmaxuh, setuge, VecQ16, HVI16>; - defm: VMinMax_pat<V6_vminw, V6_vmaxw, setgt, VecQ32, HVI32>; - defm: VMinMax_pat<V6_vminw, V6_vmaxw, setge, VecQ32, HVI32>; + defm: MinMax_pats<V6_vminb, V6_vmaxb, vselect, setgt, VecQ8, HVI8>; + defm: MinMax_pats<V6_vminb, V6_vmaxb, vselect, setge, VecQ8, HVI8>; + defm: MinMax_pats<V6_vminub, V6_vmaxub, vselect, setugt, VecQ8, HVI8>; + defm: MinMax_pats<V6_vminub, V6_vmaxub, vselect, setuge, VecQ8, HVI8>; + defm: MinMax_pats<V6_vminh, V6_vmaxh, vselect, setgt, VecQ16, HVI16>; + defm: MinMax_pats<V6_vminh, V6_vmaxh, vselect, setge, VecQ16, HVI16>; + defm: MinMax_pats<V6_vminuh, V6_vmaxuh, vselect, setugt, VecQ16, HVI16>; + defm: MinMax_pats<V6_vminuh, V6_vmaxuh, vselect, setuge, VecQ16, HVI16>; + defm: MinMax_pats<V6_vminw, V6_vmaxw, vselect, setgt, VecQ32, HVI32>; + defm: MinMax_pats<V6_vminw, V6_vmaxw, vselect, setge, VecQ32, HVI32>; } } |