diff options
Diffstat (limited to 'llvm/lib/Target')
-rw-r--r-- | llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp | 17 | ||||
-rw-r--r-- | llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.h | 1 | ||||
-rw-r--r-- | llvm/lib/Target/Hexagon/HexagonISelDAGToDAGHVX.cpp | 42 | ||||
-rw-r--r-- | llvm/lib/Target/Hexagon/HexagonISelLowering.cpp | 1 | ||||
-rw-r--r-- | llvm/lib/Target/Hexagon/HexagonISelLowering.h | 4 | ||||
-rw-r--r-- | llvm/lib/Target/Hexagon/HexagonISelLoweringHVX.cpp | 4 | ||||
-rw-r--r-- | llvm/lib/Target/Hexagon/HexagonPatternsHVX.td | 93 | ||||
-rw-r--r-- | llvm/lib/Target/Hexagon/HexagonTargetTransformInfo.cpp | 2 |
8 files changed, 93 insertions, 71 deletions
diff --git a/llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp b/llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp index b2e9cc620d1..3f3585ca31a 100644 --- a/llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp +++ b/llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp @@ -758,22 +758,6 @@ void HexagonDAGToDAGISel::SelectFrameIndex(SDNode *N) { ReplaceNode(N, R); } - -void HexagonDAGToDAGISel::SelectBitcast(SDNode *N) { - EVT SVT = N->getOperand(0).getValueType(); - EVT DVT = N->getValueType(0); - if (!SVT.isVector() || !DVT.isVector() || - SVT.getVectorElementType() == MVT::i1 || - DVT.getVectorElementType() == MVT::i1 || - SVT.getSizeInBits() != DVT.getSizeInBits()) { - SelectCode(N); - return; - } - - ReplaceUses(SDValue(N, 0), N->getOperand(0)); - CurDAG->RemoveDeadNode(N); -} - void HexagonDAGToDAGISel::SelectVAlign(SDNode *N) { MVT ResTy = N->getValueType(0).getSimpleVT(); if (HST->isHVXVectorType(ResTy, true)) @@ -882,7 +866,6 @@ void HexagonDAGToDAGISel::Select(SDNode *N) { case ISD::Constant: return SelectConstant(N); case ISD::ConstantFP: return SelectConstantFP(N); case ISD::FrameIndex: return SelectFrameIndex(N); - case ISD::BITCAST: return SelectBitcast(N); case ISD::SHL: return SelectSHL(N); case ISD::LOAD: return SelectLoad(N); case ISD::STORE: return SelectStore(N); diff --git a/llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.h b/llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.h index b9f9d90b1f9..1c3379bf015 100644 --- a/llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.h +++ b/llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.h @@ -102,7 +102,6 @@ public: void SelectIntrinsicWOChain(SDNode *N); void SelectConstant(SDNode *N); void SelectConstantFP(SDNode *N); - void SelectBitcast(SDNode *N); void SelectV65Gather(SDNode *N); void SelectV65GatherPred(SDNode *N); void SelectHVXDualOutput(SDNode *N); diff --git a/llvm/lib/Target/Hexagon/HexagonISelDAGToDAGHVX.cpp b/llvm/lib/Target/Hexagon/HexagonISelDAGToDAGHVX.cpp index 7eddf55a48e..a5c911d15dc 100644 --- a/llvm/lib/Target/Hexagon/HexagonISelDAGToDAGHVX.cpp +++ b/llvm/lib/Target/Hexagon/HexagonISelDAGToDAGHVX.cpp @@ -919,36 +919,40 @@ static bool isPermutation(ArrayRef<int> Mask) { } bool HvxSelector::selectVectorConstants(SDNode *N) { - // Constant vectors are generated as loads from constant pools or - // as VSPLATs of a constant value. - // Since they are generated during the selection process, the main - // selection algorithm is not aware of them. Select them directly - // here. + // Constant vectors are generated as loads from constant pools or as + // splats of a constant value. Since they are generated during the + // selection process, the main selection algorithm is not aware of them. + // Select them directly here. SmallVector<SDNode*,4> Nodes; SetVector<SDNode*> WorkQ; + // The one-use test for VSPLATW's operand may fail due to dead nodes + // left over in the DAG. + DAG.RemoveDeadNodes(); + // The DAG can change (due to CSE) during selection, so cache all the // unselected nodes first to avoid traversing a mutating DAG. auto IsNodeToSelect = [] (SDNode *N) { if (N->isMachineOpcode()) return false; - unsigned Opc = N->getOpcode(); - if (Opc == HexagonISD::VSPLAT || Opc == HexagonISD::VZERO) - return true; - if (Opc == ISD::BITCAST) { - // Only select bitcasts of VSPLATs. - if (N->getOperand(0).getOpcode() == HexagonISD::VSPLAT) + switch (N->getOpcode()) { + case HexagonISD::VZERO: + case HexagonISD::VSPLATW: return true; + case ISD::LOAD: { + SDValue Addr = cast<LoadSDNode>(N)->getBasePtr(); + unsigned AddrOpc = Addr.getOpcode(); + if (AddrOpc == HexagonISD::AT_PCREL || AddrOpc == HexagonISD::CP) + if (Addr.getOperand(0).getOpcode() == ISD::TargetConstantPool) + return true; + } + break; } - if (Opc == ISD::LOAD) { - SDValue Addr = cast<LoadSDNode>(N)->getBasePtr(); - unsigned AddrOpc = Addr.getOpcode(); - if (AddrOpc == HexagonISD::AT_PCREL || AddrOpc == HexagonISD::CP) - if (Addr.getOperand(0).getOpcode() == ISD::TargetConstantPool) - return true; - } - return false; + // Make sure to select the operand of VSPLATW. + bool IsSplatOp = N->hasOneUse() && + N->use_begin()->getOpcode() == HexagonISD::VSPLATW; + return IsSplatOp; }; WorkQ.insert(N); diff --git a/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp b/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp index 40740f1e156..be036b3ddb3 100644 --- a/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp +++ b/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp @@ -1731,6 +1731,7 @@ const char* HexagonTargetLowering::getTargetNodeName(unsigned Opcode) const { case HexagonISD::VROR: return "HexagonISD::VROR"; case HexagonISD::READCYCLE: return "HexagonISD::READCYCLE"; case HexagonISD::VZERO: return "HexagonISD::VZERO"; + case HexagonISD::VSPLATW: return "HexagonISD::VSPLATW"; case HexagonISD::D2P: return "HexagonISD::D2P"; case HexagonISD::P2D: return "HexagonISD::P2D"; case HexagonISD::V2Q: return "HexagonISD::V2Q"; diff --git a/llvm/lib/Target/Hexagon/HexagonISelLowering.h b/llvm/lib/Target/Hexagon/HexagonISelLowering.h index adbb066171e..5ed26101d58 100644 --- a/llvm/lib/Target/Hexagon/HexagonISelLowering.h +++ b/llvm/lib/Target/Hexagon/HexagonISelLowering.h @@ -51,7 +51,8 @@ namespace HexagonISD { CP, // Constant pool. COMBINE, - VSPLAT, + VSPLAT, // Generic splat, selection depends on argument/return + // types. VASL, VASR, VLSR, @@ -77,6 +78,7 @@ namespace HexagonISD { QTRUE, QFALSE, VZERO, + VSPLATW, // HVX splat of a 32-bit word with an arbitrary result type. TYPECAST, // No-op that's used to convert between different legal // types in a register. VALIGN, // Align two vectors (in Op0, Op1) to one that would have diff --git a/llvm/lib/Target/Hexagon/HexagonISelLoweringHVX.cpp b/llvm/lib/Target/Hexagon/HexagonISelLoweringHVX.cpp index 4aad920f2bc..281cfcf9f89 100644 --- a/llvm/lib/Target/Hexagon/HexagonISelLoweringHVX.cpp +++ b/llvm/lib/Target/Hexagon/HexagonISelLoweringHVX.cpp @@ -367,9 +367,7 @@ HexagonTargetLowering::buildHvxVectorReg(ArrayRef<SDValue> Values, auto *IdxN = dyn_cast<ConstantSDNode>(SplatV.getNode()); if (IdxN && IdxN->isNullValue()) return getZero(dl, VecTy, DAG); - MVT WordTy = MVT::getVectorVT(MVT::i32, HwLen/4); - SDValue SV = DAG.getNode(HexagonISD::VSPLAT, dl, WordTy, SplatV); - return DAG.getBitcast(VecTy, SV); + return DAG.getNode(HexagonISD::VSPLATW, dl, VecTy, SplatV); } // Delay recognizing constant vectors until here, so that we can generate diff --git a/llvm/lib/Target/Hexagon/HexagonPatternsHVX.td b/llvm/lib/Target/Hexagon/HexagonPatternsHVX.td index 6217df504f1..9c313abee8b 100644 --- a/llvm/lib/Target/Hexagon/HexagonPatternsHVX.td +++ b/llvm/lib/Target/Hexagon/HexagonPatternsHVX.td @@ -9,7 +9,10 @@ def HexagonVEXTRACTW : SDNode<"HexagonISD::VEXTRACTW", SDTHexagonVEXTRACTW>; def SDTHexagonVINSERTW0: SDTypeProfile<1, 2, [SDTCisVec<0>, SDTCisSameAs<0, 1>, SDTCisVT<2, i32>]>; -def HexagonVINSERTW0 : SDNode<"HexagonISD::VINSERTW0", SDTHexagonVINSERTW0>; +def HexagonVINSERTW0: SDNode<"HexagonISD::VINSERTW0", SDTHexagonVINSERTW0>; + +def SDTHexagonVSPLATW: SDTypeProfile<1, 1, [SDTCisVec<0>, SDTCisVT<1, i32>]>; +def HexagonVSPLATW: SDNode<"HexagonISD::VSPLATW", SDTHexagonVSPLATW>; def HwLen2: SDNodeXForm<imm, [{ const auto &ST = static_cast<const HexagonSubtarget&>(CurDAG->getSubtarget()); @@ -157,6 +160,26 @@ let Predicates = [UseHVX] in { defm: HvxSt_pat<V6_vS32Ub_ai, unalignedstore, IsVecOff, HVI32>; } +// Bitcasts between same-size vector types are no-ops, except for the +// actual type change. +class Bitcast<ValueType ResTy, ValueType InpTy, RegisterClass RC> + : Pat<(ResTy (bitconvert (InpTy RC:$Val))), (ResTy RC:$Val)>; + +let Predicates = [UseHVX] in { + def: Bitcast<VecI8, VecI16, HvxVR>; + def: Bitcast<VecI8, VecI32, HvxVR>; + def: Bitcast<VecI16, VecI8, HvxVR>; + def: Bitcast<VecI16, VecI32, HvxVR>; + def: Bitcast<VecI32, VecI8, HvxVR>; + def: Bitcast<VecI32, VecI16, HvxVR>; + + def: Bitcast<VecPI8, VecPI16, HvxWR>; + def: Bitcast<VecPI8, VecPI32, HvxWR>; + def: Bitcast<VecPI16, VecPI8, HvxWR>; + def: Bitcast<VecPI16, VecPI32, HvxWR>; + def: Bitcast<VecPI32, VecPI8, HvxWR>; + def: Bitcast<VecPI32, VecPI16, HvxWR>; +} let Predicates = [UseHVX] in { def: Pat<(VecI8 vzero), (V6_vd0)>; @@ -190,38 +213,44 @@ let Predicates = [UseHVX] in { (V6_vinsertwr HvxVR:$Vu, I32:$Rt)>; def: Pat<(HexagonVINSERTW0 HVI32:$Vu, I32:$Rt), (V6_vinsertwr HvxVR:$Vu, I32:$Rt)>; +} + +def Vsplatib: OutPatFrag<(ops node:$V), (V6_lvsplatw (ToI32 (SplatB $V)))>; +def Vsplatih: OutPatFrag<(ops node:$V), (V6_lvsplatw (ToI32 (SplatH $V)))>; +def Vsplatiw: OutPatFrag<(ops node:$V), (V6_lvsplatw (ToI32 $V))>; +def Vsplatrb: OutPatFrag<(ops node:$Rs), (V6_lvsplatw (S2_vsplatrb $Rs))>; +def Vsplatrh: OutPatFrag<(ops node:$Rs), + (V6_lvsplatw (A2_combine_ll $Rs, $Rs))>; +def Vsplatrw: OutPatFrag<(ops node:$Rs), (V6_lvsplatw $Rs)>; + +def Rep: OutPatFrag<(ops node:$N), (Combinev $N, $N)>; + +let Predicates = [UseHVX] in { let AddedComplexity = 10 in { - def: Pat<(VecI8 (HexagonVSPLAT u8_0ImmPred:$V)), - (V6_lvsplatw (ToI32 (SplatB $V)))>; - def: Pat<(VecI16 (HexagonVSPLAT u16_0ImmPred:$V)), - (V6_lvsplatw (ToI32 (SplatH $V)))>; - def: Pat<(VecI32 (HexagonVSPLAT anyimm:$V)), - (V6_lvsplatw (ToI32 $V))>; - def: Pat<(VecPI8 (HexagonVSPLAT u8_0ImmPred:$V)), - (Combinev (V6_lvsplatw (ToI32 (SplatB $V))), - (V6_lvsplatw (ToI32 (SplatB $V))))>; - def: Pat<(VecPI16 (HexagonVSPLAT u16_0ImmPred:$V)), - (Combinev (V6_lvsplatw (ToI32 (SplatH $V))), - (V6_lvsplatw (ToI32 (SplatH $V))))>; - def: Pat<(VecPI32 (HexagonVSPLAT anyimm:$V)), - (Combinev (V6_lvsplatw (ToI32 $V)), (V6_lvsplatw (ToI32 $V)))>; + def: Pat<(VecI8 (HexagonVSPLAT u8_0ImmPred:$V)), (Vsplatib $V)>; + def: Pat<(VecI16 (HexagonVSPLAT u16_0ImmPred:$V)), (Vsplatih $V)>; + def: Pat<(VecI32 (HexagonVSPLAT anyimm:$V)), (Vsplatiw $V)>; + def: Pat<(VecPI8 (HexagonVSPLAT u8_0ImmPred:$V)), (Rep (Vsplatib $V))>; + def: Pat<(VecPI16 (HexagonVSPLAT u16_0ImmPred:$V)), (Rep (Vsplatih $V))>; + def: Pat<(VecPI32 (HexagonVSPLAT anyimm:$V)), (Rep (Vsplatiw $V))>; } - def: Pat<(VecI8 (HexagonVSPLAT I32:$Rs)), - (V6_lvsplatw (S2_vsplatrb I32:$Rs))>; - def: Pat<(VecI16 (HexagonVSPLAT I32:$Rs)), - (V6_lvsplatw (A2_combine_ll I32:$Rs, I32:$Rs))>; - def: Pat<(VecI32 (HexagonVSPLAT I32:$Rs)), - (V6_lvsplatw I32:$Rs)>; - def: Pat<(VecPI8 (HexagonVSPLAT I32:$Rs)), - (Combinev (V6_lvsplatw (S2_vsplatrb I32:$Rs)), - (V6_lvsplatw (S2_vsplatrb I32:$Rs)))>; - def: Pat<(VecPI16 (HexagonVSPLAT I32:$Rs)), - (Combinev (V6_lvsplatw (A2_combine_ll I32:$Rs, I32:$Rs)), - (V6_lvsplatw (A2_combine_ll I32:$Rs, I32:$Rs)))>; - def: Pat<(VecPI32 (HexagonVSPLAT I32:$Rs)), - (Combinev (V6_lvsplatw I32:$Rs), (V6_lvsplatw I32:$Rs))>; + def: Pat<(VecI8 (HexagonVSPLAT I32:$Rs)), (Vsplatrb $Rs)>; + def: Pat<(VecI16 (HexagonVSPLAT I32:$Rs)), (Vsplatrh $Rs)>; + def: Pat<(VecI32 (HexagonVSPLAT I32:$Rs)), (Vsplatrw $Rs)>; + def: Pat<(VecPI8 (HexagonVSPLAT I32:$Rs)), (Rep (Vsplatrb $Rs))>; + def: Pat<(VecPI16 (HexagonVSPLAT I32:$Rs)), (Rep (Vsplatrh $Rs))>; + def: Pat<(VecPI32 (HexagonVSPLAT I32:$Rs)), (Rep (Vsplatrw $Rs))>; + + def: Pat<(VecI8 (HexagonVSPLATW I32:$Rs)), (V6_lvsplatw I32:$Rs)>; + def: Pat<(VecI16 (HexagonVSPLATW I32:$Rs)), (V6_lvsplatw I32:$Rs)>; + def: Pat<(VecI32 (HexagonVSPLATW I32:$Rs)), (V6_lvsplatw I32:$Rs)>; + def: Pat<(VecPI8 (HexagonVSPLATW I32:$Rs)), (Rep (V6_lvsplatw I32:$Rs))>; + def: Pat<(VecPI16 (HexagonVSPLATW I32:$Rs)), (Rep (V6_lvsplatw I32:$Rs))>; + def: Pat<(VecPI32 (HexagonVSPLATW I32:$Rs)), (Rep (V6_lvsplatw I32:$Rs))>; +} +let Predicates = [UseHVX] in { def: Pat<(add HVI8:$Vs, HVI8:$Vt), (V6_vaddb HvxVR:$Vs, HvxVR:$Vt)>; def: Pat<(add HVI16:$Vs, HVI16:$Vt), (V6_vaddh HvxVR:$Vs, HvxVR:$Vt)>; def: Pat<(add HVI32:$Vs, HVI32:$Vt), (V6_vaddw HvxVR:$Vs, HvxVR:$Vt)>; @@ -237,8 +266,14 @@ let Predicates = [UseHVX] in { def: Pat<(sub HWI32:$Vs, HWI32:$Vt), (V6_vsubw_dv HvxWR:$Vs, HvxWR:$Vt)>; def: Pat<(and HVI8:$Vs, HVI8:$Vt), (V6_vand HvxVR:$Vs, HvxVR:$Vt)>; + def: Pat<(and HVI16:$Vs, HVI16:$Vt), (V6_vand HvxVR:$Vs, HvxVR:$Vt)>; + def: Pat<(and HVI32:$Vs, HVI32:$Vt), (V6_vand HvxVR:$Vs, HvxVR:$Vt)>; def: Pat<(or HVI8:$Vs, HVI8:$Vt), (V6_vor HvxVR:$Vs, HvxVR:$Vt)>; + def: Pat<(or HVI16:$Vs, HVI16:$Vt), (V6_vor HvxVR:$Vs, HvxVR:$Vt)>; + def: Pat<(or HVI32:$Vs, HVI32:$Vt), (V6_vor HvxVR:$Vs, HvxVR:$Vt)>; def: Pat<(xor HVI8:$Vs, HVI8:$Vt), (V6_vxor HvxVR:$Vs, HvxVR:$Vt)>; + def: Pat<(xor HVI16:$Vs, HVI16:$Vt), (V6_vxor HvxVR:$Vs, HvxVR:$Vt)>; + def: Pat<(xor HVI32:$Vs, HVI32:$Vt), (V6_vxor HvxVR:$Vs, HvxVR:$Vt)>; def: Pat<(vselect HQ8:$Qu, HVI8:$Vs, HVI8:$Vt), (V6_vmux HvxQR:$Qu, HvxVR:$Vs, HvxVR:$Vt)>; diff --git a/llvm/lib/Target/Hexagon/HexagonTargetTransformInfo.cpp b/llvm/lib/Target/Hexagon/HexagonTargetTransformInfo.cpp index bca856ae9cb..ded0adb97a3 100644 --- a/llvm/lib/Target/Hexagon/HexagonTargetTransformInfo.cpp +++ b/llvm/lib/Target/Hexagon/HexagonTargetTransformInfo.cpp @@ -28,7 +28,7 @@ using namespace llvm; #define DEBUG_TYPE "hexagontti" -static cl::opt<bool> HexagonAutoHVX("hexagon-autohvx", cl::init(false), +static cl::opt<bool> HexagonAutoHVX("hexagon-autohvx", cl::init(true), cl::Hidden, cl::desc("Enable loop vectorizer for HVX")); static cl::opt<bool> EmitLookupTables("hexagon-emit-lookup-tables", |