summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp17
-rw-r--r--llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.h1
-rw-r--r--llvm/lib/Target/Hexagon/HexagonISelDAGToDAGHVX.cpp42
-rw-r--r--llvm/lib/Target/Hexagon/HexagonISelLowering.cpp1
-rw-r--r--llvm/lib/Target/Hexagon/HexagonISelLowering.h4
-rw-r--r--llvm/lib/Target/Hexagon/HexagonISelLoweringHVX.cpp4
-rw-r--r--llvm/lib/Target/Hexagon/HexagonPatternsHVX.td93
-rw-r--r--llvm/lib/Target/Hexagon/HexagonTargetTransformInfo.cpp2
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",
OpenPOWER on IntegriCloud