[llvm] [RISCV][P-ext] Improve the codegen for unzip-like shuffle and buildvector (PR #208763)
Hongyu Chen via llvm-commits
llvm-commits at lists.llvm.org
Fri Jul 10 21:56:15 PDT 2026
https://github.com/XChy updated https://github.com/llvm/llvm-project/pull/208763
>From 8ec9f361c5514f6db3985205098a1d1c75a4f79e Mon Sep 17 00:00:00 2001
From: XChy <xxs_chy at outlook.com>
Date: Fri, 10 Jul 2026 23:38:51 +0800
Subject: [PATCH 1/6] [RISCV][P-ext] Improve the codegen for unzip-like shuffle
and buildvector
---
llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 126 +++++++++--
llvm/lib/Target/RISCV/RISCVInstrInfoP.td | 36 +++
llvm/test/CodeGen/RISCV/rvp-srl-bitcast-bv.ll | 6 +-
llvm/test/CodeGen/RISCV/rvp-zip.ll | 205 +++++++++++++++---
4 files changed, 315 insertions(+), 58 deletions(-)
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index fda994a04b00f..dca57ce4ea388 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -612,7 +612,7 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
setCondCodeAction({ISD::SETNE, ISD::SETGT}, VTs, Custom);
if (!Subtarget.is64Bit())
- setOperationAction(ISD::BUILD_VECTOR, MVT::v4i8, Custom);
+ setOperationAction(ISD::BUILD_VECTOR, {MVT::v2i16, MVT::v4i8}, Custom);
// P extension vector comparisons produce all 1s for true, all 0s for false
setBooleanVectorContents(ZeroOrNegativeOneBooleanContent);
@@ -4680,6 +4680,49 @@ static SDValue lowerBuildVectorViaPacking(SDValue Op, SelectionDAG &DAG,
DAG.getBuildVector(WideVecVT, DL, NewOperands));
}
+static SDValue lowerBuildVectorAsRV32PNarrowingShift(SDValue Op,
+ SelectionDAG &DAG) {
+ // Match a legalized single-source deinterleave shuffle:
+ // BUILD_VECTOR extractelt(src, 0), extractelt(src, 2), ...
+ // BUILD_VECTOR extractelt(src, 1), extractelt(src, 3), ...
+ // and lower it to an RV32 P narrowing shift.
+ MVT VT = Op.getSimpleValueType();
+ if (VT != MVT::v4i8 && VT != MVT::v2i16)
+ return SDValue();
+
+ using namespace SDPatternMatch;
+ MVT SrcVT = VT == MVT::v4i8 ? MVT::v8i8 : MVT::v4i16;
+ unsigned EltBits = VT.getVectorElementType().getSizeInBits();
+ SDValue Src;
+ SmallVector<int, 4> ExtractIndices;
+ for (SDValue Lane : Op->op_values()) {
+ if (Lane.isUndef()) {
+ ExtractIndices.push_back(-1);
+ continue;
+ }
+
+ SDValue LaneSrc;
+ int64_t Idx;
+ if (!sd_match(Lane, m_ExtractElt(m_Value(LaneSrc), m_ConstInt(Idx))))
+ return SDValue();
+
+ if (LaneSrc.getSimpleValueType() != SrcVT || (Src && Src != LaneSrc))
+ return SDValue();
+
+ Src = LaneSrc;
+ ExtractIndices.push_back(Idx);
+ }
+
+ unsigned Index = 0;
+ if (!Src ||
+ !ShuffleVectorInst::isDeInterleaveMaskOfFactor(ExtractIndices, 2, Index))
+ return SDValue();
+
+ SDLoc DL(Op);
+ return DAG.getNode(RISCVISD::PNSRL, DL, VT, Src,
+ DAG.getConstant(Index * EltBits, DL, MVT::i32));
+}
+
static SDValue lowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG,
const RISCVSubtarget &Subtarget) {
MVT VT = Op.getSimpleValueType();
@@ -4691,30 +4734,43 @@ static SDValue lowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG,
SDLoc DL(Op);
if (Subtarget.isRV32() && Subtarget.hasStdExtP()) {
- if (VT != MVT::v4i8)
- return SDValue();
+ if (SDValue V = lowerBuildVectorAsRV32PNarrowingShift(Op, DAG))
+ return V;
- // <4 x i8> BUILD_VECTOR a, b, c, d -> PACK(PPACK.DH pair(a, c), pair(b, d))
- SDValue Val0 =
- DAG.getNode(ISD::SCALAR_TO_VECTOR, DL, MVT::v4i8, Op->getOperand(0));
- SDValue Val1 =
- DAG.getNode(ISD::SCALAR_TO_VECTOR, DL, MVT::v4i8, Op->getOperand(1));
- SDValue Val2 =
- DAG.getNode(ISD::SCALAR_TO_VECTOR, DL, MVT::v4i8, Op->getOperand(2));
- SDValue Val3 =
- DAG.getNode(ISD::SCALAR_TO_VECTOR, DL, MVT::v4i8, Op->getOperand(3));
- SDValue PPairDB =
- DAG.getNode(RISCVISD::PPAIRE_DB, DL, {MVT::v4i8, MVT::v4i8},
- {Val0, Val2, Val1, Val3});
+ if (VT == MVT::v2i16) {
+ SDValue Lo = DAG.getAnyExtOrTrunc(Op->getOperand(0), DL, MVT::i32);
+ SDValue Hi = DAG.getAnyExtOrTrunc(Op->getOperand(1), DL, MVT::i32);
+ return DAG.getBitcast(
+ MVT::v2i16,
+ SDValue(DAG.getMachineNode(RISCV::PACK, DL, MVT::i32, {Lo, Hi}), 0));
+ }
+
+ if (VT == MVT::v4i8) {
+ // <4 x i8> BUILD_VECTOR a, b, c, d -> PACK(PPACK.DH pair(a, c), pair(b, d))
+ SDValue Val0 =
+ DAG.getNode(ISD::SCALAR_TO_VECTOR, DL, MVT::v4i8, Op->getOperand(0));
+ SDValue Val1 =
+ DAG.getNode(ISD::SCALAR_TO_VECTOR, DL, MVT::v4i8, Op->getOperand(1));
+ SDValue Val2 =
+ DAG.getNode(ISD::SCALAR_TO_VECTOR, DL, MVT::v4i8, Op->getOperand(2));
+ SDValue Val3 =
+ DAG.getNode(ISD::SCALAR_TO_VECTOR, DL, MVT::v4i8, Op->getOperand(3));
+ SDValue PPairDB =
+ DAG.getNode(RISCVISD::PPAIRE_DB, DL, {MVT::v4i8, MVT::v4i8},
+ {Val0, Val2, Val1, Val3});
- return DAG.getNode(
- ISD::BITCAST, DL, MVT::v4i8,
- SDValue(
- DAG.getMachineNode(
- RISCV::PACK, DL, MVT::i32,
- {DAG.getNode(ISD::BITCAST, DL, MVT::i32, PPairDB.getValue(0)),
- DAG.getNode(ISD::BITCAST, DL, MVT::i32, PPairDB.getValue(1))}),
- 0));
+ return DAG.getNode(
+ ISD::BITCAST, DL, MVT::v4i8,
+ SDValue(
+ DAG.getMachineNode(RISCV::PACK, DL, MVT::i32,
+ {DAG.getNode(ISD::BITCAST, DL, MVT::i32,
+ PPairDB.getValue(0)),
+ DAG.getNode(ISD::BITCAST, DL, MVT::i32,
+ PPairDB.getValue(1))}),
+ 0));
+ }
+
+ llvm_unreachable("Unexpected RV32 P BUILD_VECTOR type");
}
// Proper support for f16 requires Zvfh. bf16 always requires special
@@ -6342,6 +6398,28 @@ static SDValue lowerVECTOR_SHUFFLEAsPZip(ShuffleVectorSDNode *SVN,
return SDValue();
}
+// Match a deinterleave shuffle that forms a P-extension packed unzip:
+// <a0, a2, ..., b0, b2, ...> -> unzip*p
+// <a1, a3, ..., b1, b3, ...> -> unzip*hp
+static SDValue lowerVECTOR_SHUFFLEAsPUnzip(ShuffleVectorSDNode *SVN,
+ SelectionDAG &DAG, bool IsRV64) {
+ MVT VT = SVN->getSimpleValueType(0);
+ if (!IsRV64 || (VT != MVT::v8i8 && VT != MVT::v4i16))
+ return SDValue();
+
+ SDValue V1 = SVN->getOperand(0);
+ SDValue V2 = SVN->getOperand(1);
+ SDLoc DL(SVN);
+ ArrayRef<int> Mask = SVN->getMask();
+
+ unsigned Index = 0;
+ if (!ShuffleVectorInst::isDeInterleaveMaskOfFactor(Mask, 2, Index))
+ return SDValue();
+
+ unsigned Opc = Index == 0 ? RISCVISD::PUNZIPE : RISCVISD::PUNZIPO;
+ return DAG.getNode(Opc, DL, VT, V1, V2);
+}
+
SDValue RISCVTargetLowering::lowerVECTOR_SHUFFLE(SDValue Op,
SelectionDAG &DAG) const {
SDValue V1 = Op.getOperand(0);
@@ -6377,6 +6455,8 @@ SDValue RISCVTargetLowering::lowerVECTOR_SHUFFLE(SDValue Op,
return DAG.getBitcast(VT, Srl);
}
+ if (SDValue V = lowerVECTOR_SHUFFLEAsPUnzip(SVN, DAG, Subtarget.is64Bit()))
+ return V;
if (SDValue V = lowerVECTOR_SHUFFLEAsPZip(SVN, DAG))
return V;
return SDValue();
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoP.td b/llvm/lib/Target/RISCV/RISCVInstrInfoP.td
index 7fa7c96ca99ca..8facdcbb0e8c6 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoP.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoP.td
@@ -1883,6 +1883,12 @@ def riscv_psrl : RVSDNode<"PSRL", SDT_RISCVPackedShift>;
def riscv_psra : RVSDNode<"PSRA", SDT_RISCVPackedShift>;
def riscv_pssha : RVSDNode<"PSSHA", SDT_RISCVPackedShift>;
+// RV32 packed narrowing shift.
+def SDT_RISCVPackedNarrowingShift
+ : SDTypeProfile<1, 2, [SDTCisVec<0>, SDTCisVec<1>,
+ SDTCisVT<2, XLenVT>]>;
+def riscv_pnsrl : RVSDNode<"PNSRL", SDT_RISCVPackedNarrowingShift>;
+
// The immediate for these is the number of trailing ones in the max value.
def riscv_sati : RVSDNode<"SATI", SDTIntBinOp>;
def riscv_usati : RVSDNode<"USATI", SDTIntBinOp>;
@@ -1914,6 +1920,13 @@ def SDT_RISCVPZip : SDTypeProfile<1, 2, [SDTCisVec<0>,
SDTCisSameAs<0, 2>]>;
def riscv_pzip : RVSDNode<"PZIP", SDT_RISCVPZip>;
+// Deinterleave the even/odd lanes of two packed vectors.
+def SDT_RISCVPUnzip : SDTypeProfile<1, 2, [SDTCisVec<0>,
+ SDTCisSameAs<0, 1>,
+ SDTCisSameAs<0, 2>]>;
+def riscv_punzipe : RVSDNode<"PUNZIPE", SDT_RISCVPUnzip>;
+def riscv_punzipo : RVSDNode<"PUNZIPO", SDT_RISCVPUnzip>;
+
// Add one to the immediate. Used by RISCVISD::SATI.
def IncImm : SDNodeXForm<imm, [{
return CurDAG->getTargetConstant(N->getZExtValue() + 1, SDLoc(N),
@@ -2293,6 +2306,11 @@ let append Predicates = [IsRV32] in {
def : Pat<(v4i8 (trunc (v4i16 GPRPair:$rs))), (PNSRLI_B GPRPair:$rs, 0)>;
def : Pat<(v2i16 (trunc (v2i32 GPRPair:$rs))), (PNSRLI_H GPRPair:$rs, 0)>;
+ def : Pat<(v4i8 (riscv_pnsrl (v8i8 GPRPair:$rs1), uimm4:$imm)),
+ (PNSRLI_B GPRPair:$rs1, uimm4:$imm)>;
+ def : Pat<(v2i16 (riscv_pnsrl (v4i16 GPRPair:$rs1), uimm5:$imm)),
+ (PNSRLI_H GPRPair:$rs1, uimm5:$imm)>;
+
def : Pat<(v4i8 (trunc (v4i16 (riscv_psrl GPRPair:$rs1, uimm4:$imm)))),
(PNSRLI_B GPRPair:$rs1, uimm4:$imm)>;
def : Pat<(v2i16 (trunc (v2i32 (riscv_psrl GPRPair:$rs1, uimm5:$imm)))),
@@ -2765,6 +2783,24 @@ let append Predicates = [IsRV64] in {
def : Pat<(v4i16 (zext_invec (v8i8 GPR:$rs))), (ZIP8P GPR:$rs, (v8i8 X0))>;
def : Pat<(v2i32 (zext_invec (v4i16 GPR:$rs))), (ZIP16P GPR:$rs, (v4i16 X0))>;
+ // Packed unzip.
+ def : Pat<(v8i8 (riscv_punzipe (v8i8 GPR:$rs), (v8i8 undef))),
+ (UNZIP8P GPR:$rs, (v8i8 X0))>;
+ def : Pat<(v8i8 (riscv_punzipo (v8i8 GPR:$rs), (v8i8 undef))),
+ (UNZIP8HP GPR:$rs, (v8i8 X0))>;
+ def : Pat<(v4i16 (riscv_punzipe (v4i16 GPR:$rs), (v4i16 undef))),
+ (UNZIP16P GPR:$rs, (v4i16 X0))>;
+ def : Pat<(v4i16 (riscv_punzipo (v4i16 GPR:$rs), (v4i16 undef))),
+ (UNZIP16HP GPR:$rs, (v4i16 X0))>;
+ def : Pat<(v8i8 (riscv_punzipe (v8i8 GPR:$rs1), (v8i8 GPR:$rs2))),
+ (UNZIP8P GPR:$rs1, GPR:$rs2)>;
+ def : Pat<(v8i8 (riscv_punzipo (v8i8 GPR:$rs1), (v8i8 GPR:$rs2))),
+ (UNZIP8HP GPR:$rs1, GPR:$rs2)>;
+ def : Pat<(v4i16 (riscv_punzipe (v4i16 GPR:$rs1), (v4i16 GPR:$rs2))),
+ (UNZIP16P GPR:$rs1, GPR:$rs2)>;
+ def : Pat<(v4i16 (riscv_punzipo (v4i16 GPR:$rs1), (v4i16 GPR:$rs2))),
+ (UNZIP16HP GPR:$rs1, GPR:$rs2)>;
+
// Packed zip.
def : Pat<(v8i8 (riscv_pzip (v8i8 GPR:$rs1), (v8i8 GPR:$rs2))),
(ZIP8P GPR:$rs1, GPR:$rs2)>;
diff --git a/llvm/test/CodeGen/RISCV/rvp-srl-bitcast-bv.ll b/llvm/test/CodeGen/RISCV/rvp-srl-bitcast-bv.ll
index 0a9b3ff7c5505..4692dbb7fdc1b 100644
--- a/llvm/test/CodeGen/RISCV/rvp-srl-bitcast-bv.ll
+++ b/llvm/test/CodeGen/RISCV/rvp-srl-bitcast-bv.ll
@@ -11,9 +11,9 @@ define i16 @srl_bitcast_buildvector_extract_last(<2 x i16> %v, ptr %p) {
; CHECK-RV32-NEXT: srai a3, a0, 16
; CHECK-RV32-NEXT: div a3, a2, a3
; CHECK-RV32-NEXT: sext.h a0, a0
-; CHECK-RV32-NEXT: div a2, a2, a0
-; CHECK-RV32-NEXT: zext.h a0, a3
-; CHECK-RV32-NEXT: pack a2, a2, a3
+; CHECK-RV32-NEXT: div a0, a2, a0
+; CHECK-RV32-NEXT: pack a2, a0, a3
+; CHECK-RV32-NEXT: srli a0, a2, 16
; CHECK-RV32-NEXT: sw a2, 0(a1)
; CHECK-RV32-NEXT: ret
;
diff --git a/llvm/test/CodeGen/RISCV/rvp-zip.ll b/llvm/test/CodeGen/RISCV/rvp-zip.ll
index 2f146afc23427..766db01267521 100644
--- a/llvm/test/CodeGen/RISCV/rvp-zip.ll
+++ b/llvm/test/CodeGen/RISCV/rvp-zip.ll
@@ -37,20 +37,12 @@ define <4 x i16> @test_pzip_v4i16(<2 x i16> %a, <2 x i16> %b) {
define <4 x i8> @test_punzipe_v4i8(<8 x i8> %a) {
; RV32-LABEL: test_punzipe_v4i8:
; RV32: # %bb.0:
-; RV32-NEXT: srli a3, a1, 16
-; RV32-NEXT: srli a2, a0, 16
-; RV32-NEXT: ppaire.db a0, a0, a2
-; RV32-NEXT: pack a0, a0, a1
+; RV32-NEXT: pncvt.b a0, a0
; RV32-NEXT: ret
;
; RV64-LABEL: test_punzipe_v4i8:
; RV64: # %bb.0:
-; RV64-NEXT: srli a1, a0, 48
-; RV64-NEXT: srli a2, a0, 32
-; RV64-NEXT: srli a3, a0, 16
-; RV64-NEXT: ppaire.b a1, a2, a1
-; RV64-NEXT: ppaire.b a0, a0, a3
-; RV64-NEXT: ppaire.h a0, a0, a1
+; RV64-NEXT: pncvt.wb a0, a0
; RV64-NEXT: ret
%r = shufflevector <8 x i8> %a, <8 x i8> poison, <4 x i32> <i32 0, i32 2, i32 4, i32 6>
ret <4 x i8> %r
@@ -59,23 +51,12 @@ define <4 x i8> @test_punzipe_v4i8(<8 x i8> %a) {
define <4 x i8> @test_punzipo_v4i8(<8 x i8> %a) {
; RV32-LABEL: test_punzipo_v4i8:
; RV32: # %bb.0:
-; RV32-NEXT: srli a3, a1, 24
-; RV32-NEXT: srli a1, a1, 8
-; RV32-NEXT: srli a2, a0, 24
-; RV32-NEXT: srli a0, a0, 8
-; RV32-NEXT: ppaire.db a0, a0, a2
-; RV32-NEXT: pack a0, a0, a1
+; RV32-NEXT: pncvth.b a0, a0
; RV32-NEXT: ret
;
; RV64-LABEL: test_punzipo_v4i8:
; RV64: # %bb.0:
-; RV64-NEXT: srli a1, a0, 56
-; RV64-NEXT: srli a2, a0, 40
-; RV64-NEXT: srli a3, a0, 24
-; RV64-NEXT: srli a0, a0, 8
-; RV64-NEXT: ppaire.b a1, a2, a1
-; RV64-NEXT: ppaire.b a0, a0, a3
-; RV64-NEXT: ppaire.h a0, a0, a1
+; RV64-NEXT: pncvth.wb a0, a0
; RV64-NEXT: ret
%r = shufflevector <8 x i8> %a, <8 x i8> poison, <4 x i32> <i32 1, i32 3, i32 5, i32 7>
ret <4 x i8> %r
@@ -84,13 +65,12 @@ define <4 x i8> @test_punzipo_v4i8(<8 x i8> %a) {
define <2 x i16> @test_punzipe_v2i16(<4 x i16> %a) {
; RV32-LABEL: test_punzipe_v2i16:
; RV32: # %bb.0:
-; RV32-NEXT: pack a0, a0, a1
+; RV32-NEXT: pncvt.h a0, a0
; RV32-NEXT: ret
;
; RV64-LABEL: test_punzipe_v2i16:
; RV64: # %bb.0:
-; RV64-NEXT: srli a1, a0, 32
-; RV64-NEXT: ppaire.h a0, a0, a1
+; RV64-NEXT: pncvt.wh a0, a0
; RV64-NEXT: ret
%r = shufflevector <4 x i16> %a, <4 x i16> poison, <2 x i32> <i32 0, i32 2>
ret <2 x i16> %r
@@ -99,19 +79,180 @@ define <2 x i16> @test_punzipe_v2i16(<4 x i16> %a) {
define <2 x i16> @test_punzipo_v2i16(<4 x i16> %a) {
; RV32-LABEL: test_punzipo_v2i16:
; RV32: # %bb.0:
-; RV32-NEXT: srli a1, a1, 16
-; RV32-NEXT: srli a0, a0, 16
-; RV32-NEXT: pack a0, a0, a1
+; RV32-NEXT: pncvth.h a0, a0
; RV32-NEXT: ret
;
; RV64-LABEL: test_punzipo_v2i16:
; RV64: # %bb.0:
-; RV64-NEXT: srli a1, a0, 48
-; RV64-NEXT: srli a0, a0, 16
-; RV64-NEXT: ppaire.h a0, a0, a1
+; RV64-NEXT: pncvth.wh a0, a0
; RV64-NEXT: ret
%r = shufflevector <4 x i16> %a, <4 x i16> poison, <2 x i32> <i32 1, i32 3>
ret <2 x i16> %r
}
+
+define <8 x i8> @test_unzip8p_v8i8(<8 x i8> %a, <8 x i8> %b) {
+; RV32-LABEL: test_unzip8p_v8i8:
+; RV32: # %bb.0:
+; RV32-NEXT: srli a4, a3, 16
+; RV32-NEXT: srli a5, a2, 16
+; RV32-NEXT: ppaire.b a3, a3, a4
+; RV32-NEXT: ppaire.b a2, a2, a5
+; RV32-NEXT: srli a4, a1, 16
+; RV32-NEXT: srli a5, a0, 16
+; RV32-NEXT: ppaire.b a4, a1, a4
+; RV32-NEXT: ppaire.b a0, a0, a5
+; RV32-NEXT: pack a1, a2, a3
+; RV32-NEXT: pack a0, a0, a4
+; RV32-NEXT: ret
+;
+; RV64-LABEL: test_unzip8p_v8i8:
+; RV64: # %bb.0:
+; RV64-NEXT: unzip8p a0, a0, a1
+; RV64-NEXT: ret
+ %r = shufflevector <8 x i8> %a, <8 x i8> %b, <8 x i32> <i32 0, i32 2, i32 4, i32 6, i32 8, i32 10, i32 12, i32 14>
+ ret <8 x i8> %r
+}
+
+define <8 x i8> @test_unzip8hp_v8i8(<8 x i8> %a, <8 x i8> %b) {
+; RV32-LABEL: test_unzip8hp_v8i8:
+; RV32: # %bb.0:
+; RV32-NEXT: srli a4, a3, 24
+; RV32-NEXT: srli a3, a3, 8
+; RV32-NEXT: srli a5, a2, 24
+; RV32-NEXT: srli a2, a2, 8
+; RV32-NEXT: ppaire.b a3, a3, a4
+; RV32-NEXT: ppaire.b a2, a2, a5
+; RV32-NEXT: srli a4, a1, 24
+; RV32-NEXT: srli a1, a1, 8
+; RV32-NEXT: srli a5, a0, 24
+; RV32-NEXT: srli a0, a0, 8
+; RV32-NEXT: ppaire.b a4, a1, a4
+; RV32-NEXT: ppaire.b a0, a0, a5
+; RV32-NEXT: pack a1, a2, a3
+; RV32-NEXT: pack a0, a0, a4
+; RV32-NEXT: ret
+;
+; RV64-LABEL: test_unzip8hp_v8i8:
+; RV64: # %bb.0:
+; RV64-NEXT: unzip8hp a0, a0, a1
+; RV64-NEXT: ret
+ %r = shufflevector <8 x i8> %a, <8 x i8> %b, <8 x i32> <i32 1, i32 3, i32 5, i32 7, i32 9, i32 11, i32 13, i32 15>
+ ret <8 x i8> %r
+}
+
+define <4 x i16> @test_unzip16p_v4i16(<4 x i16> %a, <4 x i16> %b) {
+; RV32-LABEL: test_unzip16p_v4i16:
+; RV32: # %bb.0:
+; RV32-NEXT: pack a2, a2, a3
+; RV32-NEXT: pack a0, a0, a1
+; RV32-NEXT: mv a1, a2
+; RV32-NEXT: ret
+;
+; RV64-LABEL: test_unzip16p_v4i16:
+; RV64: # %bb.0:
+; RV64-NEXT: unzip16p a0, a0, a1
+; RV64-NEXT: ret
+ %r = shufflevector <4 x i16> %a, <4 x i16> %b, <4 x i32> <i32 0, i32 2, i32 4, i32 6>
+ ret <4 x i16> %r
+}
+
+define <4 x i16> @test_unzip16hp_v4i16(<4 x i16> %a, <4 x i16> %b) {
+; RV32-LABEL: test_unzip16hp_v4i16:
+; RV32: # %bb.0:
+; RV32-NEXT: srli a3, a3, 16
+; RV32-NEXT: srli a2, a2, 16
+; RV32-NEXT: srli a4, a1, 16
+; RV32-NEXT: srli a0, a0, 16
+; RV32-NEXT: pack a1, a2, a3
+; RV32-NEXT: pack a0, a0, a4
+; RV32-NEXT: ret
+;
+; RV64-LABEL: test_unzip16hp_v4i16:
+; RV64: # %bb.0:
+; RV64-NEXT: unzip16hp a0, a0, a1
+; RV64-NEXT: ret
+ %r = shufflevector <4 x i16> %a, <4 x i16> %b, <4 x i32> <i32 1, i32 3, i32 5, i32 7>
+ ret <4 x i16> %r
+}
+
+define <8 x i8> @test_unzip8p_v8i8_partial_poison(<8 x i8> %a, <8 x i8> %b) {
+; RV32-LABEL: test_unzip8p_v8i8_partial_poison:
+; RV32: # %bb.0:
+; RV32-NEXT: srli a4, a2, 16
+; RV32-NEXT: ppaire.b a2, a2, a4
+; RV32-NEXT: srli a3, a3, 16
+; RV32-NEXT: ppaire.b a3, a0, a3
+; RV32-NEXT: srli a4, a1, 16
+; RV32-NEXT: ppaire.b a4, a1, a4
+; RV32-NEXT: ppaire.b a0, a0, a0
+; RV32-NEXT: pack a1, a2, a3
+; RV32-NEXT: pack a0, a0, a4
+; RV32-NEXT: ret
+;
+; RV64-LABEL: test_unzip8p_v8i8_partial_poison:
+; RV64: # %bb.0:
+; RV64-NEXT: unzip8p a0, a0, a1
+; RV64-NEXT: ret
+ %r = shufflevector <8 x i8> %a, <8 x i8> %b, <8 x i32> <i32 0, i32 poison, i32 4, i32 6, i32 8, i32 10, i32 poison, i32 14>
+ ret <8 x i8> %r
+}
+
+define <8 x i8> @test_unzip8hp_v8i8_partial_poison(<8 x i8> %a, <8 x i8> %b) {
+; RV32-LABEL: test_unzip8hp_v8i8_partial_poison:
+; RV32: # %bb.0:
+; RV32-NEXT: srli a4, a2, 24
+; RV32-NEXT: srli a2, a2, 8
+; RV32-NEXT: ppaire.b a2, a2, a4
+; RV32-NEXT: srli a3, a3, 8
+; RV32-NEXT: ppaire.b a3, a3, a0
+; RV32-NEXT: srli a4, a0, 24
+; RV32-NEXT: srli a0, a0, 8
+; RV32-NEXT: srli a1, a1, 24
+; RV32-NEXT: ppaire.b a0, a0, a4
+; RV32-NEXT: ppaire.b a4, a0, a1
+; RV32-NEXT: pack a1, a2, a3
+; RV32-NEXT: pack a0, a0, a4
+; RV32-NEXT: ret
+;
+; RV64-LABEL: test_unzip8hp_v8i8_partial_poison:
+; RV64: # %bb.0:
+; RV64-NEXT: unzip8hp a0, a0, a1
+; RV64-NEXT: ret
+ %r = shufflevector <8 x i8> %a, <8 x i8> %b, <8 x i32> <i32 1, i32 3, i32 poison, i32 7, i32 9, i32 11, i32 13, i32 poison>
+ ret <8 x i8> %r
+}
+
+define <4 x i16> @test_unzip16p_v4i16_partial_poison(<4 x i16> %a, <4 x i16> %b) {
+; RV32-LABEL: test_unzip16p_v4i16_partial_poison:
+; RV32: # %bb.0:
+; RV32-NEXT: pack a1, a2, a3
+; RV32-NEXT: pack a0, a0, a0
+; RV32-NEXT: ret
+;
+; RV64-LABEL: test_unzip16p_v4i16_partial_poison:
+; RV64: # %bb.0:
+; RV64-NEXT: unzip16p a0, a0, a1
+; RV64-NEXT: ret
+ %r = shufflevector <4 x i16> %a, <4 x i16> %b, <4 x i32> <i32 0, i32 poison, i32 4, i32 6>
+ ret <4 x i16> %r
+}
+
+define <4 x i16> @test_unzip16hp_v4i16_partial_poison(<4 x i16> %a, <4 x i16> %b) {
+; RV32-LABEL: test_unzip16hp_v4i16_partial_poison:
+; RV32: # %bb.0:
+; RV32-NEXT: srli a1, a1, 16
+; RV32-NEXT: srli a0, a0, 16
+; RV32-NEXT: srli a3, a3, 16
+; RV32-NEXT: pack a0, a0, a1
+; RV32-NEXT: pack a1, a0, a3
+; RV32-NEXT: ret
+;
+; RV64-LABEL: test_unzip16hp_v4i16_partial_poison:
+; RV64: # %bb.0:
+; RV64-NEXT: unzip16hp a0, a0, a1
+; RV64-NEXT: ret
+ %r = shufflevector <4 x i16> %a, <4 x i16> %b, <4 x i32> <i32 1, i32 3, i32 poison, i32 7>
+ ret <4 x i16> %r
+}
;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
; CHECK: {{.*}}
>From 6880a68a11a2561b3649c69835661d930668d2af Mon Sep 17 00:00:00 2001
From: XChy <xxs_chy at outlook.com>
Date: Sat, 11 Jul 2026 00:25:41 +0800
Subject: [PATCH 2/6] format
---
llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index dca57ce4ea388..d3561183c8e1c 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -4746,7 +4746,8 @@ static SDValue lowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG,
}
if (VT == MVT::v4i8) {
- // <4 x i8> BUILD_VECTOR a, b, c, d -> PACK(PPACK.DH pair(a, c), pair(b, d))
+ // <4 x i8> BUILD_VECTOR a, b, c, d -> PACK(PPACK.DH pair(a, c), pair(b,
+ // d))
SDValue Val0 =
DAG.getNode(ISD::SCALAR_TO_VECTOR, DL, MVT::v4i8, Op->getOperand(0));
SDValue Val1 =
@@ -4761,13 +4762,12 @@ static SDValue lowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG,
return DAG.getNode(
ISD::BITCAST, DL, MVT::v4i8,
- SDValue(
- DAG.getMachineNode(RISCV::PACK, DL, MVT::i32,
- {DAG.getNode(ISD::BITCAST, DL, MVT::i32,
- PPairDB.getValue(0)),
- DAG.getNode(ISD::BITCAST, DL, MVT::i32,
- PPairDB.getValue(1))}),
- 0));
+ SDValue(DAG.getMachineNode(RISCV::PACK, DL, MVT::i32,
+ {DAG.getNode(ISD::BITCAST, DL, MVT::i32,
+ PPairDB.getValue(0)),
+ DAG.getNode(ISD::BITCAST, DL, MVT::i32,
+ PPairDB.getValue(1))}),
+ 0));
}
llvm_unreachable("Unexpected RV32 P BUILD_VECTOR type");
>From 5173782d23d6b89328347b119d832cbd3b6a7436 Mon Sep 17 00:00:00 2001
From: XChy <xxs_chy at outlook.com>
Date: Sat, 11 Jul 2026 01:12:27 +0800
Subject: [PATCH 3/6] resolve comments
---
llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 14 ++++++--------
llvm/lib/Target/RISCV/RISCVInstrInfoP.td | 19 +++++++------------
2 files changed, 13 insertions(+), 20 deletions(-)
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index d3561183c8e1c..354b3d7d7c196 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -4741,8 +4741,7 @@ static SDValue lowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG,
SDValue Lo = DAG.getAnyExtOrTrunc(Op->getOperand(0), DL, MVT::i32);
SDValue Hi = DAG.getAnyExtOrTrunc(Op->getOperand(1), DL, MVT::i32);
return DAG.getBitcast(
- MVT::v2i16,
- SDValue(DAG.getMachineNode(RISCV::PACK, DL, MVT::i32, {Lo, Hi}), 0));
+ MVT::v2i16, DAG.getNode(RISCVISD::PACK, DL, MVT::i32, Lo, Hi));
}
if (VT == MVT::v4i8) {
@@ -4762,12 +4761,11 @@ static SDValue lowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG,
return DAG.getNode(
ISD::BITCAST, DL, MVT::v4i8,
- SDValue(DAG.getMachineNode(RISCV::PACK, DL, MVT::i32,
- {DAG.getNode(ISD::BITCAST, DL, MVT::i32,
- PPairDB.getValue(0)),
- DAG.getNode(ISD::BITCAST, DL, MVT::i32,
- PPairDB.getValue(1))}),
- 0));
+ DAG.getNode(RISCVISD::PACK, DL, MVT::i32,
+ DAG.getNode(ISD::BITCAST, DL, MVT::i32,
+ PPairDB.getValue(0)),
+ DAG.getNode(ISD::BITCAST, DL, MVT::i32,
+ PPairDB.getValue(1))));
}
llvm_unreachable("Unexpected RV32 P BUILD_VECTOR type");
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoP.td b/llvm/lib/Target/RISCV/RISCVInstrInfoP.td
index 8facdcbb0e8c6..c63c6a344cd70 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoP.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoP.td
@@ -1866,6 +1866,11 @@ def shiftMask16 : ComplexPattern<XLenVT, 1, "selectShiftMask<16>", [], [], 0>;
def BuildGPRPair : OutPatFrag<(ops node:$lo, node:$hi),
(REG_SEQUENCE GPRPair, $lo, sub_gpr_even, $hi, sub_gpr_odd)>;
+def SDT_RISCVPack : SDTypeProfile<1, 2, [SDTCisVT<0, XLenVT>,
+ SDTCisSameAs<0, 1>,
+ SDTCisSameAs<0, 2>]>;
+def riscv_pack : RVSDNode<"PACK", SDT_RISCVPack>;
+
// Averaging subtraction, (a - b) >> 2
def riscv_asub : RVSDNode<"ASUB", SDTIntBinOp>;
def riscv_asubu : RVSDNode<"ASUBU", SDTIntBinOp>;
@@ -2232,6 +2237,8 @@ let append Predicates = [IsRV32] in {
def : Pat<(riscv_nsra GPR:$lo, GPR:$hi, shiftMask64:$shamt),
(NSRA (BuildGPRPair GPR:$lo, GPR:$hi), shiftMask64:$shamt)>;
+ def : Pat<(riscv_pack GPR:$lo, GPR:$hi), (PACK GPR:$lo, GPR:$hi)>;
+
// Match a pattern of 2 bytes being inserted into bits [31:16], with bits
// bits [15:0] coming from a zero extended value. We can use pack with
// ppaire.b for bits [31:16]. If bits [15:0] can also be a ppaire.b, it can be
@@ -2297,10 +2304,6 @@ let append Predicates = [IsRV32] in {
def : Pat<(v4i16 (sext (v4i8 GPR:$rs))), (PWADD_B GPR:$rs, (v4i8 X0))>;
def : Pat<(v2i32 (sext (v2i16 GPR:$rs))), (PWADD_H GPR:$rs, (v2i16 X0))>;
- // Build vector patterns
- def : Pat<(v2i16 (build_vector (XLenVT GPR:$a), (XLenVT GPR:$b))),
- (PACK GPR:$a, GPR:$b)>;
-
// Truncate patterns using pnsrli.
// FIXME: Support general shift+trunc
def : Pat<(v4i8 (trunc (v4i16 GPRPair:$rs))), (PNSRLI_B GPRPair:$rs, 0)>;
@@ -2784,14 +2787,6 @@ let append Predicates = [IsRV64] in {
def : Pat<(v2i32 (zext_invec (v4i16 GPR:$rs))), (ZIP16P GPR:$rs, (v4i16 X0))>;
// Packed unzip.
- def : Pat<(v8i8 (riscv_punzipe (v8i8 GPR:$rs), (v8i8 undef))),
- (UNZIP8P GPR:$rs, (v8i8 X0))>;
- def : Pat<(v8i8 (riscv_punzipo (v8i8 GPR:$rs), (v8i8 undef))),
- (UNZIP8HP GPR:$rs, (v8i8 X0))>;
- def : Pat<(v4i16 (riscv_punzipe (v4i16 GPR:$rs), (v4i16 undef))),
- (UNZIP16P GPR:$rs, (v4i16 X0))>;
- def : Pat<(v4i16 (riscv_punzipo (v4i16 GPR:$rs), (v4i16 undef))),
- (UNZIP16HP GPR:$rs, (v4i16 X0))>;
def : Pat<(v8i8 (riscv_punzipe (v8i8 GPR:$rs1), (v8i8 GPR:$rs2))),
(UNZIP8P GPR:$rs1, GPR:$rs2)>;
def : Pat<(v8i8 (riscv_punzipo (v8i8 GPR:$rs1), (v8i8 GPR:$rs2))),
>From 229b69dc5076a6278171d9b915b03d044f3c6596 Mon Sep 17 00:00:00 2001
From: XChy <xxs_chy at outlook.com>
Date: Sat, 11 Jul 2026 02:21:35 +0800
Subject: [PATCH 4/6] use RISCVISD::PAIRE instead of RISCVISD::PACK
---
llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 4 ++--
llvm/lib/Target/RISCV/RISCVInstrInfoP.td | 10 +++++-----
2 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 354b3d7d7c196..70221884d9a8a 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -4741,7 +4741,7 @@ static SDValue lowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG,
SDValue Lo = DAG.getAnyExtOrTrunc(Op->getOperand(0), DL, MVT::i32);
SDValue Hi = DAG.getAnyExtOrTrunc(Op->getOperand(1), DL, MVT::i32);
return DAG.getBitcast(
- MVT::v2i16, DAG.getNode(RISCVISD::PACK, DL, MVT::i32, Lo, Hi));
+ MVT::v2i16, DAG.getNode(RISCVISD::PAIRE, DL, MVT::i32, Lo, Hi));
}
if (VT == MVT::v4i8) {
@@ -4761,7 +4761,7 @@ static SDValue lowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG,
return DAG.getNode(
ISD::BITCAST, DL, MVT::v4i8,
- DAG.getNode(RISCVISD::PACK, DL, MVT::i32,
+ DAG.getNode(RISCVISD::PAIRE, DL, MVT::i32,
DAG.getNode(ISD::BITCAST, DL, MVT::i32,
PPairDB.getValue(0)),
DAG.getNode(ISD::BITCAST, DL, MVT::i32,
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoP.td b/llvm/lib/Target/RISCV/RISCVInstrInfoP.td
index c63c6a344cd70..b25fc746dfdba 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoP.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoP.td
@@ -1866,10 +1866,10 @@ def shiftMask16 : ComplexPattern<XLenVT, 1, "selectShiftMask<16>", [], [], 0>;
def BuildGPRPair : OutPatFrag<(ops node:$lo, node:$hi),
(REG_SEQUENCE GPRPair, $lo, sub_gpr_even, $hi, sub_gpr_odd)>;
-def SDT_RISCVPack : SDTypeProfile<1, 2, [SDTCisVT<0, XLenVT>,
- SDTCisSameAs<0, 1>,
- SDTCisSameAs<0, 2>]>;
-def riscv_pack : RVSDNode<"PACK", SDT_RISCVPack>;
+def SDT_RISCVPairEven : SDTypeProfile<1, 2, [SDTCisVT<0, XLenVT>,
+ SDTCisSameAs<0, 1>,
+ SDTCisSameAs<0, 2>]>;
+def riscv_paire : RVSDNode<"PAIRE", SDT_RISCVPairEven>;
// Averaging subtraction, (a - b) >> 2
def riscv_asub : RVSDNode<"ASUB", SDTIntBinOp>;
@@ -2237,7 +2237,7 @@ let append Predicates = [IsRV32] in {
def : Pat<(riscv_nsra GPR:$lo, GPR:$hi, shiftMask64:$shamt),
(NSRA (BuildGPRPair GPR:$lo, GPR:$hi), shiftMask64:$shamt)>;
- def : Pat<(riscv_pack GPR:$lo, GPR:$hi), (PACK GPR:$lo, GPR:$hi)>;
+ def : Pat<(riscv_paire GPR:$lo, GPR:$hi), (PACK GPR:$lo, GPR:$hi)>;
// Match a pattern of 2 bytes being inserted into bits [31:16], with bits
// bits [15:0] coming from a zero extended value. We can use pack with
>From bf8c5b7ddaf7aa1d2b8aa578b2f234ca025be5d1 Mon Sep 17 00:00:00 2001
From: XChy <xxs_chy at outlook.com>
Date: Sat, 11 Jul 2026 02:42:44 +0800
Subject: [PATCH 5/6] add type constraint
---
llvm/lib/Target/RISCV/RISCVInstrInfoP.td | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoP.td b/llvm/lib/Target/RISCV/RISCVInstrInfoP.td
index b25fc746dfdba..f8aded51aadd9 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoP.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoP.td
@@ -2237,7 +2237,8 @@ let append Predicates = [IsRV32] in {
def : Pat<(riscv_nsra GPR:$lo, GPR:$hi, shiftMask64:$shamt),
(NSRA (BuildGPRPair GPR:$lo, GPR:$hi), shiftMask64:$shamt)>;
- def : Pat<(riscv_paire GPR:$lo, GPR:$hi), (PACK GPR:$lo, GPR:$hi)>;
+ def : Pat<(XLenVT (riscv_paire GPR:$lo, GPR:$hi)),
+ (PACK GPR:$lo, GPR:$hi)>;
// Match a pattern of 2 bytes being inserted into bits [31:16], with bits
// bits [15:0] coming from a zero extended value. We can use pack with
>From 13ef29dd75486fc9f97a6f176fa9df50a47dcfbc Mon Sep 17 00:00:00 2001
From: XChy <xxs_chy at outlook.com>
Date: Sat, 11 Jul 2026 12:55:54 +0800
Subject: [PATCH 6/6] resolve comments
---
llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 23 +++++++++++----------
llvm/lib/Target/RISCV/RISCVInstrInfoP.td | 10 ++++-----
2 files changed, 17 insertions(+), 16 deletions(-)
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 70221884d9a8a..7e6e680699438 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -4738,10 +4738,13 @@ static SDValue lowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG,
return V;
if (VT == MVT::v2i16) {
- SDValue Lo = DAG.getAnyExtOrTrunc(Op->getOperand(0), DL, MVT::i32);
- SDValue Hi = DAG.getAnyExtOrTrunc(Op->getOperand(1), DL, MVT::i32);
- return DAG.getBitcast(
- MVT::v2i16, DAG.getNode(RISCVISD::PAIRE, DL, MVT::i32, Lo, Hi));
+ SDValue Lo = DAG.getBitcast(
+ MVT::v2i16,
+ DAG.getAnyExtOrTrunc(Op->getOperand(0), DL, MVT::i32));
+ SDValue Hi = DAG.getBitcast(
+ MVT::v2i16,
+ DAG.getAnyExtOrTrunc(Op->getOperand(1), DL, MVT::i32));
+ return DAG.getNode(RISCVISD::PAIRE, DL, MVT::v2i16, Lo, Hi);
}
if (VT == MVT::v4i8) {
@@ -4759,13 +4762,11 @@ static SDValue lowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG,
DAG.getNode(RISCVISD::PPAIRE_DB, DL, {MVT::v4i8, MVT::v4i8},
{Val0, Val2, Val1, Val3});
- return DAG.getNode(
- ISD::BITCAST, DL, MVT::v4i8,
- DAG.getNode(RISCVISD::PAIRE, DL, MVT::i32,
- DAG.getNode(ISD::BITCAST, DL, MVT::i32,
- PPairDB.getValue(0)),
- DAG.getNode(ISD::BITCAST, DL, MVT::i32,
- PPairDB.getValue(1))));
+ return DAG.getBitcast(
+ MVT::v4i8,
+ DAG.getNode(RISCVISD::PAIRE, DL, MVT::v2i16,
+ DAG.getBitcast(MVT::v2i16, PPairDB.getValue(0)),
+ DAG.getBitcast(MVT::v2i16, PPairDB.getValue(1))));
}
llvm_unreachable("Unexpected RV32 P BUILD_VECTOR type");
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoP.td b/llvm/lib/Target/RISCV/RISCVInstrInfoP.td
index f8aded51aadd9..5f5b871422a85 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoP.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoP.td
@@ -1866,9 +1866,9 @@ def shiftMask16 : ComplexPattern<XLenVT, 1, "selectShiftMask<16>", [], [], 0>;
def BuildGPRPair : OutPatFrag<(ops node:$lo, node:$hi),
(REG_SEQUENCE GPRPair, $lo, sub_gpr_even, $hi, sub_gpr_odd)>;
-def SDT_RISCVPairEven : SDTypeProfile<1, 2, [SDTCisVT<0, XLenVT>,
- SDTCisSameAs<0, 1>,
- SDTCisSameAs<0, 2>]>;
+def SDT_RISCVPairEven : SDTypeProfile<1, 2, [SDTCisVec<0>,
+ SDTCisSameAs<0, 1>,
+ SDTCisSameAs<0, 2>]>;
def riscv_paire : RVSDNode<"PAIRE", SDT_RISCVPairEven>;
// Averaging subtraction, (a - b) >> 2
@@ -2237,8 +2237,8 @@ let append Predicates = [IsRV32] in {
def : Pat<(riscv_nsra GPR:$lo, GPR:$hi, shiftMask64:$shamt),
(NSRA (BuildGPRPair GPR:$lo, GPR:$hi), shiftMask64:$shamt)>;
- def : Pat<(XLenVT (riscv_paire GPR:$lo, GPR:$hi)),
- (PACK GPR:$lo, GPR:$hi)>;
+ def : Pat<(v2i16 (riscv_paire (v2i16 GPR:$lo), (v2i16 GPR:$hi))),
+ (PACK GPR:$lo, GPR:$hi)>;
// Match a pattern of 2 bytes being inserted into bits [31:16], with bits
// bits [15:0] coming from a zero extended value. We can use pack with
More information about the llvm-commits
mailing list