Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 51 additions & 0 deletions llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2319,6 +2319,53 @@ static SDValue lowerVECTOR_SHUFFLE_XVPICKOD(const SDLoc &DL, ArrayRef<int> Mask,
return DAG.getNode(LoongArchISD::VPICKOD, DL, VT, V2, V1);
}

/// Lower VECTOR_SHUFFLE into XVINSVE0 (if possible).
static SDValue
lowerVECTOR_SHUFFLE_XVINSVE0(const SDLoc &DL, ArrayRef<int> Mask, MVT VT,
SDValue V1, SDValue V2, SelectionDAG &DAG,
const LoongArchSubtarget &Subtarget) {
// LoongArch LASX only supports xvinsve0.{w/d}.
if (VT != MVT::v8i32 && VT != MVT::v8f32 && VT != MVT::v4i64 &&
VT != MVT::v4f64)
return SDValue();

MVT GRLenVT = Subtarget.getGRLenVT();
int MaskSize = Mask.size();
assert(MaskSize == (int)VT.getVectorNumElements() && "Unexpected mask size");

// Check if exactly one element of the Mask is replaced by 'Replaced', while
// all other elements are either 'Base + i' or undef (-1). On success, return
// the index of the replaced element. Otherwise, just return -1.
auto checkReplaceOne = [&](int Base, int Replaced) -> int {
int Idx = -1;
for (int i = 0; i < MaskSize; ++i) {
if (Mask[i] == Base + i || Mask[i] == -1)
continue;
if (Mask[i] != Replaced)
return -1;
if (Idx == -1)
Idx = i;
else
return -1;
}
return Idx;
};

// Case 1: the lowest element of V2 replaces one element in V1.
int Idx = checkReplaceOne(0, MaskSize);
if (Idx != -1)
return DAG.getNode(LoongArchISD::XVINSVE0, DL, VT, V1, V2,
DAG.getConstant(Idx, DL, GRLenVT));

// Case 2: the lowest element of V1 replaces one element in V2.
Idx = checkReplaceOne(MaskSize, 0);
if (Idx != -1)
return DAG.getNode(LoongArchISD::XVINSVE0, DL, VT, V2, V1,
DAG.getConstant(Idx, DL, GRLenVT));

return SDValue();
}

/// Lower VECTOR_SHUFFLE into XVSHUF (if possible).
static SDValue lowerVECTOR_SHUFFLE_XVSHUF(const SDLoc &DL, ArrayRef<int> Mask,
MVT VT, SDValue V1, SDValue V2,
Expand Down Expand Up @@ -2595,6 +2642,9 @@ static SDValue lower256BitShuffle(const SDLoc &DL, ArrayRef<int> Mask, MVT VT,
if ((Result = lowerVECTOR_SHUFFLEAsShift(DL, Mask, VT, V1, V2, DAG, Subtarget,
Zeroable)))
return Result;
if ((Result =
lowerVECTOR_SHUFFLE_XVINSVE0(DL, Mask, VT, V1, V2, DAG, Subtarget)))
return Result;
if ((Result = lowerVECTOR_SHUFFLEAsByteRotate(DL, Mask, VT, V1, V2, DAG,
Subtarget)))
return Result;
Expand Down Expand Up @@ -7453,6 +7503,7 @@ const char *LoongArchTargetLowering::getTargetNodeName(unsigned Opcode) const {
NODE_NAME_CASE(XVPERM)
NODE_NAME_CASE(XVREPLVE0)
NODE_NAME_CASE(XVREPLVE0Q)
NODE_NAME_CASE(XVINSVE0)
NODE_NAME_CASE(VPICK_SEXT_ELT)
NODE_NAME_CASE(VPICK_ZEXT_ELT)
NODE_NAME_CASE(VREPLVE)
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/Target/LoongArch/LoongArchISelLowering.h
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ enum NodeType : unsigned {
XVPERM,
XVREPLVE0,
XVREPLVE0Q,
XVINSVE0,

// Extended vector element extraction
VPICK_SEXT_ELT,
Expand Down
9 changes: 9 additions & 0 deletions llvm/lib/Target/LoongArch/LoongArchLASXInstrInfo.td
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ def loongarch_xvpermi: SDNode<"LoongArchISD::XVPERMI", SDT_LoongArchV1RUimm>;
def loongarch_xvperm: SDNode<"LoongArchISD::XVPERM", SDT_LoongArchXVPERM>;
def loongarch_xvreplve0: SDNode<"LoongArchISD::XVREPLVE0", SDT_LoongArchXVREPLVE0>;
def loongarch_xvreplve0q: SDNode<"LoongArchISD::XVREPLVE0Q", SDT_LoongArchXVREPLVE0>;
def loongarch_xvinsve0 : SDNode<"LoongArchISD::XVINSVE0", SDT_LoongArchV2RUimm>;
def loongarch_xvmskltz: SDNode<"LoongArchISD::XVMSKLTZ", SDT_LoongArchVMSKCOND>;
def loongarch_xvmskgez: SDNode<"LoongArchISD::XVMSKGEZ", SDT_LoongArchVMSKCOND>;
def loongarch_xvmskeqz: SDNode<"LoongArchISD::XVMSKEQZ", SDT_LoongArchVMSKCOND>;
Expand Down Expand Up @@ -1708,6 +1709,14 @@ def : Pat<(vector_insert v4f64:$xd, (f64(bitconvert i64:$rj)), uimm2:$imm),
(XVINSGR2VR_D v4f64:$xd, GPR:$rj, uimm2:$imm)>;

// XVINSVE0_{W/D}
def : Pat<(loongarch_xvinsve0 v8i32:$xd, v8i32:$xj, uimm3:$imm),
(XVINSVE0_W v8i32:$xd, v8i32:$xj, uimm3:$imm)>;
def : Pat<(loongarch_xvinsve0 v4i64:$xd, v4i64:$xj, uimm2:$imm),
(XVINSVE0_D v4i64:$xd, v4i64:$xj, uimm2:$imm)>;
def : Pat<(loongarch_xvinsve0 v8f32:$xd, v8f32:$xj, uimm3:$imm),
(XVINSVE0_W v8f32:$xd, v8f32:$xj, uimm3:$imm)>;
def : Pat<(loongarch_xvinsve0 v4f64:$xd, v4f64:$xj, uimm2:$imm),
(XVINSVE0_D v4f64:$xd, v4f64:$xj, uimm2:$imm)>;
def : Pat<(vector_insert v8f32:$xd, FPR32:$fj, uimm3:$imm),
(XVINSVE0_W v8f32:$xd, (SUBREG_TO_REG(i64 0), FPR32:$fj, sub_32),
uimm3:$imm)>;
Expand Down
Loading