[llvm] [RISCV][P-ext] Select PPAIREO.W when packing with the high word of a value (PR #225763)

via llvm-commits llvm-commits at lists.llvm.org
Wed Sep 23 06:28:33 PDT 2026


https://github.com/sihuan created https://github.com/llvm/llvm-project/pull/225763

The low-half packed subvector insert is a v2i32 whose low word is the subvector
and whose high word is the high word of the wide vector, which is exactly
`ppaireo.w` (the low word comes from `rs1`, the high word from `rs2`). Select it
directly instead of `srli` + `pack`.

Adds `rvp-ppaireo-w.ll`; `rvp-simd-64.ll` is updated because the scalar low
insert in `test_insert_vector_32` now selects `ppaireo.w`.


>From 82b3c9babb5c724fa61a228bebfcd6e018afb18d Mon Sep 17 00:00:00 2001
From: SiHuaN <liyongtai at iscas.ac.cn>
Date: Wed, 23 Sep 2026 11:48:17 +0000
Subject: [PATCH] [RISCV][P-ext] Select PPAIREO.W when packing with the high
 word of a value

The low-half packed subvector insert is a v2i32 whose low word is the subvector
and whose high word is the high word of the wide vector, which is exactly
ppaireo.w. Select it directly instead of srli + pack.
---
 llvm/lib/Target/RISCV/RISCVInstrInfoP.td |  5 +++
 llvm/test/CodeGen/RISCV/rvp-ppaireo-w.ll | 46 ++++++++++++++++++++++++
 llvm/test/CodeGen/RISCV/rvp-simd-64.ll   |  3 +-
 3 files changed, 52 insertions(+), 2 deletions(-)
 create mode 100644 llvm/test/CodeGen/RISCV/rvp-ppaireo-w.ll

diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoP.td b/llvm/lib/Target/RISCV/RISCVInstrInfoP.td
index 24096ab7d4a50..b77fed07cdc97 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoP.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoP.td
@@ -3426,6 +3426,11 @@ let append Predicates = [IsRV64] in {
                                  (XLenVT GPR:$c), (XLenVT GPR:$d))),
             (PACK (PPAIRE_H GPR:$a, GPR:$b), (PPAIRE_H GPR:$c, GPR:$d))>;
 
+  // PPAIREO.W packs the low word of rs1 with the high word of rs2.
+  def : Pat<(v2i32 (build_vector (XLenVT GPR:$a),
+                                 (XLenVT (srl GPR:$x, (XLenVT 32))))),
+            (PPAIREO_W GPR:$a, GPR:$x)>;
+
   def : Pat<(v2i32 (build_vector (XLenVT GPR:$a), (XLenVT GPR:$b))),
             (PACK GPR:$a, GPR:$b)>;
 
diff --git a/llvm/test/CodeGen/RISCV/rvp-ppaireo-w.ll b/llvm/test/CodeGen/RISCV/rvp-ppaireo-w.ll
new file mode 100644
index 0000000000000..23a8ad7466c9d
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/rvp-ppaireo-w.ll
@@ -0,0 +1,46 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
+; RUN: llc -mtriple=riscv64 -mattr=+experimental-p,+m,+zbb -verify-machineinstrs < %s | FileCheck %s
+
+; PPAIREO.W packs the low word of rs1 with the high word of rs2.
+
+define i64 @insert_lo_v8i8(i64 %v, i32 %s) {
+; CHECK-LABEL: insert_lo_v8i8:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    ppaireo.w a0, a1, a0
+; CHECK-NEXT:    ret
+  %hi = lshr i64 %v, 32
+  %hit = trunc i64 %hi to i32
+  %ss = bitcast i32 %s to <4 x i8>
+  %hh = bitcast i32 %hit to <4 x i8>
+  %cat = shufflevector <4 x i8> %ss, <4 x i8> %hh, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
+  %r = bitcast <8 x i8> %cat to i64
+  ret i64 %r
+}
+
+define i64 @insert_lo_v4i16(i64 %v, i32 %s) {
+; CHECK-LABEL: insert_lo_v4i16:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    ppaireo.w a0, a1, a0
+; CHECK-NEXT:    ret
+  %hi = lshr i64 %v, 32
+  %hit = trunc i64 %hi to i32
+  %ss = bitcast i32 %s to <2 x i16>
+  %hh = bitcast i32 %hit to <2 x i16>
+  %cat = shufflevector <2 x i16> %ss, <2 x i16> %hh, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
+  %r = bitcast <4 x i16> %cat to i64
+  ret i64 %r
+}
+
+; The high-half insert stays a pack.
+define i64 @insert_hi_v8i8(i64 %v, i32 %s) {
+; CHECK-LABEL: insert_hi_v8i8:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    pack a0, a0, a1
+; CHECK-NEXT:    ret
+  %lo = trunc i64 %v to i32
+  %ss = bitcast i32 %s to <4 x i8>
+  %ll = bitcast i32 %lo to <4 x i8>
+  %cat = shufflevector <4 x i8> %ll, <4 x i8> %ss, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
+  %r = bitcast <8 x i8> %cat to i64
+  ret i64 %r
+}
diff --git a/llvm/test/CodeGen/RISCV/rvp-simd-64.ll b/llvm/test/CodeGen/RISCV/rvp-simd-64.ll
index 9ac7b5ff4cf2e..97c1b24804665 100644
--- a/llvm/test/CodeGen/RISCV/rvp-simd-64.ll
+++ b/llvm/test/CodeGen/RISCV/rvp-simd-64.ll
@@ -1186,8 +1186,7 @@ define <2 x i32> @test_insert_vector_32(<2 x i32> %a, i32 %val) {
 ;
 ; RV64-LABEL: test_insert_vector_32:
 ; RV64:       # %bb.0:
-; RV64-NEXT:    srli a0, a0, 32
-; RV64-NEXT:    pack a0, a1, a0
+; RV64-NEXT:    ppaireo.w a0, a1, a0
 ; RV64-NEXT:    ret
   %res = insertelement <2 x i32> %a, i32 %val, i32 0
   ret <2 x i32> %res



More information about the llvm-commits mailing list