[llvm] 9237e73 - [Hexagon] Replace HexagonISD::VSPLAT with ISD::SPLAT_VECTOR
Krzysztof Parzyszek via llvm-commits
llvm-commits at lists.llvm.org
Sat Oct 10 17:51:42 PDT 2020
Author: Krzysztof Parzyszek
Date: 2020-10-10T19:49:47-05:00
New Revision: 9237e73ae8a359b8616b04d225aff1cd3e93938b
URL: https://github.com/llvm/llvm-project/commit/9237e73ae8a359b8616b04d225aff1cd3e93938b
DIFF: https://github.com/llvm/llvm-project/commit/9237e73ae8a359b8616b04d225aff1cd3e93938b.diff
LOG: [Hexagon] Replace HexagonISD::VSPLAT with ISD::SPLAT_VECTOR
This removes VSPLAT and VZERO. VZERO is now SPLAT_VECTOR of (i32 0).
Included is also a testcase for the previous (target-independent)
commit.
Added:
llvm/test/CodeGen/Hexagon/isel-splat-vector-crash.ll
llvm/test/CodeGen/Hexagon/isel-splat-vector-dag-crash.ll
Modified:
llvm/lib/Target/Hexagon/HexagonISelLowering.cpp
llvm/lib/Target/Hexagon/HexagonISelLowering.h
llvm/lib/Target/Hexagon/HexagonISelLoweringHVX.cpp
llvm/lib/Target/Hexagon/HexagonPatterns.td
llvm/lib/Target/Hexagon/HexagonPatternsHVX.td
llvm/test/CodeGen/Hexagon/vect/vect-cst-v4i32.ll
llvm/test/CodeGen/Hexagon/vect/vect-vsplath.ll
Removed:
################################################################################
diff --git a/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp b/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp
index 04abb21468d3..b2fc79215c1e 100644
--- a/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp
+++ b/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp
@@ -1620,7 +1620,8 @@ HexagonTargetLowering::HexagonTargetLowering(const TargetMachine &TM,
ISD::BUILD_VECTOR, ISD::SCALAR_TO_VECTOR,
ISD::EXTRACT_VECTOR_ELT, ISD::INSERT_VECTOR_ELT,
ISD::EXTRACT_SUBVECTOR, ISD::INSERT_SUBVECTOR,
- ISD::CONCAT_VECTORS, ISD::VECTOR_SHUFFLE
+ ISD::CONCAT_VECTORS, ISD::VECTOR_SHUFFLE,
+ ISD::SPLAT_VECTOR,
};
for (MVT VT : MVT::fixedlen_vector_valuetypes()) {
@@ -1677,6 +1678,9 @@ HexagonTargetLowering::HexagonTargetLowering(const TargetMachine &TM,
setOperationAction(ISD::AND, NativeVT, Legal);
setOperationAction(ISD::OR, NativeVT, Legal);
setOperationAction(ISD::XOR, NativeVT, Legal);
+
+ if (NativeVT.getVectorElementType() != MVT::i1)
+ setOperationAction(ISD::SPLAT_VECTOR, NativeVT, Legal);
}
// Custom lower unaligned loads.
@@ -1843,14 +1847,12 @@ const char* HexagonTargetLowering::getTargetNodeName(unsigned Opcode) const {
case HexagonISD::VASL: return "HexagonISD::VASL";
case HexagonISD::VASR: return "HexagonISD::VASR";
case HexagonISD::VLSR: return "HexagonISD::VLSR";
- case HexagonISD::VSPLAT: return "HexagonISD::VSPLAT";
case HexagonISD::VEXTRACTW: return "HexagonISD::VEXTRACTW";
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::D2P: return "HexagonISD::D2P";
case HexagonISD::P2D: return "HexagonISD::P2D";
case HexagonISD::V2Q: return "HexagonISD::V2Q";
@@ -2221,26 +2223,33 @@ HexagonTargetLowering::LowerVECTOR_SHUFFLE(SDValue Op, SelectionDAG &DAG)
SDValue
HexagonTargetLowering::getVectorShiftByInt(SDValue Op, SelectionDAG &DAG)
const {
- if (auto *BVN = dyn_cast<BuildVectorSDNode>(Op.getOperand(1).getNode())) {
- if (SDValue S = BVN->getSplatValue()) {
- unsigned NewOpc;
- switch (Op.getOpcode()) {
- case ISD::SHL:
- NewOpc = HexagonISD::VASL;
- break;
- case ISD::SRA:
- NewOpc = HexagonISD::VASR;
- break;
- case ISD::SRL:
- NewOpc = HexagonISD::VLSR;
- break;
- default:
- llvm_unreachable("Unexpected shift opcode");
- }
- return DAG.getNode(NewOpc, SDLoc(Op), ty(Op), Op.getOperand(0), S);
- }
+ unsigned NewOpc;
+ switch (Op.getOpcode()) {
+ case ISD::SHL:
+ NewOpc = HexagonISD::VASL;
+ break;
+ case ISD::SRA:
+ NewOpc = HexagonISD::VASR;
+ break;
+ case ISD::SRL:
+ NewOpc = HexagonISD::VLSR;
+ break;
+ default:
+ llvm_unreachable("Unexpected shift opcode");
}
+ SDValue Op0 = Op.getOperand(0);
+ SDValue Op1 = Op.getOperand(1);
+ const SDLoc &dl(Op);
+
+ switch (Op1.getOpcode()) {
+ case ISD::BUILD_VECTOR:
+ if (SDValue S = cast<BuildVectorSDNode>(Op1)->getSplatValue())
+ return DAG.getNode(NewOpc, dl, ty(Op), Op0, S);
+ break;
+ case ISD::SPLAT_VECTOR:
+ return DAG.getNode(NewOpc, dl, ty(Op), Op0, Op1.getOperand(0));
+ }
return SDValue();
}
@@ -2317,9 +2326,10 @@ HexagonTargetLowering::buildVector32(ArrayRef<SDValue> Elem, const SDLoc &dl,
bool AllConst = getBuildVectorConstInts(Elem, VecTy, DAG, Consts);
unsigned First, Num = Elem.size();
- for (First = 0; First != Num; ++First)
+ for (First = 0; First != Num; ++First) {
if (!isUndef(Elem[First]))
break;
+ }
if (First == Num)
return DAG.getUNDEF(VecTy);
@@ -2351,18 +2361,16 @@ HexagonTargetLowering::buildVector32(ArrayRef<SDValue> Elem, const SDLoc &dl,
// Then try splat.
bool IsSplat = true;
- for (unsigned i = 0; i != Num; ++i) {
- if (i == First)
- continue;
+ for (unsigned i = First+1; i != Num; ++i) {
if (Elem[i] == Elem[First] || isUndef(Elem[i]))
continue;
IsSplat = false;
break;
}
if (IsSplat) {
- // Legalize the operand to VSPLAT.
+ // Legalize the operand of SPLAT_VECTOR.
SDValue Ext = DAG.getZExtOrTrunc(Elem[First], dl, MVT::i32);
- return DAG.getNode(HexagonISD::VSPLAT, dl, VecTy, Ext);
+ return DAG.getNode(ISD::SPLAT_VECTOR, dl, VecTy, Ext);
}
// Generate
@@ -2400,9 +2408,10 @@ HexagonTargetLowering::buildVector64(ArrayRef<SDValue> Elem, const SDLoc &dl,
bool AllConst = getBuildVectorConstInts(Elem, VecTy, DAG, Consts);
unsigned First, Num = Elem.size();
- for (First = 0; First != Num; ++First)
+ for (First = 0; First != Num; ++First) {
if (!isUndef(Elem[First]))
break;
+ }
if (First == Num)
return DAG.getUNDEF(VecTy);
@@ -2413,18 +2422,16 @@ HexagonTargetLowering::buildVector64(ArrayRef<SDValue> Elem, const SDLoc &dl,
// First try splat if possible.
if (ElemTy == MVT::i16) {
bool IsSplat = true;
- for (unsigned i = 0; i != Num; ++i) {
- if (i == First)
- continue;
+ for (unsigned i = First+1; i != Num; ++i) {
if (Elem[i] == Elem[First] || isUndef(Elem[i]))
continue;
IsSplat = false;
break;
}
if (IsSplat) {
- // Legalize the operand to VSPLAT.
+ // Legalize the operand of SPLAT_VECTOR
SDValue Ext = DAG.getZExtOrTrunc(Elem[First], dl, MVT::i32);
- return DAG.getNode(HexagonISD::VSPLAT, dl, VecTy, Ext);
+ return DAG.getNode(ISD::SPLAT_VECTOR, dl, VecTy, Ext);
}
}
@@ -2642,7 +2649,7 @@ HexagonTargetLowering::getZero(const SDLoc &dl, MVT Ty, SelectionDAG &DAG)
unsigned W = Ty.getSizeInBits();
if (W <= 64)
return DAG.getBitcast(Ty, DAG.getConstant(0, dl, MVT::getIntegerVT(W)));
- return DAG.getNode(HexagonISD::VZERO, dl, Ty);
+ return DAG.getNode(ISD::SPLAT_VECTOR, dl, Ty, getZero(dl, MVT::i32, DAG));
}
if (Ty.isInteger())
@@ -3146,14 +3153,15 @@ HexagonTargetLowering::ReplaceNodeResults(SDNode *N,
SDValue
HexagonTargetLowering::PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI)
const {
- if (DCI.isBeforeLegalizeOps())
- return SDValue();
if (isHvxOperation(N, DCI.DAG)) {
if (SDValue V = PerformHvxDAGCombine(N, DCI))
return V;
return SDValue();
}
+ if (DCI.isBeforeLegalizeOps())
+ return SDValue();
+
SDValue Op(N, 0);
const SDLoc &dl(Op);
unsigned Opc = Op.getOpcode();
diff --git a/llvm/lib/Target/Hexagon/HexagonISelLowering.h b/llvm/lib/Target/Hexagon/HexagonISelLowering.h
index 9d3d98635617..b7715cc94833 100644
--- a/llvm/lib/Target/Hexagon/HexagonISelLowering.h
+++ b/llvm/lib/Target/Hexagon/HexagonISelLowering.h
@@ -53,8 +53,6 @@ enum NodeType : unsigned {
CP, // Constant pool.
COMBINE,
- VSPLAT, // Generic splat, selection depends on argument/return
- // types.
VASL,
VASR,
VLSR,
@@ -81,7 +79,6 @@ enum NodeType : unsigned {
QCAT,
QTRUE,
QFALSE,
- VZERO,
TYPECAST, // No-op that's used to convert between
diff erent 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 85b6e6bfb20a..1582443765a9 100644
--- a/llvm/lib/Target/Hexagon/HexagonISelLoweringHVX.cpp
+++ b/llvm/lib/Target/Hexagon/HexagonISelLoweringHVX.cpp
@@ -94,6 +94,7 @@ HexagonTargetLowering::initializeHVXLowering() {
setOperationAction(ISD::MUL, T, Legal);
setOperationAction(ISD::CTPOP, T, Legal);
setOperationAction(ISD::CTLZ, T, Legal);
+ setOperationAction(ISD::SPLAT_VECTOR, T, Legal);
if (T != ByteV) {
setOperationAction(ISD::SIGN_EXTEND_VECTOR_INREG, T, Legal);
setOperationAction(ISD::ZERO_EXTEND_VECTOR_INREG, T, Legal);
@@ -153,6 +154,7 @@ HexagonTargetLowering::initializeHVXLowering() {
setOperationAction(ISD::ANY_EXTEND_VECTOR_INREG, T, Custom);
setOperationAction(ISD::SIGN_EXTEND_VECTOR_INREG, T, Legal);
setOperationAction(ISD::ZERO_EXTEND_VECTOR_INREG, T, Legal);
+ setOperationAction(ISD::SPLAT_VECTOR, T, Custom);
setOperationAction(ISD::LOAD, T, Custom);
setOperationAction(ISD::STORE, T, Custom);
@@ -244,6 +246,7 @@ HexagonTargetLowering::initializeHVXLowering() {
}
}
+ setTargetDAGCombine(ISD::SPLAT_VECTOR);
setTargetDAGCombine(ISD::VSELECT);
}
@@ -497,7 +500,7 @@ HexagonTargetLowering::buildHvxVectorReg(ArrayRef<SDValue> Values,
if (IdxN && IdxN->isNullValue())
return getZero(dl, VecTy, DAG);
MVT WordTy = MVT::getVectorVT(MVT::i32, HwLen/4);
- SDValue S = DAG.getNode(HexagonISD::VSPLAT, dl, WordTy, SplatV);
+ SDValue S = DAG.getNode(ISD::SPLAT_VECTOR, dl, WordTy, SplatV);
return DAG.getBitcast(VecTy, S);
}
@@ -1128,7 +1131,7 @@ HexagonTargetLowering::extendHvxVectorPred(SDValue VecV, const SDLoc &dl,
return DAG.getNode(HexagonISD::Q2V, dl, ResTy, VecV);
assert(ty(VecV).getVectorNumElements() == ResTy.getVectorNumElements());
- SDValue True = DAG.getNode(HexagonISD::VSPLAT, dl, ResTy,
+ SDValue True = DAG.getNode(ISD::SPLAT_VECTOR, dl, ResTy,
DAG.getConstant(1, dl, MVT::i32));
SDValue False = getZero(dl, ResTy, DAG);
return DAG.getSelect(dl, ResTy, VecV, True, False);
@@ -1424,11 +1427,11 @@ HexagonTargetLowering::LowerHvxCttz(SDValue Op, SelectionDAG &DAG) const {
MVT ElemTy = ty(InpV).getVectorElementType();
unsigned ElemWidth = ElemTy.getSizeInBits();
- SDValue Vec1 = DAG.getNode(HexagonISD::VSPLAT, dl, ResTy,
+ SDValue Vec1 = DAG.getNode(ISD::SPLAT_VECTOR, dl, ResTy,
DAG.getConstant(1, dl, MVT::i32));
- SDValue VecW = DAG.getNode(HexagonISD::VSPLAT, dl, ResTy,
+ SDValue VecW = DAG.getNode(ISD::SPLAT_VECTOR, dl, ResTy,
DAG.getConstant(ElemWidth, dl, MVT::i32));
- SDValue VecN1 = DAG.getNode(HexagonISD::VSPLAT, dl, ResTy,
+ SDValue VecN1 = DAG.getNode(ISD::SPLAT_VECTOR, dl, ResTy,
DAG.getConstant(-1, dl, MVT::i32));
// Do not use DAG.getNOT, because that would create BUILD_VECTOR with
@@ -2009,6 +2012,7 @@ HexagonTargetLowering::LowerHvxOperation(SDValue Op, SelectionDAG &DAG) const {
case ISD::SIGN_EXTEND:
case ISD::ZERO_EXTEND:
case ISD::SIGN_EXTEND_INREG:
+ case ISD::SPLAT_VECTOR:
return SplitHvxPairOp(Op, DAG);
}
}
@@ -2131,14 +2135,14 @@ HexagonTargetLowering::ReplaceHvxNodeResults(SDNode *N,
SDValue
HexagonTargetLowering::PerformHvxDAGCombine(SDNode *N, DAGCombinerInfo &DCI)
const {
- if (DCI.isBeforeLegalizeOps())
- return SDValue();
-
const SDLoc &dl(N);
SelectionDAG &DAG = DCI.DAG;
SDValue Op(N, 0);
-
unsigned Opc = Op.getOpcode();
+
+ if (DCI.isBeforeLegalizeOps())
+ return SDValue();
+
switch (Opc) {
case ISD::VSELECT: {
// (vselect (xor x, qtrue), v0, v1) -> (vselect x, v1, v0)
diff --git a/llvm/lib/Target/Hexagon/HexagonPatterns.td b/llvm/lib/Target/Hexagon/HexagonPatterns.td
index c3422d595c79..e9022f6d807e 100644
--- a/llvm/lib/Target/Hexagon/HexagonPatterns.td
+++ b/llvm/lib/Target/Hexagon/HexagonPatterns.td
@@ -229,6 +229,21 @@ def NegImm32: SDNodeXForm<imm, [{
return CurDAG->getTargetConstant(NV, SDLoc(N), MVT::i32);
}]>;
+def SplatB: SDNodeXForm<imm, [{
+ uint32_t V = N->getZExtValue();
+ assert(isUInt<8>(V) || V >> 8 == 0xFFFFFF);
+ uint32_t S = V << 24 | V << 16 | V << 8 | V;
+ V &= 0xFF;
+ return CurDAG->getTargetConstant(S, SDLoc(N), MVT::i32);
+}]>;
+
+def SplatH: SDNodeXForm<imm, [{
+ uint32_t V = N->getZExtValue();
+ assert(isUInt<16>(V) || V >> 16 == 0xFFFF);
+ V &= 0xFFFF;
+ return CurDAG->getTargetConstant(V << 16 | V, SDLoc(N), MVT::i32);
+}]>;
+
// Helpers for type promotions/contractions.
def I1toI32: OutPatFrag<(ops node:$Rs), (C2_muxii (i1 $Rs), 1, 0)>;
@@ -991,21 +1006,26 @@ def: Pat<(HexagonEXTRACTU I32:$Rs, I32:$Width, I32:$Off),
def: Pat<(HexagonEXTRACTU I64:$Rs, I32:$Width, I32:$Off),
(S2_extractup_rp I64:$Rs, (Combinew $Width, $Off))>;
-def SDTHexagonVSPLAT:
- SDTypeProfile<1, 1, [SDTCisVec<0>, SDTCisVT<1, i32>]>;
-
-def HexagonVSPLAT: SDNode<"HexagonISD::VSPLAT", SDTHexagonVSPLAT>;
-
-def: Pat<(v4i8 (HexagonVSPLAT I32:$Rs)), (S2_vsplatrb I32:$Rs)>;
-def: Pat<(v4i16 (HexagonVSPLAT I32:$Rs)), (S2_vsplatrh I32:$Rs)>;
-def: Pat<(v2i32 (HexagonVSPLAT s8_0ImmPred:$s8)),
+def: Pat<(v4i8 (splat_vector anyint:$V)), (ToI32 (SplatB $V))>;
+def: Pat<(v2i16 (splat_vector anyint:$V)), (ToI32 (SplatH $V))>;
+def: Pat<(v8i8 (splat_vector anyint:$V)),
+ (Combinew (ToI32 (SplatB $V)), (ToI32 (SplatB $V)))>;
+def: Pat<(v4i16 (splat_vector anyint:$V)),
+ (Combinew (ToI32 (SplatH $V)), (ToI32 (SplatH $V)))>;
+let AddedComplexity = 10 in
+def: Pat<(v2i32 (splat_vector s8_0ImmPred:$s8)),
(A2_combineii imm:$s8, imm:$s8)>;
-def: Pat<(v2i32 (HexagonVSPLAT I32:$Rs)), (Combinew I32:$Rs, I32:$Rs)>;
+def: Pat<(v2i32 (splat_vector anyimm:$V)), (Combinew (ToI32 $V), (ToI32 $V))>;
+
+def: Pat<(v4i8 (splat_vector I32:$Rs)), (S2_vsplatrb I32:$Rs)>;
+def: Pat<(v2i16 (splat_vector I32:$Rs)), (LoReg (S2_vsplatrh I32:$Rs))>;
+def: Pat<(v4i16 (splat_vector I32:$Rs)), (S2_vsplatrh I32:$Rs)>;
+def: Pat<(v2i32 (splat_vector I32:$Rs)), (Combinew I32:$Rs, I32:$Rs)>;
let AddedComplexity = 10 in
-def: Pat<(v8i8 (HexagonVSPLAT I32:$Rs)), (S6_vsplatrbp I32:$Rs)>,
+def: Pat<(v8i8 (splat_vector I32:$Rs)), (S6_vsplatrbp I32:$Rs)>,
Requires<[HasV62]>;
-def: Pat<(v8i8 (HexagonVSPLAT I32:$Rs)),
+def: Pat<(v8i8 (splat_vector I32:$Rs)),
(Combinew (S2_vsplatrb I32:$Rs), (S2_vsplatrb I32:$Rs))>;
@@ -1307,17 +1327,17 @@ def: OpR_RR_pat<S2_asr_r_vh, pf2<HexagonVASR>, v4i16, V4I16, I32>;
def: OpR_RR_pat<S2_lsr_r_vw, pf2<HexagonVLSR>, v2i32, V2I32, I32>;
def: OpR_RR_pat<S2_lsr_r_vh, pf2<HexagonVLSR>, v4i16, V4I16, I32>;
-def: Pat<(sra V2I32:$b, (v2i32 (HexagonVSPLAT u5_0ImmPred:$c))),
+def: Pat<(sra V2I32:$b, (v2i32 (splat_vector u5_0ImmPred:$c))),
(S2_asr_i_vw V2I32:$b, imm:$c)>;
-def: Pat<(srl V2I32:$b, (v2i32 (HexagonVSPLAT u5_0ImmPred:$c))),
+def: Pat<(srl V2I32:$b, (v2i32 (splat_vector u5_0ImmPred:$c))),
(S2_lsr_i_vw V2I32:$b, imm:$c)>;
-def: Pat<(shl V2I32:$b, (v2i32 (HexagonVSPLAT u5_0ImmPred:$c))),
+def: Pat<(shl V2I32:$b, (v2i32 (splat_vector u5_0ImmPred:$c))),
(S2_asl_i_vw V2I32:$b, imm:$c)>;
-def: Pat<(sra V4I16:$b, (v4i16 (HexagonVSPLAT u4_0ImmPred:$c))),
+def: Pat<(sra V4I16:$b, (v4i16 (splat_vector u4_0ImmPred:$c))),
(S2_asr_i_vh V4I16:$b, imm:$c)>;
-def: Pat<(srl V4I16:$b, (v4i16 (HexagonVSPLAT u4_0ImmPred:$c))),
+def: Pat<(srl V4I16:$b, (v4i16 (splat_vector u4_0ImmPred:$c))),
(S2_lsr_i_vh V4I16:$b, imm:$c)>;
-def: Pat<(shl V4I16:$b, (v4i16 (HexagonVSPLAT u4_0ImmPred:$c))),
+def: Pat<(shl V4I16:$b, (v4i16 (splat_vector u4_0ImmPred:$c))),
(S2_asl_i_vh V4I16:$b, imm:$c)>;
def: Pat<(HexagonVASR V2I16:$Rs, u4_0ImmPred:$S),
diff --git a/llvm/lib/Target/Hexagon/HexagonPatternsHVX.td b/llvm/lib/Target/Hexagon/HexagonPatternsHVX.td
index 135c493e49be..b60326ad8fbf 100644
--- a/llvm/lib/Target/Hexagon/HexagonPatternsHVX.td
+++ b/llvm/lib/Target/Hexagon/HexagonPatternsHVX.td
@@ -33,7 +33,6 @@ def Combineq: OutPatFrag<(ops node:$Qs, node:$Qt),
def LoVec: OutPatFrag<(ops node:$Vs), (EXTRACT_SUBREG $Vs, vsub_lo)>;
def HiVec: OutPatFrag<(ops node:$Vs), (EXTRACT_SUBREG $Vs, vsub_hi)>;
-def HexagonVZERO: SDNode<"HexagonISD::VZERO", SDTVecLeaf>;
def HexagonQCAT: SDNode<"HexagonISD::QCAT", SDTVecBinOp>;
def HexagonQTRUE: SDNode<"HexagonISD::QTRUE", SDTVecLeaf>;
def HexagonQFALSE: SDNode<"HexagonISD::QFALSE", SDTVecLeaf>;
@@ -41,7 +40,7 @@ def HexagonVPACKL: SDNode<"HexagonISD::VPACKL", SDTVecUnaryOp>;
def HexagonVUNPACK: SDNode<"HexagonISD::VUNPACK", SDTVecUnaryOp>;
def HexagonVUNPACKU: SDNode<"HexagonISD::VUNPACKU", SDTVecUnaryOp>;
-def vzero: PatFrag<(ops), (HexagonVZERO)>;
+def vzero: PatFrag<(ops), (splat_vector (i32 0))>;
def qtrue: PatFrag<(ops), (HexagonQTRUE)>;
def qfalse: PatFrag<(ops), (HexagonQFALSE)>;
def qcat: PatFrag<(ops node:$Qs, node:$Qt),
@@ -57,19 +56,6 @@ def VSxth: OutPatFrag<(ops node:$Vs), (V6_vunpackh $Vs)>;
def VZxtb: OutPatFrag<(ops node:$Vs), (V6_vunpackub $Vs)>;
def VZxth: OutPatFrag<(ops node:$Vs), (V6_vunpackuh $Vs)>;
-def SplatB: SDNodeXForm<imm, [{
- uint32_t V = N->getZExtValue();
- assert(isUInt<8>(V));
- uint32_t S = V << 24 | V << 16 | V << 8 | V;
- return CurDAG->getTargetConstant(S, SDLoc(N), MVT::i32);
-}]>;
-
-def SplatH: SDNodeXForm<imm, [{
- uint32_t V = N->getZExtValue();
- assert(isUInt<16>(V));
- return CurDAG->getTargetConstant(V << 16 | V, SDLoc(N), MVT::i32);
-}]>;
-
def IsVecOff : PatLeaf<(i32 imm), [{
int32_t V = N->getSExtValue();
int32_t VecSize = HRI->getSpillSize(Hexagon::HvxVRRegClass);
@@ -226,23 +212,23 @@ def Rep: OutPatFrag<(ops node:$N), (Combinev $N, $N)>;
let Predicates = [UseHVX] in {
let AddedComplexity = 10 in {
- 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 (splat_vector u8_0ImmPred:$V)), (Vsplatib $V)>;
+ def: Pat<(VecI16 (splat_vector u16_0ImmPred:$V)), (Vsplatih $V)>;
+ def: Pat<(VecI32 (splat_vector anyimm:$V)), (Vsplatiw $V)>;
+ def: Pat<(VecPI8 (splat_vector u8_0ImmPred:$V)), (Rep (Vsplatib $V))>;
+ def: Pat<(VecPI16 (splat_vector u16_0ImmPred:$V)), (Rep (Vsplatih $V))>;
+ def: Pat<(VecPI32 (splat_vector anyimm:$V)), (Rep (Vsplatiw $V))>;
}
- 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 (splat_vector I32:$Rs)), (Vsplatrb $Rs)>;
+ def: Pat<(VecI16 (splat_vector I32:$Rs)), (Vsplatrh $Rs)>;
+ def: Pat<(VecI32 (splat_vector I32:$Rs)), (Vsplatrw $Rs)>;
+ def: Pat<(VecPI8 (splat_vector I32:$Rs)), (Rep (Vsplatrb $Rs))>;
+ def: Pat<(VecPI16 (splat_vector I32:$Rs)), (Rep (Vsplatrh $Rs))>;
+ def: Pat<(VecPI32 (splat_vector I32:$Rs)), (Rep (Vsplatrw $Rs))>;
}
class Vneg1<ValueType VecTy>
- : PatFrag<(ops), (VecTy (HexagonVSPLAT (i32 -1)))>;
+ : PatFrag<(ops), (VecTy (splat_vector (i32 -1)))>;
class Vnot<ValueType VecTy>
: PatFrag<(ops node:$Vs), (xor $Vs, Vneg1<VecTy>)>;
diff --git a/llvm/test/CodeGen/Hexagon/isel-splat-vector-crash.ll b/llvm/test/CodeGen/Hexagon/isel-splat-vector-crash.ll
new file mode 100644
index 000000000000..f58eca3446d3
--- /dev/null
+++ b/llvm/test/CodeGen/Hexagon/isel-splat-vector-crash.ll
@@ -0,0 +1,32 @@
+; RUN: llc -march=hexagon < %s | FileCheck %s
+
+; Check that this doesn't crash.
+; CHECK: vmemu
+
+target datalayout = "e-m:e-p:32:32:32-a:0-n16:32-i64:64:64-i32:32:32-i16:16:16-i1:8:8-f32:32:32-f64:64:64-v32:32:32-v64:64:64-v512:512:512-v1024:1024:1024-v2048:2048:2048"
+target triple = "hexagon"
+
+define dso_local void @f0(i16* %a0) local_unnamed_addr #0 {
+b0:
+ %v0 = getelementptr inbounds i16, i16* %a0, i32 undef
+ %v1 = load <64 x i16>, <64 x i16>* undef, align 2
+ %v2 = shufflevector <64 x i16> %v1, <64 x i16> undef, <8 x i32> <i32 2, i32 10, i32 18, i32 26, i32 34, i32 42, i32 50, i32 58>
+ %v3 = shufflevector <64 x i16> %v1, <64 x i16> undef, <8 x i32> <i32 6, i32 14, i32 22, i32 30, i32 38, i32 46, i32 54, i32 62>
+ %v4 = sext <8 x i16> %v2 to <8 x i32>
+ %v5 = mul nsw <8 x i32> %v4, <i32 60548, i32 60548, i32 60548, i32 60548, i32 60548, i32 60548, i32 60548, i32 60548>
+ %v6 = sext <8 x i16> %v3 to <8 x i32>
+ %v7 = mul nsw <8 x i32> %v6, <i32 25080, i32 25080, i32 25080, i32 25080, i32 25080, i32 25080, i32 25080, i32 25080>
+ %v8 = add nsw <8 x i32> %v5, <i32 32768, i32 32768, i32 32768, i32 32768, i32 32768, i32 32768, i32 32768, i32 32768>
+ %v9 = add <8 x i32> %v8, %v7
+ %v10 = ashr <8 x i32> %v9, <i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16>
+ %v11 = add nsw <8 x i32> %v10, zeroinitializer
+ %v12 = shl <8 x i32> %v11, <i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16>
+ %v13 = ashr exact <8 x i32> %v12, <i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16>
+ %v14 = add nsw <8 x i32> zeroinitializer, %v13
+ %v15 = trunc <8 x i32> %v14 to <8 x i16>
+ %v16 = extractelement <8 x i16> %v15, i32 0
+ store i16 %v16, i16* %v0, align 2
+ ret void
+}
+
+attributes #0 = { "target-features"="+v66,+hvxv66,+hvx,+hvx-length64b" }
diff --git a/llvm/test/CodeGen/Hexagon/isel-splat-vector-dag-crash.ll b/llvm/test/CodeGen/Hexagon/isel-splat-vector-dag-crash.ll
new file mode 100644
index 000000000000..2b1fe2dd6fd8
--- /dev/null
+++ b/llvm/test/CodeGen/Hexagon/isel-splat-vector-dag-crash.ll
@@ -0,0 +1,30 @@
+; RUN: llc -march=hexagon < %s | FileCheck %s
+
+; This used to crash because SelectionDAG::isSplatValue did not set UndefElts
+; for ISD::SPLAT_VECTOR.
+; CHECK: vmemu
+
+target datalayout = "e-m:e-p:32:32:32-a:0-n16:32-i64:64:64-i32:32:32-i16:16:16-i1:8:8-f32:32:32-f64:64:64-v32:32:32-v64:64:64-v512:512:512-v1024:1024:1024-v2048:2048:2048"
+target triple = "hexagon"
+
+define dso_local void @f0(i16* %a0) local_unnamed_addr #0 {
+b0:
+ %v0 = getelementptr inbounds i16, i16* %a0, i32 undef
+ %v1 = load <64 x i16>, <64 x i16>* undef, align 2
+ %v2 = shufflevector <64 x i16> %v1, <64 x i16> undef, <8 x i32> <i32 3, i32 11, i32 19, i32 27, i32 35, i32 43, i32 51, i32 59>
+ %v3 = sext <8 x i16> %v2 to <8 x i32>
+ %v4 = mul nsw <8 x i32> %v3, <i32 54492, i32 54492, i32 54492, i32 54492, i32 54492, i32 54492, i32 54492, i32 54492>
+ %v5 = add nsw <8 x i32> %v4, <i32 32768, i32 32768, i32 32768, i32 32768, i32 32768, i32 32768, i32 32768, i32 32768>
+ %v6 = add <8 x i32> %v5, zeroinitializer
+ %v7 = ashr <8 x i32> %v6, <i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16>
+ %v8 = add nsw <8 x i32> zeroinitializer, %v7
+ %v9 = shl <8 x i32> %v8, <i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16>
+ %v10 = ashr exact <8 x i32> %v9, <i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16>
+ %v11 = add nsw <8 x i32> %v10, zeroinitializer
+ %v12 = trunc <8 x i32> %v11 to <8 x i16>
+ %v13 = extractelement <8 x i16> %v12, i32 0
+ store i16 %v13, i16* %v0, align 2
+ ret void
+}
+
+attributes #0 = { "target-cpu"="hexagonv60" "target-features"="+hvx,+hvx-length128b" }
diff --git a/llvm/test/CodeGen/Hexagon/vect/vect-cst-v4i32.ll b/llvm/test/CodeGen/Hexagon/vect/vect-cst-v4i32.ll
index 12f9e00f0d06..41dfd4d40fe3 100644
--- a/llvm/test/CodeGen/Hexagon/vect/vect-cst-v4i32.ll
+++ b/llvm/test/CodeGen/Hexagon/vect/vect-cst-v4i32.ll
@@ -1,7 +1,4 @@
-; XFAIL: *
-; Extract selecting of a constant into a generic utility function.
-;
-; RUN: llc -march=hexagon -mcpu=hexagonv5 -disable-hsdr < %s | FileCheck %s
+; RUN: llc -march=hexagon < %s | FileCheck %s
; This one should generate a combine with two immediates.
; CHECK: combine(#7,#7)
@B = common global [400 x i32] zeroinitializer, align 8
diff --git a/llvm/test/CodeGen/Hexagon/vect/vect-vsplath.ll b/llvm/test/CodeGen/Hexagon/vect/vect-vsplath.ll
index db90bf42be2a..2f6897c32809 100644
--- a/llvm/test/CodeGen/Hexagon/vect/vect-vsplath.ll
+++ b/llvm/test/CodeGen/Hexagon/vect/vect-vsplath.ll
@@ -1,6 +1,9 @@
-; RUN: llc -march=hexagon -disable-hcp < %s | FileCheck %s
-; Make sure we build the constant vector <7, 7, 7, 7> with a vsplath.
-; CHECK: vsplath
+; RUN: llc -march=hexagon < %s | FileCheck %s
+
+; Actually, don't use vsplath.
+
+; CHECK: r[[R0:[0-9]+]] = ##458759
+; CHECK: vmpyh(r{{[0-9]+}},r[[R0]])
@B = common global [400 x i16] zeroinitializer, align 8
@A = common global [400 x i16] zeroinitializer, align 8
@C = common global [400 x i16] zeroinitializer, align 8
More information about the llvm-commits
mailing list