diff --git a/cross-project-tests/intrinsic-header-tests/riscv_packed_simd.c b/cross-project-tests/intrinsic-header-tests/riscv_packed_simd.c index fb2e245f8328..a73c0376db9d 100644 --- a/cross-project-tests/intrinsic-header-tests/riscv_packed_simd.c +++ b/cross-project-tests/intrinsic-header-tests/riscv_packed_simd.c @@ -2350,12 +2350,12 @@ uint8x4_t test_prev_u8x4(uint8x4_t a) { return __riscv_prev_u8x4(a); } // CHECK-LABEL: test_prev_i16x2: // RV32: ppairoe.h -// RV64: rev16 +// RV64: ppairoe.h int16x2_t test_prev_i16x2(int16x2_t a) { return __riscv_prev_i16x2(a); } // CHECK-LABEL: test_prev_u16x2: // RV32: ppairoe.h -// RV64: rev16 +// RV64: ppairoe.h uint16x2_t test_prev_u16x2(uint16x2_t a) { return __riscv_prev_u16x2(a); } // CHECK-LABEL: test_prev_i8x8: diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp index 3073f6cf91ed..61a954099d9e 100644 --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -6547,6 +6547,8 @@ SDValue RISCVTargetLowering::lowerVECTOR_SHUFFLE(SDValue Op, }; if (IsLowReverse(NumElts)) return DAG.getNode(ISD::VECTOR_REVERSE, DL, VT, V1); + if (Subtarget.is64Bit() && VT == MVT::v4i16 && IsLowReverse(/*L=*/2)) + return DAG.getNode(RISCVISD::PPAIROE_H, DL, VT, V1, V1); // Widened: reversing sends the low-half lanes to the top half, so shift // them back down by half the register. Only the 64-bit packed types are // legal here, so the register is XLen (i64). diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoP.td b/llvm/lib/Target/RISCV/RISCVInstrInfoP.td index 37cab93b6bbc..99fece437117 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfoP.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoP.td @@ -1870,6 +1870,10 @@ def SDT_RISCVPPairEven : SDTypeProfile<1, 2, [SDTCisVec<0>, SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>]>; def riscv_ppaire : RVSDNode<"PPAIRE", SDT_RISCVPPairEven>; +def SDT_RISCVPackedBinary : SDTypeProfile<1, 2, [SDTCisVec<0>, + SDTCisSameAs<0, 1>, + SDTCisSameAs<0, 2>]>; +def riscv_ppairoe_h : RVSDNode<"PPAIROE_H", SDT_RISCVPackedBinary>; // Averaging subtraction, (a - b) >> 2 def riscv_asub : RVSDNode<"ASUB", SDTIntBinOp>; @@ -2153,9 +2157,11 @@ let Predicates = [HasStdExtP] in { def : Pat<(XLenVecI16VT (vselect (XLenVecI16VT GPR:$mask), GPR:$true_v, GPR:$false_v)), (MERGE GPR:$mask, GPR:$false_v, GPR:$true_v)>; - // 16-bit bswap patterns + // 16-bit permute patterns def : Pat<(XLenVecI16VT (bswap GPR:$rs)), (PPAIROE_B GPR:$rs, GPR:$rs)>; + def : Pat<(XLenVecI16VT (riscv_ppairoe_h GPR:$rs1, GPR:$rs2)), + (PPAIROE_H GPR:$rs1, GPR:$rs2)>; let append Predicates = [IsRV32] in { def : PatGpr; diff --git a/llvm/test/CodeGen/RISCV/rvp-reverse.ll b/llvm/test/CodeGen/RISCV/rvp-reverse.ll index 7490e8f3ab83..4f98dfebca70 100644 --- a/llvm/test/CodeGen/RISCV/rvp-reverse.ll +++ b/llvm/test/CodeGen/RISCV/rvp-reverse.ll @@ -29,8 +29,7 @@ define <2 x i16> @test_prev_v2i16(<2 x i16> %a) { ; ; RV64-LABEL: test_prev_v2i16: ; RV64: # %bb.0: -; RV64-NEXT: rev16 a0, a0 -; RV64-NEXT: srli a0, a0, 32 +; RV64-NEXT: ppairoe.h a0, a0, a0 ; RV64-NEXT: ret %r = shufflevector <2 x i16> %a, <2 x i16> poison, <2 x i32> ret <2 x i16> %r