[llvm-branch-commits] [llvm] [LoongArch] Add DAG combine for horizontal widening add/sub (PR #201488)
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Tue Jun 16 01:49:25 PDT 2026
https://github.com/heiher updated https://github.com/llvm/llvm-project/pull/201488
>From 6d12916c9d1675b23f4615ae88f7b3e11c64761b Mon Sep 17 00:00:00 2001
From: WANG Rui <wangrui at loongson.cn>
Date: Fri, 29 May 2026 16:35:12 +0800
Subject: [PATCH 1/2] [LoongArch] Add DAG combine for horizontal widening
add/sub
Add a DAG combine to recognize horizontal widening add/subtract patterns
and lower them to the corresponding LSX/LASX instructions.
The following pattern is matched for both signed and unsigned variants:
```
ADD/SUB(SEXT/ZEXT(BUILD_VECTOR(extract_elt(vj, 1), extract_elt(vj, 3), ...)),
SEXT/ZEXT(BUILD_VECTOR(extract_elt(vk, 0), extract_elt(vk, 2), ...)))
```
This covers the following instructions:
```
LSX: VHADDW.H.B, VHADDW.W.H, VHADDW.D.W
VHADDW.HU.BU, VHADDW.WU.HU, VHADDW.DU.WU
VHSUBW.H.B, VHSUBW.W.H, VHSUBW.D.W
VHSUBW.HU.BU, VHSUBW.WU.HU, VHSUBW.DU.WU
LASX: XVHADDW.H.B, XVHADDW.W.H, XVHADDW.D.W
XVHADDW.HU.BU, XVHADDW.WU.HU, XVHADDW.DU.WU
XVHSUBW.H.B, XVHSUBW.W.H, XVHSUBW.D.W
XVHSUBW.HU.BU, XVHSUBW.WU.HU, XVHSUBW.DU.WU
```
The Q_D variants (VHADDW.Q.D, VHSUBW.Q.D and their unsigned counterparts)
are not handled here because the result type v1i128 is not yet legalized
in the backend.
---
.../LoongArch/LoongArchISelLowering.cpp | 119 ++++++++++++++++++
.../LoongArch/LoongArchLASXInstrInfo.td | 28 ++++-
.../Target/LoongArch/LoongArchLSXInstrInfo.td | 36 +++++-
3 files changed, 174 insertions(+), 9 deletions(-)
diff --git a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
index 561064b3e1090..1b2258df77fa1 100644
--- a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
+++ b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
@@ -509,6 +509,7 @@ LoongArchTargetLowering::LoongArchTargetLowering(const TargetMachine &TM,
if (Subtarget.hasExtLSX()) {
setTargetDAGCombine(ISD::ADD);
+ setTargetDAGCombine(ISD::SUB);
setTargetDAGCombine(ISD::INTRINSIC_WO_CHAIN);
setTargetDAGCombine(ISD::BITCAST);
setTargetDAGCombine(ISD::VSELECT);
@@ -1045,7 +1046,9 @@ SDValue LoongArchTargetLowering::lowerVECREDUCE_ADD(SDValue Op,
LegalVecSize = 256;
}
+ EleBits *= 2;
for (unsigned i = 1; i < NumEles; i *= 2, EleBits *= 2) {
+ EleBits = std::min(EleBits, 64u);
MVT IntTy = MVT::getIntegerVT(EleBits);
MVT VecTy = MVT::getVectorVT(IntTy, LegalVecSize / EleBits);
Val = DAG.getNode(LoongArchISD::VHADDW, DL, VecTy, Val, Val);
@@ -5907,9 +5910,114 @@ static bool isConstantSplatVector(SDValue N, APInt &SplatValue,
/*IsBigEndian=*/false);
}
+static SDValue matchDeinterleaveBuildVector(SDValue N, unsigned &StartIndex) {
+ auto *BV = dyn_cast<BuildVectorSDNode>(N);
+ if (!BV)
+ return SDValue();
+
+ SDValue Src;
+ int Start = -1;
+
+ for (unsigned i = 0, NumElts = BV->getNumOperands(); i < NumElts; ++i) {
+ SDValue Op = BV->getOperand(i);
+ if (Op.isUndef())
+ continue;
+ if (Op.getOpcode() != ISD::EXTRACT_VECTOR_ELT)
+ return SDValue();
+
+ auto *IdxC = dyn_cast<ConstantSDNode>(Op.getOperand(1));
+ if (!IdxC)
+ return SDValue();
+
+ unsigned EltIdx = IdxC->getZExtValue();
+ if (Start < 0)
+ Start = (int)EltIdx - (int)(i * 2);
+ if (Start < 0 || Start > 1 || EltIdx != (unsigned)(Start + (int)(i * 2)))
+ return SDValue();
+
+ SDValue CurSrc = Op.getOperand(0);
+ if (!Src)
+ Src = CurSrc;
+ else if (Src != CurSrc)
+ return SDValue();
+ }
+
+ if (!Src || Start < 0)
+ return SDValue();
+
+ StartIndex = (unsigned)Start;
+ return Src;
+}
+
+static SDValue
+performHorizWideningCombine(SDNode *N, SelectionDAG &DAG,
+ const LoongArchSubtarget &Subtarget) {
+ if (!Subtarget.hasExtLSX())
+ return SDValue();
+
+ unsigned Opc = N->getOpcode();
+ assert((Opc == ISD::ADD || Opc == ISD::SUB) && "Unexpected opcode");
+
+ EVT VT = N->getValueType(0);
+ SDLoc DL(N);
+
+ SDValue LHS = N->getOperand(0);
+ SDValue RHS = N->getOperand(1);
+
+ bool isSigned;
+ unsigned ExtOpc = LHS.getOpcode();
+ if (ExtOpc == ISD::SIGN_EXTEND)
+ isSigned = true;
+ else if (ExtOpc == ISD::ZERO_EXTEND)
+ isSigned = false;
+ else
+ return SDValue();
+
+ if (ExtOpc != RHS.getOpcode())
+ return SDValue();
+
+ if (!LHS.hasOneUse() || !RHS.hasOneUse())
+ return SDValue();
+
+ unsigned OddIdx, EvenIdx;
+ SDValue LHSVec = matchDeinterleaveBuildVector(LHS.getOperand(0), OddIdx);
+ SDValue RHSVec = matchDeinterleaveBuildVector(RHS.getOperand(0), EvenIdx);
+
+ if (!LHSVec || !RHSVec)
+ return SDValue();
+ if (OddIdx != 1 || EvenIdx != 0)
+ return SDValue();
+ if (LHSVec.getValueType() != RHSVec.getValueType())
+ return SDValue();
+
+ EVT SrcVT = LHSVec.getValueType();
+ EVT SrcEltVT = SrcVT.getVectorElementType();
+ EVT DstEltVT = VT.getVectorElementType();
+
+ if (!SrcVT.isVector() || !VT.isVector())
+ return SDValue();
+ if (SrcVT.getSizeInBits() != VT.getSizeInBits())
+ return SDValue();
+ if (DstEltVT.getSizeInBits() != SrcEltVT.getSizeInBits() * 2)
+ return SDValue();
+ if (!SrcEltVT.isInteger() || SrcEltVT.getSizeInBits() > 32)
+ return SDValue();
+
+ unsigned TargetOpc;
+ if (Opc == ISD::ADD)
+ TargetOpc = isSigned ? LoongArchISD::VHADDW : LoongArchISD::VHADDW_U;
+ else
+ TargetOpc = isSigned ? LoongArchISD::VHSUBW : LoongArchISD::VHSUBW_U;
+
+ return DAG.getNode(TargetOpc, DL, VT, LHSVec, RHSVec);
+}
+
static SDValue performADDCombine(SDNode *N, SelectionDAG &DAG,
TargetLowering::DAGCombinerInfo &DCI,
const LoongArchSubtarget &Subtarget) {
+ if (SDValue V = performHorizWideningCombine(N, DAG, Subtarget))
+ return V;
+
if (DCI.isBeforeLegalizeOps())
return SDValue();
@@ -6159,6 +6267,15 @@ static SDValue performSRLCombine(SDNode *N, SelectionDAG &DAG,
return SDValue();
}
+static SDValue performSUBCombine(SDNode *N, SelectionDAG &DAG,
+ TargetLowering::DAGCombinerInfo &DCI,
+ const LoongArchSubtarget &Subtarget) {
+ if (SDValue V = performHorizWideningCombine(N, DAG, Subtarget))
+ return V;
+
+ return SDValue();
+}
+
// Helper to peek through bitops/trunc/setcc to determine size of source vector.
// Allows BITCASTCombine to determine what size vector generated a <X x i1>.
static bool checkBitcastSrcVectorSize(SDValue Src, unsigned Size,
@@ -8061,6 +8178,8 @@ SDValue LoongArchTargetLowering::PerformDAGCombine(SDNode *N,
return performSETCCCombine(N, DAG, DCI, Subtarget);
case ISD::SRL:
return performSRLCombine(N, DAG, DCI, Subtarget);
+ case ISD::SUB:
+ return performSUBCombine(N, DAG, DCI, Subtarget);
case ISD::BITCAST:
return performBITCASTCombine(N, DAG, DCI, Subtarget);
case ISD::ANY_EXTEND:
diff --git a/llvm/lib/Target/LoongArch/LoongArchLASXInstrInfo.td b/llvm/lib/Target/LoongArch/LoongArchLASXInstrInfo.td
index 0fb2b1d332f60..24a03d592dc92 100644
--- a/llvm/lib/Target/LoongArch/LoongArchLASXInstrInfo.td
+++ b/llvm/lib/Target/LoongArch/LoongArchLASXInstrInfo.td
@@ -1213,16 +1213,27 @@ multiclass PatXrXrXr<SDPatternOperator OpNode, string Inst> {
}
multiclass PatXrXrW<SDPatternOperator OpNode, string Inst> {
- def : Pat<(OpNode(v32i8 LASX256:$vj), (v32i8 LASX256:$vk)),
+ def : Pat<(v16i16 (OpNode(v32i8 LASX256:$vj), (v32i8 LASX256:$vk))),
(!cast<LAInst>(Inst#"_H_B") LASX256:$vj, LASX256:$vk)>;
- def : Pat<(OpNode(v16i16 LASX256:$vj), (v16i16 LASX256:$vk)),
+ def : Pat<(v8i32 (OpNode(v16i16 LASX256:$vj), (v16i16 LASX256:$vk))),
(!cast<LAInst>(Inst#"_W_H") LASX256:$vj, LASX256:$vk)>;
- def : Pat<(OpNode(v8i32 LASX256:$vj), (v8i32 LASX256:$vk)),
+ def : Pat<(v4i64 (OpNode(v8i32 LASX256:$vj), (v8i32 LASX256:$vk))),
(!cast<LAInst>(Inst#"_D_W") LASX256:$vj, LASX256:$vk)>;
- def : Pat<(OpNode(v4i64 LASX256:$vj), (v4i64 LASX256:$vk)),
+ def : Pat<(v4i64 (OpNode(v4i64 LASX256:$vj), (v4i64 LASX256:$vk))),
(!cast<LAInst>(Inst#"_Q_D") LASX256:$vj, LASX256:$vk)>;
}
+multiclass PatXrXrWU<SDPatternOperator OpNode, string Inst> {
+ def : Pat<(v16i16 (OpNode(v32i8 LASX256:$vj), (v32i8 LASX256:$vk))),
+ (!cast<LAInst>(Inst#"_HU_BU") LASX256:$vj, LASX256:$vk)>;
+ def : Pat<(v8i32 (OpNode(v16i16 LASX256:$vj), (v16i16 LASX256:$vk))),
+ (!cast<LAInst>(Inst#"_WU_HU") LASX256:$vj, LASX256:$vk)>;
+ def : Pat<(v4i64 (OpNode(v8i32 LASX256:$vj), (v8i32 LASX256:$vk))),
+ (!cast<LAInst>(Inst#"_DU_WU") LASX256:$vj, LASX256:$vk)>;
+ def : Pat<(v4i64 (OpNode(v4i64 LASX256:$vj), (v4i64 LASX256:$vk))),
+ (!cast<LAInst>(Inst#"_QU_DU") LASX256:$vj, LASX256:$vk)>;
+}
+
multiclass PatShiftXrXr<SDPatternOperator OpNode, string Inst> {
def : Pat<(OpNode (v32i8 LASX256:$xj), (and vsplati8_imm_eq_7,
(v32i8 LASX256:$xk))),
@@ -1634,6 +1645,15 @@ def : Pat<(bswap (v4i64 LASX256:$xj)),
// XVHADDW_{H_B/W_H/D_W/Q_D}
defm : PatXrXrW<loongarch_vhaddw, "XVHADDW">;
+// XVHADDW_{HU_BU/WU_HU/DU_WU/QU_DU}
+defm : PatXrXrWU<loongarch_vhaddw_u, "XVHADDW">;
+
+// XVHSUBW_{H_B/W_H/D_W/Q_D}
+defm : PatXrXrW<loongarch_vhsubw, "XVHSUBW">;
+
+// XVHSUBW_{HU_BU/WU_HU/DU_WU/QU_DU}
+defm : PatXrXrWU<loongarch_vhsubw_u, "XVHSUBW">;
+
// XVFADD_{S/D}
defm : PatXrXrF<fadd, "XVFADD">;
diff --git a/llvm/lib/Target/LoongArch/LoongArchLSXInstrInfo.td b/llvm/lib/Target/LoongArch/LoongArchLSXInstrInfo.td
index 34d4e2435b39d..21861378cbb3d 100644
--- a/llvm/lib/Target/LoongArch/LoongArchLSXInstrInfo.td
+++ b/llvm/lib/Target/LoongArch/LoongArchLSXInstrInfo.td
@@ -27,6 +27,7 @@ def SDT_LoongArchV2RUimm
: SDTypeProfile<1, 3,
[SDTCisVec<0>, SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>,
SDTCisVT<3, GRLenVT>]>;
+def SDT_LoongArchVHW : SDTypeProfile<1, 2, [SDTCisVec<0>, SDTCisVec<1>, SDTCisSameAs<1, 2>]>;
def SDT_LoongArchVreplgr2vr : SDTypeProfile<1, 1, [SDTCisInt<0>, SDTCisVec<0>, SDTCisInt<1>]>;
def SDT_LoongArchVFRECIPE : SDTypeProfile<1, 1, [SDTCisFP<0>, SDTCisVec<0>, SDTCisSameAs<0, 1>]>;
def SDT_LoongArchVFRSQRTE : SDTypeProfile<1, 1, [SDTCisFP<0>, SDTCisVec<0>, SDTCisSameAs<0, 1>]>;
@@ -86,7 +87,12 @@ def loongarch_vbsll : SDNode<"LoongArchISD::VBSLL", SDT_LoongArchV1RUimm>;
def loongarch_vbsrl : SDNode<"LoongArchISD::VBSRL", SDT_LoongArchV1RUimm>;
// Vector Horizontal Addition with Widening
-def loongarch_vhaddw : SDNode<"LoongArchISD::VHADDW", SDT_LoongArchV2R>;
+def loongarch_vhaddw : SDNode<"LoongArchISD::VHADDW", SDT_LoongArchVHW>;
+def loongarch_vhaddw_u : SDNode<"LoongArchISD::VHADDW_U", SDT_LoongArchVHW>;
+
+// Vector Horizontal Subtration with Widening
+def loongarch_vhsubw : SDNode<"LoongArchISD::VHSUBW", SDT_LoongArchVHW>;
+def loongarch_vhsubw_u : SDNode<"LoongArchISD::VHSUBW_U", SDT_LoongArchVHW>;
// Scalar load broadcast to vector
def loongarch_vldrepl
@@ -1439,16 +1445,27 @@ multiclass PatVrVrVr<SDPatternOperator OpNode, string Inst> {
}
multiclass PatVrVrW<SDPatternOperator OpNode, string Inst> {
- def : Pat<(OpNode(v16i8 LSX128:$vj), (v16i8 LSX128:$vk)),
+ def : Pat<(v8i16 (OpNode(v16i8 LSX128:$vj), (v16i8 LSX128:$vk))),
(!cast<LAInst>(Inst#"_H_B") LSX128:$vj, LSX128:$vk)>;
- def : Pat<(OpNode(v8i16 LSX128:$vj), (v8i16 LSX128:$vk)),
+ def : Pat<(v4i32 (OpNode(v8i16 LSX128:$vj), (v8i16 LSX128:$vk))),
(!cast<LAInst>(Inst#"_W_H") LSX128:$vj, LSX128:$vk)>;
- def : Pat<(OpNode(v4i32 LSX128:$vj), (v4i32 LSX128:$vk)),
+ def : Pat<(v2i64 (OpNode(v4i32 LSX128:$vj), (v4i32 LSX128:$vk))),
(!cast<LAInst>(Inst#"_D_W") LSX128:$vj, LSX128:$vk)>;
- def : Pat<(OpNode(v2i64 LSX128:$vj), (v2i64 LSX128:$vk)),
+ def : Pat<(v2i64 (OpNode(v2i64 LSX128:$vj), (v2i64 LSX128:$vk))),
(!cast<LAInst>(Inst#"_Q_D") LSX128:$vj, LSX128:$vk)>;
}
+multiclass PatVrVrWU<SDPatternOperator OpNode, string Inst> {
+ def : Pat<(v8i16 (OpNode(v16i8 LSX128:$vj), (v16i8 LSX128:$vk))),
+ (!cast<LAInst>(Inst#"_HU_BU") LSX128:$vj, LSX128:$vk)>;
+ def : Pat<(v4i32 (OpNode(v8i16 LSX128:$vj), (v8i16 LSX128:$vk))),
+ (!cast<LAInst>(Inst#"_WU_HU") LSX128:$vj, LSX128:$vk)>;
+ def : Pat<(v2i64 (OpNode(v4i32 LSX128:$vj), (v4i32 LSX128:$vk))),
+ (!cast<LAInst>(Inst#"_DU_WU") LSX128:$vj, LSX128:$vk)>;
+ def : Pat<(v2i64 (OpNode(v2i64 LSX128:$vj), (v2i64 LSX128:$vk))),
+ (!cast<LAInst>(Inst#"_QU_DU") LSX128:$vj, LSX128:$vk)>;
+}
+
multiclass PatShiftVrVr<SDPatternOperator OpNode, string Inst> {
def : Pat<(OpNode (v16i8 LSX128:$vj), (and vsplati8_imm_eq_7,
(v16i8 LSX128:$vk))),
@@ -1878,6 +1895,15 @@ def : Pat<(bswap (v2i64 LSX128:$vj)),
// VHADDW_{H_B/W_H/D_W/Q_D}
defm : PatVrVrW<loongarch_vhaddw, "VHADDW">;
+// VHADDW_{HU_BU/WU_HU/DU_WU/QU_DU}
+defm : PatVrVrWU<loongarch_vhaddw_u, "VHADDW">;
+
+// VHSUBW_{H_B/W_H/D_W/Q_D}
+defm : PatVrVrW<loongarch_vhsubw, "VHSUBW">;
+
+// VHSUBW_{HU_BU/WU_HU/DU_WU/QU_DU}
+defm : PatVrVrWU<loongarch_vhsubw_u, "VHSUBW">;
+
// VFADD_{S/D}
defm : PatVrVrF<fadd, "VFADD">;
>From 9a7e672cfda79f70443da036431d9082d1be4765 Mon Sep 17 00:00:00 2001
From: WANG Rui <wangrui at loongson.cn>
Date: Tue, 16 Jun 2026 15:41:37 +0800
Subject: [PATCH 2/2] Fix DAG combine for illegal vector types
---
.../LoongArch/LoongArchISelLowering.cpp | 3 +
llvm/test/CodeGen/LoongArch/lasx/vhaddw.ll | 260 +-----------------
llvm/test/CodeGen/LoongArch/lasx/vhsubw.ll | 260 +-----------------
llvm/test/CodeGen/LoongArch/lsx/vhaddw.ll | 45 +--
llvm/test/CodeGen/LoongArch/lsx/vhsubw.ll | 45 +--
5 files changed, 31 insertions(+), 582 deletions(-)
diff --git a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
index 1b2258df77fa1..e5143a1646799 100644
--- a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
+++ b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
@@ -5993,7 +5993,10 @@ performHorizWideningCombine(SDNode *N, SelectionDAG &DAG,
EVT SrcVT = LHSVec.getValueType();
EVT SrcEltVT = SrcVT.getVectorElementType();
EVT DstEltVT = VT.getVectorElementType();
+ auto &TLI = DAG.getTargetLoweringInfo();
+ if (!TLI.isTypeLegal(VT) || !TLI.isTypeLegal(SrcVT))
+ return SDValue();
if (!SrcVT.isVector() || !VT.isVector())
return SDValue();
if (SrcVT.getSizeInBits() != VT.getSizeInBits())
diff --git a/llvm/test/CodeGen/LoongArch/lasx/vhaddw.ll b/llvm/test/CodeGen/LoongArch/lasx/vhaddw.ll
index 1f405d640b133..2304a5d6f83fd 100644
--- a/llvm/test/CodeGen/LoongArch/lasx/vhaddw.ll
+++ b/llvm/test/CodeGen/LoongArch/lasx/vhaddw.ll
@@ -173,77 +173,9 @@ entry:
define void @xvhaddw_h_b(ptr %a, ptr %b, ptr %r) nounwind {
; CHECK-LABEL: xvhaddw_h_b:
; CHECK: # %bb.0: # %entry
-; CHECK-NEXT: xvld $xr2, $a0, 0
+; CHECK-NEXT: xvld $xr0, $a0, 0
; CHECK-NEXT: xvld $xr1, $a1, 0
-; CHECK-NEXT: vpickve2gr.b $a0, $vr2, 1
-; CHECK-NEXT: vinsgr2vr.b $vr0, $a0, 0
-; CHECK-NEXT: vpickve2gr.b $a0, $vr2, 3
-; CHECK-NEXT: vinsgr2vr.b $vr0, $a0, 1
-; CHECK-NEXT: vpickve2gr.b $a0, $vr2, 5
-; CHECK-NEXT: vinsgr2vr.b $vr0, $a0, 2
-; CHECK-NEXT: vpickve2gr.b $a0, $vr2, 7
-; CHECK-NEXT: vinsgr2vr.b $vr0, $a0, 3
-; CHECK-NEXT: vpickve2gr.b $a0, $vr2, 9
-; CHECK-NEXT: vinsgr2vr.b $vr0, $a0, 4
-; CHECK-NEXT: vpickve2gr.b $a0, $vr2, 11
-; CHECK-NEXT: vinsgr2vr.b $vr0, $a0, 5
-; CHECK-NEXT: vpickve2gr.b $a0, $vr2, 13
-; CHECK-NEXT: vinsgr2vr.b $vr0, $a0, 6
-; CHECK-NEXT: vpickve2gr.b $a0, $vr2, 15
-; CHECK-NEXT: vinsgr2vr.b $vr0, $a0, 7
-; CHECK-NEXT: xvpermi.d $xr2, $xr2, 14
-; CHECK-NEXT: vpickve2gr.b $a0, $vr2, 1
-; CHECK-NEXT: vinsgr2vr.b $vr0, $a0, 8
-; CHECK-NEXT: vpickve2gr.b $a0, $vr2, 3
-; CHECK-NEXT: vinsgr2vr.b $vr0, $a0, 9
-; CHECK-NEXT: vpickve2gr.b $a0, $vr2, 5
-; CHECK-NEXT: vinsgr2vr.b $vr0, $a0, 10
-; CHECK-NEXT: vpickve2gr.b $a0, $vr2, 7
-; CHECK-NEXT: vinsgr2vr.b $vr0, $a0, 11
-; CHECK-NEXT: vpickve2gr.b $a0, $vr2, 9
-; CHECK-NEXT: vinsgr2vr.b $vr0, $a0, 12
-; CHECK-NEXT: vpickve2gr.b $a0, $vr2, 11
-; CHECK-NEXT: vinsgr2vr.b $vr0, $a0, 13
-; CHECK-NEXT: vpickve2gr.b $a0, $vr2, 13
-; CHECK-NEXT: vinsgr2vr.b $vr0, $a0, 14
-; CHECK-NEXT: vpickve2gr.b $a0, $vr2, 15
-; CHECK-NEXT: vinsgr2vr.b $vr0, $a0, 15
-; CHECK-NEXT: vpickve2gr.b $a0, $vr1, 0
-; CHECK-NEXT: vinsgr2vr.b $vr2, $a0, 0
-; CHECK-NEXT: vpickve2gr.b $a0, $vr1, 2
-; CHECK-NEXT: vinsgr2vr.b $vr2, $a0, 1
-; CHECK-NEXT: vpickve2gr.b $a0, $vr1, 4
-; CHECK-NEXT: vinsgr2vr.b $vr2, $a0, 2
-; CHECK-NEXT: vpickve2gr.b $a0, $vr1, 6
-; CHECK-NEXT: vinsgr2vr.b $vr2, $a0, 3
-; CHECK-NEXT: vpickve2gr.b $a0, $vr1, 8
-; CHECK-NEXT: vinsgr2vr.b $vr2, $a0, 4
-; CHECK-NEXT: vpickve2gr.b $a0, $vr1, 10
-; CHECK-NEXT: vinsgr2vr.b $vr2, $a0, 5
-; CHECK-NEXT: vpickve2gr.b $a0, $vr1, 12
-; CHECK-NEXT: vinsgr2vr.b $vr2, $a0, 6
-; CHECK-NEXT: vpickve2gr.b $a0, $vr1, 14
-; CHECK-NEXT: vinsgr2vr.b $vr2, $a0, 7
-; CHECK-NEXT: xvpermi.d $xr1, $xr1, 14
-; CHECK-NEXT: vpickve2gr.b $a0, $vr1, 0
-; CHECK-NEXT: vinsgr2vr.b $vr2, $a0, 8
-; CHECK-NEXT: vpickve2gr.b $a0, $vr1, 2
-; CHECK-NEXT: vinsgr2vr.b $vr2, $a0, 9
-; CHECK-NEXT: vpickve2gr.b $a0, $vr1, 4
-; CHECK-NEXT: vinsgr2vr.b $vr2, $a0, 10
-; CHECK-NEXT: vpickve2gr.b $a0, $vr1, 6
-; CHECK-NEXT: vinsgr2vr.b $vr2, $a0, 11
-; CHECK-NEXT: vpickve2gr.b $a0, $vr1, 8
-; CHECK-NEXT: vinsgr2vr.b $vr2, $a0, 12
-; CHECK-NEXT: vpickve2gr.b $a0, $vr1, 10
-; CHECK-NEXT: vinsgr2vr.b $vr2, $a0, 13
-; CHECK-NEXT: vpickve2gr.b $a0, $vr1, 12
-; CHECK-NEXT: vinsgr2vr.b $vr2, $a0, 14
-; CHECK-NEXT: vpickve2gr.b $a0, $vr1, 14
-; CHECK-NEXT: vinsgr2vr.b $vr2, $a0, 15
-; CHECK-NEXT: vext2xv.h.b $xr0, $xr0
-; CHECK-NEXT: vext2xv.h.b $xr1, $xr2
-; CHECK-NEXT: xvadd.h $xr0, $xr0, $xr1
+; CHECK-NEXT: xvhaddw.h.b $xr0, $xr0, $xr1
; CHECK-NEXT: xvst $xr0, $a2, 0
; CHECK-NEXT: ret
entry:
@@ -267,43 +199,7 @@ define void @xvhaddw_w_h(ptr %a, ptr %b, ptr %r) nounwind {
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xvld $xr0, $a0, 0
; CHECK-NEXT: xvld $xr1, $a1, 0
-; CHECK-NEXT: vpickve2gr.h $a0, $vr0, 1
-; CHECK-NEXT: vinsgr2vr.h $vr2, $a0, 0
-; CHECK-NEXT: vpickve2gr.h $a0, $vr0, 3
-; CHECK-NEXT: vinsgr2vr.h $vr2, $a0, 1
-; CHECK-NEXT: vpickve2gr.h $a0, $vr0, 5
-; CHECK-NEXT: vinsgr2vr.h $vr2, $a0, 2
-; CHECK-NEXT: vpickve2gr.h $a0, $vr0, 7
-; CHECK-NEXT: vinsgr2vr.h $vr2, $a0, 3
-; CHECK-NEXT: xvpermi.d $xr0, $xr0, 14
-; CHECK-NEXT: vpickve2gr.h $a0, $vr0, 1
-; CHECK-NEXT: vinsgr2vr.h $vr2, $a0, 4
-; CHECK-NEXT: vpickve2gr.h $a0, $vr0, 3
-; CHECK-NEXT: vinsgr2vr.h $vr2, $a0, 5
-; CHECK-NEXT: vpickve2gr.h $a0, $vr0, 5
-; CHECK-NEXT: vinsgr2vr.h $vr2, $a0, 6
-; CHECK-NEXT: vpickve2gr.h $a0, $vr0, 7
-; CHECK-NEXT: vinsgr2vr.h $vr2, $a0, 7
-; CHECK-NEXT: vpickve2gr.h $a0, $vr1, 0
-; CHECK-NEXT: vinsgr2vr.h $vr0, $a0, 0
-; CHECK-NEXT: vpickve2gr.h $a0, $vr1, 2
-; CHECK-NEXT: vinsgr2vr.h $vr0, $a0, 1
-; CHECK-NEXT: vpickve2gr.h $a0, $vr1, 4
-; CHECK-NEXT: vinsgr2vr.h $vr0, $a0, 2
-; CHECK-NEXT: vpickve2gr.h $a0, $vr1, 6
-; CHECK-NEXT: vinsgr2vr.h $vr0, $a0, 3
-; CHECK-NEXT: xvpermi.d $xr1, $xr1, 14
-; CHECK-NEXT: vpickve2gr.h $a0, $vr1, 0
-; CHECK-NEXT: vinsgr2vr.h $vr0, $a0, 4
-; CHECK-NEXT: vpickve2gr.h $a0, $vr1, 2
-; CHECK-NEXT: vinsgr2vr.h $vr0, $a0, 5
-; CHECK-NEXT: vpickve2gr.h $a0, $vr1, 4
-; CHECK-NEXT: vinsgr2vr.h $vr0, $a0, 6
-; CHECK-NEXT: vpickve2gr.h $a0, $vr1, 6
-; CHECK-NEXT: vinsgr2vr.h $vr0, $a0, 7
-; CHECK-NEXT: vext2xv.w.h $xr1, $xr2
-; CHECK-NEXT: vext2xv.w.h $xr0, $xr0
-; CHECK-NEXT: xvadd.w $xr0, $xr1, $xr0
+; CHECK-NEXT: xvhaddw.w.h $xr0, $xr0, $xr1
; CHECK-NEXT: xvst $xr0, $a2, 0
; CHECK-NEXT: ret
entry:
@@ -325,25 +221,7 @@ define void @xvhaddw_d_w(ptr %a, ptr %b, ptr %r) nounwind {
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xvld $xr0, $a0, 0
; CHECK-NEXT: xvld $xr1, $a1, 0
-; CHECK-NEXT: xvpickve2gr.w $a0, $xr0, 1
-; CHECK-NEXT: vinsgr2vr.w $vr2, $a0, 0
-; CHECK-NEXT: xvpickve2gr.w $a0, $xr0, 3
-; CHECK-NEXT: vinsgr2vr.w $vr2, $a0, 1
-; CHECK-NEXT: xvpickve2gr.w $a0, $xr0, 5
-; CHECK-NEXT: vinsgr2vr.w $vr2, $a0, 2
-; CHECK-NEXT: xvpickve2gr.w $a0, $xr0, 7
-; CHECK-NEXT: vinsgr2vr.w $vr2, $a0, 3
-; CHECK-NEXT: xvpickve2gr.w $a0, $xr1, 0
-; CHECK-NEXT: vinsgr2vr.w $vr0, $a0, 0
-; CHECK-NEXT: xvpickve2gr.w $a0, $xr1, 2
-; CHECK-NEXT: vinsgr2vr.w $vr0, $a0, 1
-; CHECK-NEXT: xvpickve2gr.w $a0, $xr1, 4
-; CHECK-NEXT: vinsgr2vr.w $vr0, $a0, 2
-; CHECK-NEXT: xvpickve2gr.w $a0, $xr1, 6
-; CHECK-NEXT: vinsgr2vr.w $vr0, $a0, 3
-; CHECK-NEXT: vext2xv.d.w $xr1, $xr2
-; CHECK-NEXT: vext2xv.d.w $xr0, $xr0
-; CHECK-NEXT: xvadd.d $xr0, $xr1, $xr0
+; CHECK-NEXT: xvhaddw.d.w $xr0, $xr0, $xr1
; CHECK-NEXT: xvst $xr0, $a2, 0
; CHECK-NEXT: ret
entry:
@@ -361,77 +239,9 @@ entry:
define void @xvhaddw_hu_bu(ptr %a, ptr %b, ptr %r) nounwind {
; CHECK-LABEL: xvhaddw_hu_bu:
; CHECK: # %bb.0: # %entry
-; CHECK-NEXT: xvld $xr2, $a0, 0
+; CHECK-NEXT: xvld $xr0, $a0, 0
; CHECK-NEXT: xvld $xr1, $a1, 0
-; CHECK-NEXT: vpickve2gr.b $a0, $vr2, 1
-; CHECK-NEXT: vinsgr2vr.b $vr0, $a0, 0
-; CHECK-NEXT: vpickve2gr.b $a0, $vr2, 3
-; CHECK-NEXT: vinsgr2vr.b $vr0, $a0, 1
-; CHECK-NEXT: vpickve2gr.b $a0, $vr2, 5
-; CHECK-NEXT: vinsgr2vr.b $vr0, $a0, 2
-; CHECK-NEXT: vpickve2gr.b $a0, $vr2, 7
-; CHECK-NEXT: vinsgr2vr.b $vr0, $a0, 3
-; CHECK-NEXT: vpickve2gr.b $a0, $vr2, 9
-; CHECK-NEXT: vinsgr2vr.b $vr0, $a0, 4
-; CHECK-NEXT: vpickve2gr.b $a0, $vr2, 11
-; CHECK-NEXT: vinsgr2vr.b $vr0, $a0, 5
-; CHECK-NEXT: vpickve2gr.b $a0, $vr2, 13
-; CHECK-NEXT: vinsgr2vr.b $vr0, $a0, 6
-; CHECK-NEXT: vpickve2gr.b $a0, $vr2, 15
-; CHECK-NEXT: vinsgr2vr.b $vr0, $a0, 7
-; CHECK-NEXT: xvpermi.d $xr2, $xr2, 14
-; CHECK-NEXT: vpickve2gr.b $a0, $vr2, 1
-; CHECK-NEXT: vinsgr2vr.b $vr0, $a0, 8
-; CHECK-NEXT: vpickve2gr.b $a0, $vr2, 3
-; CHECK-NEXT: vinsgr2vr.b $vr0, $a0, 9
-; CHECK-NEXT: vpickve2gr.b $a0, $vr2, 5
-; CHECK-NEXT: vinsgr2vr.b $vr0, $a0, 10
-; CHECK-NEXT: vpickve2gr.b $a0, $vr2, 7
-; CHECK-NEXT: vinsgr2vr.b $vr0, $a0, 11
-; CHECK-NEXT: vpickve2gr.b $a0, $vr2, 9
-; CHECK-NEXT: vinsgr2vr.b $vr0, $a0, 12
-; CHECK-NEXT: vpickve2gr.b $a0, $vr2, 11
-; CHECK-NEXT: vinsgr2vr.b $vr0, $a0, 13
-; CHECK-NEXT: vpickve2gr.b $a0, $vr2, 13
-; CHECK-NEXT: vinsgr2vr.b $vr0, $a0, 14
-; CHECK-NEXT: vpickve2gr.b $a0, $vr2, 15
-; CHECK-NEXT: vinsgr2vr.b $vr0, $a0, 15
-; CHECK-NEXT: vpickve2gr.b $a0, $vr1, 0
-; CHECK-NEXT: vinsgr2vr.b $vr2, $a0, 0
-; CHECK-NEXT: vpickve2gr.b $a0, $vr1, 2
-; CHECK-NEXT: vinsgr2vr.b $vr2, $a0, 1
-; CHECK-NEXT: vpickve2gr.b $a0, $vr1, 4
-; CHECK-NEXT: vinsgr2vr.b $vr2, $a0, 2
-; CHECK-NEXT: vpickve2gr.b $a0, $vr1, 6
-; CHECK-NEXT: vinsgr2vr.b $vr2, $a0, 3
-; CHECK-NEXT: vpickve2gr.b $a0, $vr1, 8
-; CHECK-NEXT: vinsgr2vr.b $vr2, $a0, 4
-; CHECK-NEXT: vpickve2gr.b $a0, $vr1, 10
-; CHECK-NEXT: vinsgr2vr.b $vr2, $a0, 5
-; CHECK-NEXT: vpickve2gr.b $a0, $vr1, 12
-; CHECK-NEXT: vinsgr2vr.b $vr2, $a0, 6
-; CHECK-NEXT: vpickve2gr.b $a0, $vr1, 14
-; CHECK-NEXT: vinsgr2vr.b $vr2, $a0, 7
-; CHECK-NEXT: xvpermi.d $xr1, $xr1, 14
-; CHECK-NEXT: vpickve2gr.b $a0, $vr1, 0
-; CHECK-NEXT: vinsgr2vr.b $vr2, $a0, 8
-; CHECK-NEXT: vpickve2gr.b $a0, $vr1, 2
-; CHECK-NEXT: vinsgr2vr.b $vr2, $a0, 9
-; CHECK-NEXT: vpickve2gr.b $a0, $vr1, 4
-; CHECK-NEXT: vinsgr2vr.b $vr2, $a0, 10
-; CHECK-NEXT: vpickve2gr.b $a0, $vr1, 6
-; CHECK-NEXT: vinsgr2vr.b $vr2, $a0, 11
-; CHECK-NEXT: vpickve2gr.b $a0, $vr1, 8
-; CHECK-NEXT: vinsgr2vr.b $vr2, $a0, 12
-; CHECK-NEXT: vpickve2gr.b $a0, $vr1, 10
-; CHECK-NEXT: vinsgr2vr.b $vr2, $a0, 13
-; CHECK-NEXT: vpickve2gr.b $a0, $vr1, 12
-; CHECK-NEXT: vinsgr2vr.b $vr2, $a0, 14
-; CHECK-NEXT: vpickve2gr.b $a0, $vr1, 14
-; CHECK-NEXT: vinsgr2vr.b $vr2, $a0, 15
-; CHECK-NEXT: vext2xv.hu.bu $xr0, $xr0
-; CHECK-NEXT: vext2xv.hu.bu $xr1, $xr2
-; CHECK-NEXT: xvadd.h $xr0, $xr0, $xr1
+; CHECK-NEXT: xvhaddw.hu.bu $xr0, $xr0, $xr1
; CHECK-NEXT: xvst $xr0, $a2, 0
; CHECK-NEXT: ret
entry:
@@ -455,43 +265,7 @@ define void @xvhaddw_wu_hu(ptr %a, ptr %b, ptr %r) nounwind {
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xvld $xr0, $a0, 0
; CHECK-NEXT: xvld $xr1, $a1, 0
-; CHECK-NEXT: vpickve2gr.h $a0, $vr0, 1
-; CHECK-NEXT: vinsgr2vr.h $vr2, $a0, 0
-; CHECK-NEXT: vpickve2gr.h $a0, $vr0, 3
-; CHECK-NEXT: vinsgr2vr.h $vr2, $a0, 1
-; CHECK-NEXT: vpickve2gr.h $a0, $vr0, 5
-; CHECK-NEXT: vinsgr2vr.h $vr2, $a0, 2
-; CHECK-NEXT: vpickve2gr.h $a0, $vr0, 7
-; CHECK-NEXT: vinsgr2vr.h $vr2, $a0, 3
-; CHECK-NEXT: xvpermi.d $xr0, $xr0, 14
-; CHECK-NEXT: vpickve2gr.h $a0, $vr0, 1
-; CHECK-NEXT: vinsgr2vr.h $vr2, $a0, 4
-; CHECK-NEXT: vpickve2gr.h $a0, $vr0, 3
-; CHECK-NEXT: vinsgr2vr.h $vr2, $a0, 5
-; CHECK-NEXT: vpickve2gr.h $a0, $vr0, 5
-; CHECK-NEXT: vinsgr2vr.h $vr2, $a0, 6
-; CHECK-NEXT: vpickve2gr.h $a0, $vr0, 7
-; CHECK-NEXT: vinsgr2vr.h $vr2, $a0, 7
-; CHECK-NEXT: vpickve2gr.h $a0, $vr1, 0
-; CHECK-NEXT: vinsgr2vr.h $vr0, $a0, 0
-; CHECK-NEXT: vpickve2gr.h $a0, $vr1, 2
-; CHECK-NEXT: vinsgr2vr.h $vr0, $a0, 1
-; CHECK-NEXT: vpickve2gr.h $a0, $vr1, 4
-; CHECK-NEXT: vinsgr2vr.h $vr0, $a0, 2
-; CHECK-NEXT: vpickve2gr.h $a0, $vr1, 6
-; CHECK-NEXT: vinsgr2vr.h $vr0, $a0, 3
-; CHECK-NEXT: xvpermi.d $xr1, $xr1, 14
-; CHECK-NEXT: vpickve2gr.h $a0, $vr1, 0
-; CHECK-NEXT: vinsgr2vr.h $vr0, $a0, 4
-; CHECK-NEXT: vpickve2gr.h $a0, $vr1, 2
-; CHECK-NEXT: vinsgr2vr.h $vr0, $a0, 5
-; CHECK-NEXT: vpickve2gr.h $a0, $vr1, 4
-; CHECK-NEXT: vinsgr2vr.h $vr0, $a0, 6
-; CHECK-NEXT: vpickve2gr.h $a0, $vr1, 6
-; CHECK-NEXT: vinsgr2vr.h $vr0, $a0, 7
-; CHECK-NEXT: vext2xv.wu.hu $xr1, $xr2
-; CHECK-NEXT: vext2xv.wu.hu $xr0, $xr0
-; CHECK-NEXT: xvadd.w $xr0, $xr1, $xr0
+; CHECK-NEXT: xvhaddw.wu.hu $xr0, $xr0, $xr1
; CHECK-NEXT: xvst $xr0, $a2, 0
; CHECK-NEXT: ret
entry:
@@ -513,25 +287,7 @@ define void @xvhaddw_du_wu(ptr %a, ptr %b, ptr %r) nounwind {
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xvld $xr0, $a0, 0
; CHECK-NEXT: xvld $xr1, $a1, 0
-; CHECK-NEXT: xvpickve2gr.w $a0, $xr0, 1
-; CHECK-NEXT: vinsgr2vr.w $vr2, $a0, 0
-; CHECK-NEXT: xvpickve2gr.w $a0, $xr0, 3
-; CHECK-NEXT: vinsgr2vr.w $vr2, $a0, 1
-; CHECK-NEXT: xvpickve2gr.w $a0, $xr0, 5
-; CHECK-NEXT: vinsgr2vr.w $vr2, $a0, 2
-; CHECK-NEXT: xvpickve2gr.w $a0, $xr0, 7
-; CHECK-NEXT: vinsgr2vr.w $vr2, $a0, 3
-; CHECK-NEXT: xvpickve2gr.w $a0, $xr1, 0
-; CHECK-NEXT: vinsgr2vr.w $vr0, $a0, 0
-; CHECK-NEXT: xvpickve2gr.w $a0, $xr1, 2
-; CHECK-NEXT: vinsgr2vr.w $vr0, $a0, 1
-; CHECK-NEXT: xvpickve2gr.w $a0, $xr1, 4
-; CHECK-NEXT: vinsgr2vr.w $vr0, $a0, 2
-; CHECK-NEXT: xvpickve2gr.w $a0, $xr1, 6
-; CHECK-NEXT: vinsgr2vr.w $vr0, $a0, 3
-; CHECK-NEXT: vext2xv.du.wu $xr1, $xr2
-; CHECK-NEXT: vext2xv.du.wu $xr0, $xr0
-; CHECK-NEXT: xvadd.d $xr0, $xr1, $xr0
+; CHECK-NEXT: xvhaddw.du.wu $xr0, $xr0, $xr1
; CHECK-NEXT: xvst $xr0, $a2, 0
; CHECK-NEXT: ret
entry:
diff --git a/llvm/test/CodeGen/LoongArch/lasx/vhsubw.ll b/llvm/test/CodeGen/LoongArch/lasx/vhsubw.ll
index 856a7bf52e159..20b959aa74d7a 100644
--- a/llvm/test/CodeGen/LoongArch/lasx/vhsubw.ll
+++ b/llvm/test/CodeGen/LoongArch/lasx/vhsubw.ll
@@ -173,77 +173,9 @@ entry:
define void @xvhsubw_h_b(ptr %a, ptr %b, ptr %r) nounwind {
; CHECK-LABEL: xvhsubw_h_b:
; CHECK: # %bb.0: # %entry
-; CHECK-NEXT: xvld $xr2, $a0, 0
+; CHECK-NEXT: xvld $xr0, $a0, 0
; CHECK-NEXT: xvld $xr1, $a1, 0
-; CHECK-NEXT: vpickve2gr.b $a0, $vr2, 1
-; CHECK-NEXT: vinsgr2vr.b $vr0, $a0, 0
-; CHECK-NEXT: vpickve2gr.b $a0, $vr2, 3
-; CHECK-NEXT: vinsgr2vr.b $vr0, $a0, 1
-; CHECK-NEXT: vpickve2gr.b $a0, $vr2, 5
-; CHECK-NEXT: vinsgr2vr.b $vr0, $a0, 2
-; CHECK-NEXT: vpickve2gr.b $a0, $vr2, 7
-; CHECK-NEXT: vinsgr2vr.b $vr0, $a0, 3
-; CHECK-NEXT: vpickve2gr.b $a0, $vr2, 9
-; CHECK-NEXT: vinsgr2vr.b $vr0, $a0, 4
-; CHECK-NEXT: vpickve2gr.b $a0, $vr2, 11
-; CHECK-NEXT: vinsgr2vr.b $vr0, $a0, 5
-; CHECK-NEXT: vpickve2gr.b $a0, $vr2, 13
-; CHECK-NEXT: vinsgr2vr.b $vr0, $a0, 6
-; CHECK-NEXT: vpickve2gr.b $a0, $vr2, 15
-; CHECK-NEXT: vinsgr2vr.b $vr0, $a0, 7
-; CHECK-NEXT: xvpermi.d $xr2, $xr2, 14
-; CHECK-NEXT: vpickve2gr.b $a0, $vr2, 1
-; CHECK-NEXT: vinsgr2vr.b $vr0, $a0, 8
-; CHECK-NEXT: vpickve2gr.b $a0, $vr2, 3
-; CHECK-NEXT: vinsgr2vr.b $vr0, $a0, 9
-; CHECK-NEXT: vpickve2gr.b $a0, $vr2, 5
-; CHECK-NEXT: vinsgr2vr.b $vr0, $a0, 10
-; CHECK-NEXT: vpickve2gr.b $a0, $vr2, 7
-; CHECK-NEXT: vinsgr2vr.b $vr0, $a0, 11
-; CHECK-NEXT: vpickve2gr.b $a0, $vr2, 9
-; CHECK-NEXT: vinsgr2vr.b $vr0, $a0, 12
-; CHECK-NEXT: vpickve2gr.b $a0, $vr2, 11
-; CHECK-NEXT: vinsgr2vr.b $vr0, $a0, 13
-; CHECK-NEXT: vpickve2gr.b $a0, $vr2, 13
-; CHECK-NEXT: vinsgr2vr.b $vr0, $a0, 14
-; CHECK-NEXT: vpickve2gr.b $a0, $vr2, 15
-; CHECK-NEXT: vinsgr2vr.b $vr0, $a0, 15
-; CHECK-NEXT: vpickve2gr.b $a0, $vr1, 0
-; CHECK-NEXT: vinsgr2vr.b $vr2, $a0, 0
-; CHECK-NEXT: vpickve2gr.b $a0, $vr1, 2
-; CHECK-NEXT: vinsgr2vr.b $vr2, $a0, 1
-; CHECK-NEXT: vpickve2gr.b $a0, $vr1, 4
-; CHECK-NEXT: vinsgr2vr.b $vr2, $a0, 2
-; CHECK-NEXT: vpickve2gr.b $a0, $vr1, 6
-; CHECK-NEXT: vinsgr2vr.b $vr2, $a0, 3
-; CHECK-NEXT: vpickve2gr.b $a0, $vr1, 8
-; CHECK-NEXT: vinsgr2vr.b $vr2, $a0, 4
-; CHECK-NEXT: vpickve2gr.b $a0, $vr1, 10
-; CHECK-NEXT: vinsgr2vr.b $vr2, $a0, 5
-; CHECK-NEXT: vpickve2gr.b $a0, $vr1, 12
-; CHECK-NEXT: vinsgr2vr.b $vr2, $a0, 6
-; CHECK-NEXT: vpickve2gr.b $a0, $vr1, 14
-; CHECK-NEXT: vinsgr2vr.b $vr2, $a0, 7
-; CHECK-NEXT: xvpermi.d $xr1, $xr1, 14
-; CHECK-NEXT: vpickve2gr.b $a0, $vr1, 0
-; CHECK-NEXT: vinsgr2vr.b $vr2, $a0, 8
-; CHECK-NEXT: vpickve2gr.b $a0, $vr1, 2
-; CHECK-NEXT: vinsgr2vr.b $vr2, $a0, 9
-; CHECK-NEXT: vpickve2gr.b $a0, $vr1, 4
-; CHECK-NEXT: vinsgr2vr.b $vr2, $a0, 10
-; CHECK-NEXT: vpickve2gr.b $a0, $vr1, 6
-; CHECK-NEXT: vinsgr2vr.b $vr2, $a0, 11
-; CHECK-NEXT: vpickve2gr.b $a0, $vr1, 8
-; CHECK-NEXT: vinsgr2vr.b $vr2, $a0, 12
-; CHECK-NEXT: vpickve2gr.b $a0, $vr1, 10
-; CHECK-NEXT: vinsgr2vr.b $vr2, $a0, 13
-; CHECK-NEXT: vpickve2gr.b $a0, $vr1, 12
-; CHECK-NEXT: vinsgr2vr.b $vr2, $a0, 14
-; CHECK-NEXT: vpickve2gr.b $a0, $vr1, 14
-; CHECK-NEXT: vinsgr2vr.b $vr2, $a0, 15
-; CHECK-NEXT: vext2xv.h.b $xr0, $xr0
-; CHECK-NEXT: vext2xv.h.b $xr1, $xr2
-; CHECK-NEXT: xvsub.h $xr0, $xr0, $xr1
+; CHECK-NEXT: xvhsubw.h.b $xr0, $xr0, $xr1
; CHECK-NEXT: xvst $xr0, $a2, 0
; CHECK-NEXT: ret
entry:
@@ -267,43 +199,7 @@ define void @xvhsubw_w_h(ptr %a, ptr %b, ptr %r) nounwind {
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xvld $xr0, $a0, 0
; CHECK-NEXT: xvld $xr1, $a1, 0
-; CHECK-NEXT: vpickve2gr.h $a0, $vr0, 1
-; CHECK-NEXT: vinsgr2vr.h $vr2, $a0, 0
-; CHECK-NEXT: vpickve2gr.h $a0, $vr0, 3
-; CHECK-NEXT: vinsgr2vr.h $vr2, $a0, 1
-; CHECK-NEXT: vpickve2gr.h $a0, $vr0, 5
-; CHECK-NEXT: vinsgr2vr.h $vr2, $a0, 2
-; CHECK-NEXT: vpickve2gr.h $a0, $vr0, 7
-; CHECK-NEXT: vinsgr2vr.h $vr2, $a0, 3
-; CHECK-NEXT: xvpermi.d $xr0, $xr0, 14
-; CHECK-NEXT: vpickve2gr.h $a0, $vr0, 1
-; CHECK-NEXT: vinsgr2vr.h $vr2, $a0, 4
-; CHECK-NEXT: vpickve2gr.h $a0, $vr0, 3
-; CHECK-NEXT: vinsgr2vr.h $vr2, $a0, 5
-; CHECK-NEXT: vpickve2gr.h $a0, $vr0, 5
-; CHECK-NEXT: vinsgr2vr.h $vr2, $a0, 6
-; CHECK-NEXT: vpickve2gr.h $a0, $vr0, 7
-; CHECK-NEXT: vinsgr2vr.h $vr2, $a0, 7
-; CHECK-NEXT: vpickve2gr.h $a0, $vr1, 0
-; CHECK-NEXT: vinsgr2vr.h $vr0, $a0, 0
-; CHECK-NEXT: vpickve2gr.h $a0, $vr1, 2
-; CHECK-NEXT: vinsgr2vr.h $vr0, $a0, 1
-; CHECK-NEXT: vpickve2gr.h $a0, $vr1, 4
-; CHECK-NEXT: vinsgr2vr.h $vr0, $a0, 2
-; CHECK-NEXT: vpickve2gr.h $a0, $vr1, 6
-; CHECK-NEXT: vinsgr2vr.h $vr0, $a0, 3
-; CHECK-NEXT: xvpermi.d $xr1, $xr1, 14
-; CHECK-NEXT: vpickve2gr.h $a0, $vr1, 0
-; CHECK-NEXT: vinsgr2vr.h $vr0, $a0, 4
-; CHECK-NEXT: vpickve2gr.h $a0, $vr1, 2
-; CHECK-NEXT: vinsgr2vr.h $vr0, $a0, 5
-; CHECK-NEXT: vpickve2gr.h $a0, $vr1, 4
-; CHECK-NEXT: vinsgr2vr.h $vr0, $a0, 6
-; CHECK-NEXT: vpickve2gr.h $a0, $vr1, 6
-; CHECK-NEXT: vinsgr2vr.h $vr0, $a0, 7
-; CHECK-NEXT: vext2xv.w.h $xr1, $xr2
-; CHECK-NEXT: vext2xv.w.h $xr0, $xr0
-; CHECK-NEXT: xvsub.w $xr0, $xr1, $xr0
+; CHECK-NEXT: xvhsubw.w.h $xr0, $xr0, $xr1
; CHECK-NEXT: xvst $xr0, $a2, 0
; CHECK-NEXT: ret
entry:
@@ -325,25 +221,7 @@ define void @xvhsubw_d_w(ptr %a, ptr %b, ptr %r) nounwind {
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xvld $xr0, $a0, 0
; CHECK-NEXT: xvld $xr1, $a1, 0
-; CHECK-NEXT: xvpickve2gr.w $a0, $xr0, 1
-; CHECK-NEXT: vinsgr2vr.w $vr2, $a0, 0
-; CHECK-NEXT: xvpickve2gr.w $a0, $xr0, 3
-; CHECK-NEXT: vinsgr2vr.w $vr2, $a0, 1
-; CHECK-NEXT: xvpickve2gr.w $a0, $xr0, 5
-; CHECK-NEXT: vinsgr2vr.w $vr2, $a0, 2
-; CHECK-NEXT: xvpickve2gr.w $a0, $xr0, 7
-; CHECK-NEXT: vinsgr2vr.w $vr2, $a0, 3
-; CHECK-NEXT: xvpickve2gr.w $a0, $xr1, 0
-; CHECK-NEXT: vinsgr2vr.w $vr0, $a0, 0
-; CHECK-NEXT: xvpickve2gr.w $a0, $xr1, 2
-; CHECK-NEXT: vinsgr2vr.w $vr0, $a0, 1
-; CHECK-NEXT: xvpickve2gr.w $a0, $xr1, 4
-; CHECK-NEXT: vinsgr2vr.w $vr0, $a0, 2
-; CHECK-NEXT: xvpickve2gr.w $a0, $xr1, 6
-; CHECK-NEXT: vinsgr2vr.w $vr0, $a0, 3
-; CHECK-NEXT: vext2xv.d.w $xr1, $xr2
-; CHECK-NEXT: vext2xv.d.w $xr0, $xr0
-; CHECK-NEXT: xvsub.d $xr0, $xr1, $xr0
+; CHECK-NEXT: xvhsubw.d.w $xr0, $xr0, $xr1
; CHECK-NEXT: xvst $xr0, $a2, 0
; CHECK-NEXT: ret
entry:
@@ -361,77 +239,9 @@ entry:
define void @xvhsubw_hu_bu(ptr %a, ptr %b, ptr %r) nounwind {
; CHECK-LABEL: xvhsubw_hu_bu:
; CHECK: # %bb.0: # %entry
-; CHECK-NEXT: xvld $xr2, $a0, 0
+; CHECK-NEXT: xvld $xr0, $a0, 0
; CHECK-NEXT: xvld $xr1, $a1, 0
-; CHECK-NEXT: vpickve2gr.b $a0, $vr2, 1
-; CHECK-NEXT: vinsgr2vr.b $vr0, $a0, 0
-; CHECK-NEXT: vpickve2gr.b $a0, $vr2, 3
-; CHECK-NEXT: vinsgr2vr.b $vr0, $a0, 1
-; CHECK-NEXT: vpickve2gr.b $a0, $vr2, 5
-; CHECK-NEXT: vinsgr2vr.b $vr0, $a0, 2
-; CHECK-NEXT: vpickve2gr.b $a0, $vr2, 7
-; CHECK-NEXT: vinsgr2vr.b $vr0, $a0, 3
-; CHECK-NEXT: vpickve2gr.b $a0, $vr2, 9
-; CHECK-NEXT: vinsgr2vr.b $vr0, $a0, 4
-; CHECK-NEXT: vpickve2gr.b $a0, $vr2, 11
-; CHECK-NEXT: vinsgr2vr.b $vr0, $a0, 5
-; CHECK-NEXT: vpickve2gr.b $a0, $vr2, 13
-; CHECK-NEXT: vinsgr2vr.b $vr0, $a0, 6
-; CHECK-NEXT: vpickve2gr.b $a0, $vr2, 15
-; CHECK-NEXT: vinsgr2vr.b $vr0, $a0, 7
-; CHECK-NEXT: xvpermi.d $xr2, $xr2, 14
-; CHECK-NEXT: vpickve2gr.b $a0, $vr2, 1
-; CHECK-NEXT: vinsgr2vr.b $vr0, $a0, 8
-; CHECK-NEXT: vpickve2gr.b $a0, $vr2, 3
-; CHECK-NEXT: vinsgr2vr.b $vr0, $a0, 9
-; CHECK-NEXT: vpickve2gr.b $a0, $vr2, 5
-; CHECK-NEXT: vinsgr2vr.b $vr0, $a0, 10
-; CHECK-NEXT: vpickve2gr.b $a0, $vr2, 7
-; CHECK-NEXT: vinsgr2vr.b $vr0, $a0, 11
-; CHECK-NEXT: vpickve2gr.b $a0, $vr2, 9
-; CHECK-NEXT: vinsgr2vr.b $vr0, $a0, 12
-; CHECK-NEXT: vpickve2gr.b $a0, $vr2, 11
-; CHECK-NEXT: vinsgr2vr.b $vr0, $a0, 13
-; CHECK-NEXT: vpickve2gr.b $a0, $vr2, 13
-; CHECK-NEXT: vinsgr2vr.b $vr0, $a0, 14
-; CHECK-NEXT: vpickve2gr.b $a0, $vr2, 15
-; CHECK-NEXT: vinsgr2vr.b $vr0, $a0, 15
-; CHECK-NEXT: vpickve2gr.b $a0, $vr1, 0
-; CHECK-NEXT: vinsgr2vr.b $vr2, $a0, 0
-; CHECK-NEXT: vpickve2gr.b $a0, $vr1, 2
-; CHECK-NEXT: vinsgr2vr.b $vr2, $a0, 1
-; CHECK-NEXT: vpickve2gr.b $a0, $vr1, 4
-; CHECK-NEXT: vinsgr2vr.b $vr2, $a0, 2
-; CHECK-NEXT: vpickve2gr.b $a0, $vr1, 6
-; CHECK-NEXT: vinsgr2vr.b $vr2, $a0, 3
-; CHECK-NEXT: vpickve2gr.b $a0, $vr1, 8
-; CHECK-NEXT: vinsgr2vr.b $vr2, $a0, 4
-; CHECK-NEXT: vpickve2gr.b $a0, $vr1, 10
-; CHECK-NEXT: vinsgr2vr.b $vr2, $a0, 5
-; CHECK-NEXT: vpickve2gr.b $a0, $vr1, 12
-; CHECK-NEXT: vinsgr2vr.b $vr2, $a0, 6
-; CHECK-NEXT: vpickve2gr.b $a0, $vr1, 14
-; CHECK-NEXT: vinsgr2vr.b $vr2, $a0, 7
-; CHECK-NEXT: xvpermi.d $xr1, $xr1, 14
-; CHECK-NEXT: vpickve2gr.b $a0, $vr1, 0
-; CHECK-NEXT: vinsgr2vr.b $vr2, $a0, 8
-; CHECK-NEXT: vpickve2gr.b $a0, $vr1, 2
-; CHECK-NEXT: vinsgr2vr.b $vr2, $a0, 9
-; CHECK-NEXT: vpickve2gr.b $a0, $vr1, 4
-; CHECK-NEXT: vinsgr2vr.b $vr2, $a0, 10
-; CHECK-NEXT: vpickve2gr.b $a0, $vr1, 6
-; CHECK-NEXT: vinsgr2vr.b $vr2, $a0, 11
-; CHECK-NEXT: vpickve2gr.b $a0, $vr1, 8
-; CHECK-NEXT: vinsgr2vr.b $vr2, $a0, 12
-; CHECK-NEXT: vpickve2gr.b $a0, $vr1, 10
-; CHECK-NEXT: vinsgr2vr.b $vr2, $a0, 13
-; CHECK-NEXT: vpickve2gr.b $a0, $vr1, 12
-; CHECK-NEXT: vinsgr2vr.b $vr2, $a0, 14
-; CHECK-NEXT: vpickve2gr.b $a0, $vr1, 14
-; CHECK-NEXT: vinsgr2vr.b $vr2, $a0, 15
-; CHECK-NEXT: vext2xv.hu.bu $xr0, $xr0
-; CHECK-NEXT: vext2xv.hu.bu $xr1, $xr2
-; CHECK-NEXT: xvsub.h $xr0, $xr0, $xr1
+; CHECK-NEXT: xvhsubw.hu.bu $xr0, $xr0, $xr1
; CHECK-NEXT: xvst $xr0, $a2, 0
; CHECK-NEXT: ret
entry:
@@ -455,43 +265,7 @@ define void @xvhsubw_wu_hu(ptr %a, ptr %b, ptr %r) nounwind {
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xvld $xr0, $a0, 0
; CHECK-NEXT: xvld $xr1, $a1, 0
-; CHECK-NEXT: vpickve2gr.h $a0, $vr0, 1
-; CHECK-NEXT: vinsgr2vr.h $vr2, $a0, 0
-; CHECK-NEXT: vpickve2gr.h $a0, $vr0, 3
-; CHECK-NEXT: vinsgr2vr.h $vr2, $a0, 1
-; CHECK-NEXT: vpickve2gr.h $a0, $vr0, 5
-; CHECK-NEXT: vinsgr2vr.h $vr2, $a0, 2
-; CHECK-NEXT: vpickve2gr.h $a0, $vr0, 7
-; CHECK-NEXT: vinsgr2vr.h $vr2, $a0, 3
-; CHECK-NEXT: xvpermi.d $xr0, $xr0, 14
-; CHECK-NEXT: vpickve2gr.h $a0, $vr0, 1
-; CHECK-NEXT: vinsgr2vr.h $vr2, $a0, 4
-; CHECK-NEXT: vpickve2gr.h $a0, $vr0, 3
-; CHECK-NEXT: vinsgr2vr.h $vr2, $a0, 5
-; CHECK-NEXT: vpickve2gr.h $a0, $vr0, 5
-; CHECK-NEXT: vinsgr2vr.h $vr2, $a0, 6
-; CHECK-NEXT: vpickve2gr.h $a0, $vr0, 7
-; CHECK-NEXT: vinsgr2vr.h $vr2, $a0, 7
-; CHECK-NEXT: vpickve2gr.h $a0, $vr1, 0
-; CHECK-NEXT: vinsgr2vr.h $vr0, $a0, 0
-; CHECK-NEXT: vpickve2gr.h $a0, $vr1, 2
-; CHECK-NEXT: vinsgr2vr.h $vr0, $a0, 1
-; CHECK-NEXT: vpickve2gr.h $a0, $vr1, 4
-; CHECK-NEXT: vinsgr2vr.h $vr0, $a0, 2
-; CHECK-NEXT: vpickve2gr.h $a0, $vr1, 6
-; CHECK-NEXT: vinsgr2vr.h $vr0, $a0, 3
-; CHECK-NEXT: xvpermi.d $xr1, $xr1, 14
-; CHECK-NEXT: vpickve2gr.h $a0, $vr1, 0
-; CHECK-NEXT: vinsgr2vr.h $vr0, $a0, 4
-; CHECK-NEXT: vpickve2gr.h $a0, $vr1, 2
-; CHECK-NEXT: vinsgr2vr.h $vr0, $a0, 5
-; CHECK-NEXT: vpickve2gr.h $a0, $vr1, 4
-; CHECK-NEXT: vinsgr2vr.h $vr0, $a0, 6
-; CHECK-NEXT: vpickve2gr.h $a0, $vr1, 6
-; CHECK-NEXT: vinsgr2vr.h $vr0, $a0, 7
-; CHECK-NEXT: vext2xv.wu.hu $xr1, $xr2
-; CHECK-NEXT: vext2xv.wu.hu $xr0, $xr0
-; CHECK-NEXT: xvsub.w $xr0, $xr1, $xr0
+; CHECK-NEXT: xvhsubw.wu.hu $xr0, $xr0, $xr1
; CHECK-NEXT: xvst $xr0, $a2, 0
; CHECK-NEXT: ret
entry:
@@ -513,25 +287,7 @@ define void @xvhsubw_du_wu(ptr %a, ptr %b, ptr %r) nounwind {
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xvld $xr0, $a0, 0
; CHECK-NEXT: xvld $xr1, $a1, 0
-; CHECK-NEXT: xvpickve2gr.w $a0, $xr0, 1
-; CHECK-NEXT: vinsgr2vr.w $vr2, $a0, 0
-; CHECK-NEXT: xvpickve2gr.w $a0, $xr0, 3
-; CHECK-NEXT: vinsgr2vr.w $vr2, $a0, 1
-; CHECK-NEXT: xvpickve2gr.w $a0, $xr0, 5
-; CHECK-NEXT: vinsgr2vr.w $vr2, $a0, 2
-; CHECK-NEXT: xvpickve2gr.w $a0, $xr0, 7
-; CHECK-NEXT: vinsgr2vr.w $vr2, $a0, 3
-; CHECK-NEXT: xvpickve2gr.w $a0, $xr1, 0
-; CHECK-NEXT: vinsgr2vr.w $vr0, $a0, 0
-; CHECK-NEXT: xvpickve2gr.w $a0, $xr1, 2
-; CHECK-NEXT: vinsgr2vr.w $vr0, $a0, 1
-; CHECK-NEXT: xvpickve2gr.w $a0, $xr1, 4
-; CHECK-NEXT: vinsgr2vr.w $vr0, $a0, 2
-; CHECK-NEXT: xvpickve2gr.w $a0, $xr1, 6
-; CHECK-NEXT: vinsgr2vr.w $vr0, $a0, 3
-; CHECK-NEXT: vext2xv.du.wu $xr1, $xr2
-; CHECK-NEXT: vext2xv.du.wu $xr0, $xr0
-; CHECK-NEXT: xvsub.d $xr0, $xr1, $xr0
+; CHECK-NEXT: xvhsubw.du.wu $xr0, $xr0, $xr1
; CHECK-NEXT: xvst $xr0, $a2, 0
; CHECK-NEXT: ret
entry:
diff --git a/llvm/test/CodeGen/LoongArch/lsx/vhaddw.ll b/llvm/test/CodeGen/LoongArch/lsx/vhaddw.ll
index 5a89e26de741f..8a75f7c234e8b 100644
--- a/llvm/test/CodeGen/LoongArch/lsx/vhaddw.ll
+++ b/llvm/test/CodeGen/LoongArch/lsx/vhaddw.ll
@@ -60,13 +60,7 @@ define void @vhaddw_h_b(ptr %a, ptr %b, ptr %r) nounwind {
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: vld $vr0, $a0, 0
; CHECK-NEXT: vld $vr1, $a1, 0
-; CHECK-NEXT: vpickod.b $vr0, $vr0, $vr0
-; CHECK-NEXT: vpickev.b $vr1, $vr1, $vr1
-; CHECK-NEXT: vslti.b $vr2, $vr0, 0
-; CHECK-NEXT: vilvl.b $vr0, $vr2, $vr0
-; CHECK-NEXT: vslti.b $vr2, $vr1, 0
-; CHECK-NEXT: vilvl.b $vr1, $vr2, $vr1
-; CHECK-NEXT: vadd.h $vr0, $vr0, $vr1
+; CHECK-NEXT: vhaddw.h.b $vr0, $vr0, $vr1
; CHECK-NEXT: vst $vr0, $a2, 0
; CHECK-NEXT: ret
entry:
@@ -88,13 +82,7 @@ define void @vhaddw_w_h(ptr %a, ptr %b, ptr %r) nounwind {
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: vld $vr0, $a0, 0
; CHECK-NEXT: vld $vr1, $a1, 0
-; CHECK-NEXT: vpickod.h $vr0, $vr0, $vr0
-; CHECK-NEXT: vpickev.h $vr1, $vr1, $vr1
-; CHECK-NEXT: vslti.h $vr2, $vr0, 0
-; CHECK-NEXT: vilvl.h $vr0, $vr2, $vr0
-; CHECK-NEXT: vslti.h $vr2, $vr1, 0
-; CHECK-NEXT: vilvl.h $vr1, $vr2, $vr1
-; CHECK-NEXT: vadd.w $vr0, $vr0, $vr1
+; CHECK-NEXT: vhaddw.w.h $vr0, $vr0, $vr1
; CHECK-NEXT: vst $vr0, $a2, 0
; CHECK-NEXT: ret
entry:
@@ -116,13 +104,7 @@ define void @vhaddw_d_w(ptr %a, ptr %b, ptr %r) nounwind {
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: vld $vr0, $a0, 0
; CHECK-NEXT: vld $vr1, $a1, 0
-; CHECK-NEXT: vshuf4i.w $vr0, $vr0, 13
-; CHECK-NEXT: vshuf4i.w $vr1, $vr1, 8
-; CHECK-NEXT: vslti.w $vr2, $vr0, 0
-; CHECK-NEXT: vilvl.w $vr0, $vr2, $vr0
-; CHECK-NEXT: vslti.w $vr2, $vr1, 0
-; CHECK-NEXT: vilvl.w $vr1, $vr2, $vr1
-; CHECK-NEXT: vadd.d $vr0, $vr0, $vr1
+; CHECK-NEXT: vhaddw.d.w $vr0, $vr0, $vr1
; CHECK-NEXT: vst $vr0, $a2, 0
; CHECK-NEXT: ret
entry:
@@ -142,12 +124,7 @@ define void @vhaddw_hu_bu(ptr %a, ptr %b, ptr %r) nounwind {
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: vld $vr0, $a0, 0
; CHECK-NEXT: vld $vr1, $a1, 0
-; CHECK-NEXT: pcalau12i $a0, %pc_hi20(.LCPI4_0)
-; CHECK-NEXT: vld $vr2, $a0, %pc_lo12(.LCPI4_0)
-; CHECK-NEXT: vrepli.b $vr3, 0
-; CHECK-NEXT: vpackod.b $vr0, $vr3, $vr0
-; CHECK-NEXT: vshuf.b $vr1, $vr3, $vr1, $vr2
-; CHECK-NEXT: vadd.h $vr0, $vr0, $vr1
+; CHECK-NEXT: vhaddw.hu.bu $vr0, $vr0, $vr1
; CHECK-NEXT: vst $vr0, $a2, 0
; CHECK-NEXT: ret
entry:
@@ -169,12 +146,7 @@ define void @vhaddw_wu_hu(ptr %a, ptr %b, ptr %r) nounwind {
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: vld $vr0, $a0, 0
; CHECK-NEXT: vld $vr1, $a1, 0
-; CHECK-NEXT: pcalau12i $a0, %pc_hi20(.LCPI5_0)
-; CHECK-NEXT: vld $vr2, $a0, %pc_lo12(.LCPI5_0)
-; CHECK-NEXT: vrepli.b $vr3, 0
-; CHECK-NEXT: vpackod.h $vr0, $vr3, $vr0
-; CHECK-NEXT: vshuf.h $vr2, $vr3, $vr1
-; CHECK-NEXT: vadd.w $vr0, $vr0, $vr2
+; CHECK-NEXT: vhaddw.wu.hu $vr0, $vr0, $vr1
; CHECK-NEXT: vst $vr0, $a2, 0
; CHECK-NEXT: ret
entry:
@@ -196,12 +168,7 @@ define void @vhaddw_du_wu(ptr %a, ptr %b, ptr %r) nounwind {
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: vld $vr0, $a0, 0
; CHECK-NEXT: vld $vr1, $a1, 0
-; CHECK-NEXT: pcalau12i $a0, %pc_hi20(.LCPI6_0)
-; CHECK-NEXT: vld $vr2, $a0, %pc_lo12(.LCPI6_0)
-; CHECK-NEXT: vrepli.b $vr3, 0
-; CHECK-NEXT: vpackod.w $vr0, $vr3, $vr0
-; CHECK-NEXT: vshuf.w $vr2, $vr3, $vr1
-; CHECK-NEXT: vadd.d $vr0, $vr0, $vr2
+; CHECK-NEXT: vhaddw.du.wu $vr0, $vr0, $vr1
; CHECK-NEXT: vst $vr0, $a2, 0
; CHECK-NEXT: ret
entry:
diff --git a/llvm/test/CodeGen/LoongArch/lsx/vhsubw.ll b/llvm/test/CodeGen/LoongArch/lsx/vhsubw.ll
index 79d02daa0648f..6960c043163c7 100644
--- a/llvm/test/CodeGen/LoongArch/lsx/vhsubw.ll
+++ b/llvm/test/CodeGen/LoongArch/lsx/vhsubw.ll
@@ -60,13 +60,7 @@ define void @vhsubw_h_b(ptr %a, ptr %b, ptr %r) nounwind {
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: vld $vr0, $a0, 0
; CHECK-NEXT: vld $vr1, $a1, 0
-; CHECK-NEXT: vpickod.b $vr0, $vr0, $vr0
-; CHECK-NEXT: vpickev.b $vr1, $vr1, $vr1
-; CHECK-NEXT: vslti.b $vr2, $vr0, 0
-; CHECK-NEXT: vilvl.b $vr0, $vr2, $vr0
-; CHECK-NEXT: vslti.b $vr2, $vr1, 0
-; CHECK-NEXT: vilvl.b $vr1, $vr2, $vr1
-; CHECK-NEXT: vsub.h $vr0, $vr0, $vr1
+; CHECK-NEXT: vhsubw.h.b $vr0, $vr0, $vr1
; CHECK-NEXT: vst $vr0, $a2, 0
; CHECK-NEXT: ret
entry:
@@ -88,13 +82,7 @@ define void @vhsubw_w_h(ptr %a, ptr %b, ptr %r) nounwind {
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: vld $vr0, $a0, 0
; CHECK-NEXT: vld $vr1, $a1, 0
-; CHECK-NEXT: vpickod.h $vr0, $vr0, $vr0
-; CHECK-NEXT: vpickev.h $vr1, $vr1, $vr1
-; CHECK-NEXT: vslti.h $vr2, $vr0, 0
-; CHECK-NEXT: vilvl.h $vr0, $vr2, $vr0
-; CHECK-NEXT: vslti.h $vr2, $vr1, 0
-; CHECK-NEXT: vilvl.h $vr1, $vr2, $vr1
-; CHECK-NEXT: vsub.w $vr0, $vr0, $vr1
+; CHECK-NEXT: vhsubw.w.h $vr0, $vr0, $vr1
; CHECK-NEXT: vst $vr0, $a2, 0
; CHECK-NEXT: ret
entry:
@@ -116,13 +104,7 @@ define void @vhsubw_d_w(ptr %a, ptr %b, ptr %r) nounwind {
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: vld $vr0, $a0, 0
; CHECK-NEXT: vld $vr1, $a1, 0
-; CHECK-NEXT: vshuf4i.w $vr0, $vr0, 13
-; CHECK-NEXT: vshuf4i.w $vr1, $vr1, 8
-; CHECK-NEXT: vslti.w $vr2, $vr0, 0
-; CHECK-NEXT: vilvl.w $vr0, $vr2, $vr0
-; CHECK-NEXT: vslti.w $vr2, $vr1, 0
-; CHECK-NEXT: vilvl.w $vr1, $vr2, $vr1
-; CHECK-NEXT: vsub.d $vr0, $vr0, $vr1
+; CHECK-NEXT: vhsubw.d.w $vr0, $vr0, $vr1
; CHECK-NEXT: vst $vr0, $a2, 0
; CHECK-NEXT: ret
entry:
@@ -142,12 +124,7 @@ define void @vhsubw_hu_bu(ptr %a, ptr %b, ptr %r) nounwind {
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: vld $vr0, $a0, 0
; CHECK-NEXT: vld $vr1, $a1, 0
-; CHECK-NEXT: pcalau12i $a0, %pc_hi20(.LCPI4_0)
-; CHECK-NEXT: vld $vr2, $a0, %pc_lo12(.LCPI4_0)
-; CHECK-NEXT: vrepli.b $vr3, 0
-; CHECK-NEXT: vpackod.b $vr0, $vr3, $vr0
-; CHECK-NEXT: vshuf.b $vr1, $vr3, $vr1, $vr2
-; CHECK-NEXT: vsub.h $vr0, $vr0, $vr1
+; CHECK-NEXT: vhsubw.hu.bu $vr0, $vr0, $vr1
; CHECK-NEXT: vst $vr0, $a2, 0
; CHECK-NEXT: ret
entry:
@@ -169,12 +146,7 @@ define void @vhsubw_wu_hu(ptr %a, ptr %b, ptr %r) nounwind {
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: vld $vr0, $a0, 0
; CHECK-NEXT: vld $vr1, $a1, 0
-; CHECK-NEXT: pcalau12i $a0, %pc_hi20(.LCPI5_0)
-; CHECK-NEXT: vld $vr2, $a0, %pc_lo12(.LCPI5_0)
-; CHECK-NEXT: vrepli.b $vr3, 0
-; CHECK-NEXT: vpackod.h $vr0, $vr3, $vr0
-; CHECK-NEXT: vshuf.h $vr2, $vr3, $vr1
-; CHECK-NEXT: vsub.w $vr0, $vr0, $vr2
+; CHECK-NEXT: vhsubw.wu.hu $vr0, $vr0, $vr1
; CHECK-NEXT: vst $vr0, $a2, 0
; CHECK-NEXT: ret
entry:
@@ -196,12 +168,7 @@ define void @vhsubw_du_wu(ptr %a, ptr %b, ptr %r) nounwind {
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: vld $vr0, $a0, 0
; CHECK-NEXT: vld $vr1, $a1, 0
-; CHECK-NEXT: pcalau12i $a0, %pc_hi20(.LCPI6_0)
-; CHECK-NEXT: vld $vr2, $a0, %pc_lo12(.LCPI6_0)
-; CHECK-NEXT: vrepli.b $vr3, 0
-; CHECK-NEXT: vpackod.w $vr0, $vr3, $vr0
-; CHECK-NEXT: vshuf.w $vr2, $vr3, $vr1
-; CHECK-NEXT: vsub.d $vr0, $vr0, $vr2
+; CHECK-NEXT: vhsubw.du.wu $vr0, $vr0, $vr1
; CHECK-NEXT: vst $vr0, $a2, 0
; CHECK-NEXT: ret
entry:
More information about the llvm-branch-commits
mailing list