[llvm] [RISCV][P-ext] Improve RV64 v2i16 reverse codegen (PR #208664)

via llvm-commits llvm-commits at lists.llvm.org
Fri Jul 10 01:58:55 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-risc-v

Author: SiHuaN (sihuan)

<details>
<summary>Changes</summary>

On RV64, v2i16 is widened to v4i16 before shuffle lowering. Recognize the widened low-half reverse and select ppairoe.h directly instead of rev16 followed by srli.

Tests:
- build/bin/llvm-lit -q llvm/test/CodeGen/RISCV/rvp-reverse.ll cross-project-tests/intrinsic-header-tests/riscv_packed_simd.c
- ninja -C build check-llvm-codegen-riscv

---
Full diff: https://github.com/llvm/llvm-project/pull/208664.diff


4 Files Affected:

- (modified) cross-project-tests/intrinsic-header-tests/riscv_packed_simd.c (+2-2) 
- (modified) llvm/lib/Target/RISCV/RISCVISelLowering.cpp (+2) 
- (modified) llvm/lib/Target/RISCV/RISCVInstrInfoP.td (+8-1) 
- (modified) llvm/test/CodeGen/RISCV/rvp-reverse.ll (+1-2) 


``````````diff
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 3e53c097888f0..a9dea008dc634 100644
--- a/cross-project-tests/intrinsic-header-tests/riscv_packed_simd.c
+++ b/cross-project-tests/intrinsic-header-tests/riscv_packed_simd.c
@@ -2300,12 +2300,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 fda994a04b00f..3f576f024aa1c 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -6364,6 +6364,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 7fa7c96ca99ca..92eed1ca96303 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoP.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoP.td
@@ -1903,6 +1903,11 @@ def SDT_RISCVPPairE_DB : SDTypeProfile<2, 4, [SDTCisVT<0, v4i8>,
                                               SDTCisSameAs<0, 5>]>;
 def riscv_ppaire_db : RVSDNode<"PPAIRE_DB", SDT_RISCVPPairE_DB>;
 
+def SDT_RISCVPackedBinary : SDTypeProfile<1, 2, [SDTCisVec<0>,
+                                                 SDTCisSameAs<0, 1>,
+                                                 SDTCisSameAs<0, 2>]>;
+def riscv_ppairoe_h : RVSDNode<"PPAIROE_H", SDT_RISCVPackedBinary>;
+
 // signed-saturating abs of each lane; an INT_MIN lane maps to INT_MAX.
 def SDT_RISCVPackedUnary : SDTypeProfile<1, 1, [SDTCisVec<0>,
                                                 SDTCisSameAs<0, 1>]>;
@@ -2144,9 +2149,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<bitreverse, REV_RV32>;
diff --git a/llvm/test/CodeGen/RISCV/rvp-reverse.ll b/llvm/test/CodeGen/RISCV/rvp-reverse.ll
index 7490e8f3ab833..4f98dfebca700 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> <i32 1, i32 0>
   ret <2 x i16> %r

``````````

</details>


https://github.com/llvm/llvm-project/pull/208664


More information about the llvm-commits mailing list