[clang] [llvm] [RISCV][P-ext] Support Packed Element Extract (PR #221565)

Hongyu Chen via cfe-commits cfe-commits at lists.llvm.org
Mon Sep 7 11:54:05 PDT 2026


https://github.com/XChy updated https://github.com/llvm/llvm-project/pull/221565

>From 6429e310f5a979912e3c3c0879dc89db80d30f04 Mon Sep 17 00:00:00 2001
From: XChy <xxs_chy at outlook.com>
Date: Sun, 6 Sep 2026 19:46:59 +0800
Subject: [PATCH 1/3] [RISCV][P-ext] Support Packed Element Extract

---
 clang/lib/Headers/riscv_packed_simd.h         |  24 +++
 clang/test/CodeGen/RISCV/rvp-intrinsics.c     | 182 ++++++++++++++++++
 .../riscv_packed_simd.c                       |  86 +++++++++
 3 files changed, 292 insertions(+)

diff --git a/clang/lib/Headers/riscv_packed_simd.h b/clang/lib/Headers/riscv_packed_simd.h
index bb0e7624a50e9..7f75a5ef3e5fd 100644
--- a/clang/lib/Headers/riscv_packed_simd.h
+++ b/clang/lib/Headers/riscv_packed_simd.h
@@ -66,6 +66,15 @@ typedef uint32_t uint32x2_t __attribute__((__vector_size__(8)));
     return op __rs1;                                                           \
   }
 
+#define __packed_extract(name, rty, ty, max_idx)                               \
+  static __inline__ rty __DEFAULT_FN_ATTRS __riscv_##name(                     \
+      ty __v, const unsigned __idx)                                            \
+      __attribute__((__enable_if__(                                            \
+          __idx <= (max_idx),                                                  \
+          "index must be a constant integer from 0 to " #max_idx))) {          \
+    return __v[__idx];                                                         \
+  }
+
 #define __packed_binary_builtin(name, ty, builtin)                             \
   static __inline__ ty __DEFAULT_FN_ATTRS __riscv_##name(ty __rs1, ty __rs2) { \
     return builtin(__rs1, __rs2);                                              \
@@ -989,6 +998,20 @@ __packed_binary_builtin_cast(pnclipup_u16x4, uint32x2_t, uint16x4_t, __builtin_r
 __packed_binary_builtin_cast(pnclipp_i32x2, int64_t, int32x2_t, __builtin_riscv_pnclipp_i32x2)
 __packed_binary_builtin_cast(pnclipup_u32x2, uint64_t, uint32x2_t, __builtin_riscv_pnclipup_u32x2)
 
+/* Packed Element Extract (32-bit) */
+__packed_extract(pget_i8x4_i8, int8_t, int8x4_t, 3)
+__packed_extract(pget_u8x4_u8, uint8_t, uint8x4_t, 3)
+__packed_extract(pget_i16x2_i16, int16_t, int16x2_t, 1)
+__packed_extract(pget_u16x2_u16, uint16_t, uint16x2_t, 1)
+
+/* Packed Element Extract (64-bit) */
+__packed_extract(pget_i8x8_i8, int8_t, int8x8_t, 7)
+__packed_extract(pget_u8x8_u8, uint8_t, uint8x8_t, 7)
+__packed_extract(pget_i16x4_i16, int16_t, int16x4_t, 3)
+__packed_extract(pget_u16x4_u16, uint16_t, uint16x4_t, 3)
+__packed_extract(pget_i32x2_i32, int32_t, int32x2_t, 1)
+__packed_extract(pget_u32x2_u32, uint32_t, uint32x2_t, 1)
+
 /* Reinterpret Casts, Packed <-> Scalar (32-bit) */
 __packed_reinterpret(u8x4_u32, uint32_t, uint8x4_t)
 __packed_reinterpret(u16x2_u32, uint32_t, uint16x2_t)
@@ -1137,6 +1160,7 @@ __packed_reinterpret(u32x2_i32x2, int32x2_t, uint32x2_t)
 #undef __packed_nziph4
 #undef __packed_abdsum
 #undef __packed_ternary_builtin_cast
+#undef __packed_extract
 #undef __packed_reinterpret
 #undef __DEFAULT_FN_ATTRS
 
diff --git a/clang/test/CodeGen/RISCV/rvp-intrinsics.c b/clang/test/CodeGen/RISCV/rvp-intrinsics.c
index 9453a07e89ce7..7589157c38754 100644
--- a/clang/test/CodeGen/RISCV/rvp-intrinsics.c
+++ b/clang/test/CodeGen/RISCV/rvp-intrinsics.c
@@ -10701,3 +10701,185 @@ int64_t test_mqracc_w01_i64(int64_t rd, int32x2_t rs1, int32x2_t rs2) {
 int64_t test_mqracc_w11_i64(int64_t rd, int32x2_t rs1, int32x2_t rs2) {
   return __riscv_mqracc_w11_i64(rd, rs1, rs2);
 }
+
+/* Packed Element Extract */
+
+// RV32-LABEL: define dso_local signext i8 @test_pget_i8x4_i8(
+// RV32-SAME: i32 noundef [[V_COERCE:%.*]]) #[[ATTR0]] {
+// RV32-NEXT:  [[ENTRY:.*:]]
+// RV32-NEXT:    [[EXTELT_OFFSET:%.*]] = lshr i32 [[V_COERCE]], 24
+// RV32-NEXT:    [[VECEXT_I:%.*]] = trunc nuw i32 [[EXTELT_OFFSET]] to i8
+// RV32-NEXT:    ret i8 [[VECEXT_I]]
+//
+// RV64-LABEL: define dso_local signext i8 @test_pget_i8x4_i8(
+// RV64-SAME: i32 noundef [[V_COERCE:%.*]]) #[[ATTR0]] {
+// RV64-NEXT:  [[ENTRY:.*:]]
+// RV64-NEXT:    [[EXTELT_OFFSET:%.*]] = lshr i32 [[V_COERCE]], 24
+// RV64-NEXT:    [[VECEXT_I:%.*]] = trunc nuw i32 [[EXTELT_OFFSET]] to i8
+// RV64-NEXT:    ret i8 [[VECEXT_I]]
+//
+int8_t test_pget_i8x4_i8(int8x4_t v) {
+  return __riscv_pget_i8x4_i8(v, 3);
+}
+
+// RV32-LABEL: define dso_local zeroext i8 @test_pget_u8x4_u8(
+// RV32-SAME: i32 noundef [[V_COERCE:%.*]]) #[[ATTR0]] {
+// RV32-NEXT:  [[ENTRY:.*:]]
+// RV32-NEXT:    [[EXTELT_OFFSET:%.*]] = lshr i32 [[V_COERCE]], 24
+// RV32-NEXT:    [[VECEXT_I:%.*]] = trunc nuw i32 [[EXTELT_OFFSET]] to i8
+// RV32-NEXT:    ret i8 [[VECEXT_I]]
+//
+// RV64-LABEL: define dso_local zeroext i8 @test_pget_u8x4_u8(
+// RV64-SAME: i32 noundef [[V_COERCE:%.*]]) #[[ATTR0]] {
+// RV64-NEXT:  [[ENTRY:.*:]]
+// RV64-NEXT:    [[EXTELT_OFFSET:%.*]] = lshr i32 [[V_COERCE]], 24
+// RV64-NEXT:    [[VECEXT_I:%.*]] = trunc nuw i32 [[EXTELT_OFFSET]] to i8
+// RV64-NEXT:    ret i8 [[VECEXT_I]]
+//
+uint8_t test_pget_u8x4_u8(uint8x4_t v) {
+  return __riscv_pget_u8x4_u8(v, 3);
+}
+
+// RV32-LABEL: define dso_local signext i16 @test_pget_i16x2_i16(
+// RV32-SAME: i32 noundef [[V_COERCE:%.*]]) #[[ATTR0]] {
+// RV32-NEXT:  [[ENTRY:.*:]]
+// RV32-NEXT:    [[EXTELT_OFFSET:%.*]] = lshr i32 [[V_COERCE]], 16
+// RV32-NEXT:    [[VECEXT_I:%.*]] = trunc nuw i32 [[EXTELT_OFFSET]] to i16
+// RV32-NEXT:    ret i16 [[VECEXT_I]]
+//
+// RV64-LABEL: define dso_local signext i16 @test_pget_i16x2_i16(
+// RV64-SAME: i32 noundef [[V_COERCE:%.*]]) #[[ATTR0]] {
+// RV64-NEXT:  [[ENTRY:.*:]]
+// RV64-NEXT:    [[EXTELT_OFFSET:%.*]] = lshr i32 [[V_COERCE]], 16
+// RV64-NEXT:    [[VECEXT_I:%.*]] = trunc nuw i32 [[EXTELT_OFFSET]] to i16
+// RV64-NEXT:    ret i16 [[VECEXT_I]]
+//
+int16_t test_pget_i16x2_i16(int16x2_t v) {
+  return __riscv_pget_i16x2_i16(v, 1);
+}
+
+// RV32-LABEL: define dso_local zeroext i16 @test_pget_u16x2_u16(
+// RV32-SAME: i32 noundef [[V_COERCE:%.*]]) #[[ATTR0]] {
+// RV32-NEXT:  [[ENTRY:.*:]]
+// RV32-NEXT:    [[EXTELT_OFFSET:%.*]] = lshr i32 [[V_COERCE]], 16
+// RV32-NEXT:    [[VECEXT_I:%.*]] = trunc nuw i32 [[EXTELT_OFFSET]] to i16
+// RV32-NEXT:    ret i16 [[VECEXT_I]]
+//
+// RV64-LABEL: define dso_local zeroext i16 @test_pget_u16x2_u16(
+// RV64-SAME: i32 noundef [[V_COERCE:%.*]]) #[[ATTR0]] {
+// RV64-NEXT:  [[ENTRY:.*:]]
+// RV64-NEXT:    [[EXTELT_OFFSET:%.*]] = lshr i32 [[V_COERCE]], 16
+// RV64-NEXT:    [[VECEXT_I:%.*]] = trunc nuw i32 [[EXTELT_OFFSET]] to i16
+// RV64-NEXT:    ret i16 [[VECEXT_I]]
+//
+uint16_t test_pget_u16x2_u16(uint16x2_t v) {
+  return __riscv_pget_u16x2_u16(v, 1);
+}
+
+// RV32-LABEL: define dso_local signext i8 @test_pget_i8x8_i8(
+// RV32-SAME: i64 noundef [[V_COERCE:%.*]]) #[[ATTR0]] {
+// RV32-NEXT:  [[ENTRY:.*:]]
+// RV32-NEXT:    [[TMP0:%.*]] = bitcast i64 [[V_COERCE]] to <8 x i8>
+// RV32-NEXT:    [[VECEXT_I:%.*]] = extractelement <8 x i8> [[TMP0]], i64 7
+// RV32-NEXT:    ret i8 [[VECEXT_I]]
+//
+// RV64-LABEL: define dso_local signext i8 @test_pget_i8x8_i8(
+// RV64-SAME: i64 noundef [[V_COERCE:%.*]]) #[[ATTR0]] {
+// RV64-NEXT:  [[ENTRY:.*:]]
+// RV64-NEXT:    [[EXTELT_OFFSET:%.*]] = lshr i64 [[V_COERCE]], 56
+// RV64-NEXT:    [[VECEXT_I:%.*]] = trunc nuw i64 [[EXTELT_OFFSET]] to i8
+// RV64-NEXT:    ret i8 [[VECEXT_I]]
+//
+int8_t test_pget_i8x8_i8(int8x8_t v) {
+  return __riscv_pget_i8x8_i8(v, 7);
+}
+
+// RV32-LABEL: define dso_local zeroext i8 @test_pget_u8x8_u8(
+// RV32-SAME: i64 noundef [[V_COERCE:%.*]]) #[[ATTR0]] {
+// RV32-NEXT:  [[ENTRY:.*:]]
+// RV32-NEXT:    [[TMP0:%.*]] = bitcast i64 [[V_COERCE]] to <8 x i8>
+// RV32-NEXT:    [[VECEXT_I:%.*]] = extractelement <8 x i8> [[TMP0]], i64 7
+// RV32-NEXT:    ret i8 [[VECEXT_I]]
+//
+// RV64-LABEL: define dso_local zeroext i8 @test_pget_u8x8_u8(
+// RV64-SAME: i64 noundef [[V_COERCE:%.*]]) #[[ATTR0]] {
+// RV64-NEXT:  [[ENTRY:.*:]]
+// RV64-NEXT:    [[EXTELT_OFFSET:%.*]] = lshr i64 [[V_COERCE]], 56
+// RV64-NEXT:    [[VECEXT_I:%.*]] = trunc nuw i64 [[EXTELT_OFFSET]] to i8
+// RV64-NEXT:    ret i8 [[VECEXT_I]]
+//
+uint8_t test_pget_u8x8_u8(uint8x8_t v) {
+  return __riscv_pget_u8x8_u8(v, 7);
+}
+
+// RV32-LABEL: define dso_local signext i16 @test_pget_i16x4_i16(
+// RV32-SAME: i64 noundef [[V_COERCE:%.*]]) #[[ATTR0]] {
+// RV32-NEXT:  [[ENTRY:.*:]]
+// RV32-NEXT:    [[TMP0:%.*]] = bitcast i64 [[V_COERCE]] to <4 x i16>
+// RV32-NEXT:    [[VECEXT_I:%.*]] = extractelement <4 x i16> [[TMP0]], i64 3
+// RV32-NEXT:    ret i16 [[VECEXT_I]]
+//
+// RV64-LABEL: define dso_local signext i16 @test_pget_i16x4_i16(
+// RV64-SAME: i64 noundef [[V_COERCE:%.*]]) #[[ATTR0]] {
+// RV64-NEXT:  [[ENTRY:.*:]]
+// RV64-NEXT:    [[EXTELT_OFFSET:%.*]] = lshr i64 [[V_COERCE]], 48
+// RV64-NEXT:    [[VECEXT_I:%.*]] = trunc nuw i64 [[EXTELT_OFFSET]] to i16
+// RV64-NEXT:    ret i16 [[VECEXT_I]]
+//
+int16_t test_pget_i16x4_i16(int16x4_t v) {
+  return __riscv_pget_i16x4_i16(v, 3);
+}
+
+// RV32-LABEL: define dso_local zeroext i16 @test_pget_u16x4_u16(
+// RV32-SAME: i64 noundef [[V_COERCE:%.*]]) #[[ATTR0]] {
+// RV32-NEXT:  [[ENTRY:.*:]]
+// RV32-NEXT:    [[TMP0:%.*]] = bitcast i64 [[V_COERCE]] to <4 x i16>
+// RV32-NEXT:    [[VECEXT_I:%.*]] = extractelement <4 x i16> [[TMP0]], i64 3
+// RV32-NEXT:    ret i16 [[VECEXT_I]]
+//
+// RV64-LABEL: define dso_local zeroext i16 @test_pget_u16x4_u16(
+// RV64-SAME: i64 noundef [[V_COERCE:%.*]]) #[[ATTR0]] {
+// RV64-NEXT:  [[ENTRY:.*:]]
+// RV64-NEXT:    [[EXTELT_OFFSET:%.*]] = lshr i64 [[V_COERCE]], 48
+// RV64-NEXT:    [[VECEXT_I:%.*]] = trunc nuw i64 [[EXTELT_OFFSET]] to i16
+// RV64-NEXT:    ret i16 [[VECEXT_I]]
+//
+uint16_t test_pget_u16x4_u16(uint16x4_t v) {
+  return __riscv_pget_u16x4_u16(v, 3);
+}
+
+// RV32-LABEL: define dso_local i32 @test_pget_i32x2_i32(
+// RV32-SAME: i64 noundef [[V_COERCE:%.*]]) #[[ATTR0]] {
+// RV32-NEXT:  [[ENTRY:.*:]]
+// RV32-NEXT:    [[TMP0:%.*]] = bitcast i64 [[V_COERCE]] to <2 x i32>
+// RV32-NEXT:    [[VECEXT_I:%.*]] = extractelement <2 x i32> [[TMP0]], i64 1
+// RV32-NEXT:    ret i32 [[VECEXT_I]]
+//
+// RV64-LABEL: define dso_local signext i32 @test_pget_i32x2_i32(
+// RV64-SAME: i64 noundef [[V_COERCE:%.*]]) #[[ATTR0]] {
+// RV64-NEXT:  [[ENTRY:.*:]]
+// RV64-NEXT:    [[EXTELT_OFFSET:%.*]] = lshr i64 [[V_COERCE]], 32
+// RV64-NEXT:    [[VECEXT_I:%.*]] = trunc nuw i64 [[EXTELT_OFFSET]] to i32
+// RV64-NEXT:    ret i32 [[VECEXT_I]]
+//
+int32_t test_pget_i32x2_i32(int32x2_t v) {
+  return __riscv_pget_i32x2_i32(v, 1);
+}
+
+// RV32-LABEL: define dso_local i32 @test_pget_u32x2_u32(
+// RV32-SAME: i64 noundef [[V_COERCE:%.*]]) #[[ATTR0]] {
+// RV32-NEXT:  [[ENTRY:.*:]]
+// RV32-NEXT:    [[TMP0:%.*]] = bitcast i64 [[V_COERCE]] to <2 x i32>
+// RV32-NEXT:    [[VECEXT_I:%.*]] = extractelement <2 x i32> [[TMP0]], i64 1
+// RV32-NEXT:    ret i32 [[VECEXT_I]]
+//
+// RV64-LABEL: define dso_local signext i32 @test_pget_u32x2_u32(
+// RV64-SAME: i64 noundef [[V_COERCE:%.*]]) #[[ATTR0]] {
+// RV64-NEXT:  [[ENTRY:.*:]]
+// RV64-NEXT:    [[EXTELT_OFFSET:%.*]] = lshr i64 [[V_COERCE]], 32
+// RV64-NEXT:    [[VECEXT_I:%.*]] = trunc nuw i64 [[EXTELT_OFFSET]] to i32
+// RV64-NEXT:    ret i32 [[VECEXT_I]]
+//
+uint32_t test_pget_u32x2_u32(uint32x2_t v) {
+  return __riscv_pget_u32x2_u32(v, 1);
+}
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 d76b2b0a4c7db..3a1045a8b94f1 100644
--- a/cross-project-tests/intrinsic-header-tests/riscv_packed_simd.c
+++ b/cross-project-tests/intrinsic-header-tests/riscv_packed_simd.c
@@ -4172,3 +4172,89 @@ int64_t test_mulsu_w00_i64(int32x2_t a, uint32x2_t b) {
 int64_t test_mulsu_w11_i64(int32x2_t a, uint32x2_t b) {
   return __riscv_mulsu_w11_i64(a, b);
 }
+
+// CHECK-LABEL: test_pget_i8x4_i8:
+// CHECK:       srai
+int8_t test_pget_i8x4_i8(int8x4_t v) {
+  return __riscv_pget_i8x4_i8(v, 3);
+}
+
+// CHECK-LABEL: test_pget_i8x4_i8_idx0:
+// CHECK:       sext.b
+int8_t test_pget_i8x4_i8_idx0(int8x4_t v) {
+  return __riscv_pget_i8x4_i8(v, 0);
+}
+
+// CHECK-LABEL: test_pget_u8x4_u8:
+// CHECK:       srli
+uint8_t test_pget_u8x4_u8(uint8x4_t v) {
+  return __riscv_pget_u8x4_u8(v, 3);
+}
+
+// CHECK-LABEL: test_pget_u8x4_u8_idx0:
+// CHECK:       zext.b
+uint8_t test_pget_u8x4_u8_idx0(uint8x4_t v) {
+  return __riscv_pget_u8x4_u8(v, 0);
+}
+
+// CHECK-LABEL: test_pget_i16x2_i16:
+// CHECK:       srai
+int16_t test_pget_i16x2_i16(int16x2_t v) {
+  return __riscv_pget_i16x2_i16(v, 1);
+}
+
+// CHECK-LABEL: test_pget_i16x2_i16_idx0:
+// CHECK:       sext.h
+int16_t test_pget_i16x2_i16_idx0(int16x2_t v) {
+  return __riscv_pget_i16x2_i16(v, 0);
+}
+
+// CHECK-LABEL: test_pget_u16x2_u16:
+// CHECK:       srli
+uint16_t test_pget_u16x2_u16(uint16x2_t v) {
+  return __riscv_pget_u16x2_u16(v, 1);
+}
+
+// CHECK-LABEL: test_pget_u16x2_u16_idx0:
+// CHECK:       zext.h
+uint16_t test_pget_u16x2_u16_idx0(uint16x2_t v) {
+  return __riscv_pget_u16x2_u16(v, 0);
+}
+
+// CHECK-LABEL: test_pget_i8x8_i8:
+// CHECK:       srai
+int8_t test_pget_i8x8_i8(int8x8_t v) {
+  return __riscv_pget_i8x8_i8(v, 7);
+}
+
+// CHECK-LABEL: test_pget_u8x8_u8:
+// CHECK:       srli
+uint8_t test_pget_u8x8_u8(uint8x8_t v) {
+  return __riscv_pget_u8x8_u8(v, 7);
+}
+
+// CHECK-LABEL: test_pget_i16x4_i16:
+// CHECK:       srai
+int16_t test_pget_i16x4_i16(int16x4_t v) {
+  return __riscv_pget_i16x4_i16(v, 3);
+}
+
+// CHECK-LABEL: test_pget_u16x4_u16:
+// CHECK:       srli
+uint16_t test_pget_u16x4_u16(uint16x4_t v) {
+  return __riscv_pget_u16x4_u16(v, 3);
+}
+
+// CHECK-LABEL: test_pget_i32x2_i32:
+// RV32:        mv
+// RV64:        srai
+int32_t test_pget_i32x2_i32(int32x2_t v) {
+  return __riscv_pget_i32x2_i32(v, 1);
+}
+
+// CHECK-LABEL: test_pget_u32x2_u32:
+// RV32:        mv
+// RV64:        srai
+uint32_t test_pget_u32x2_u32(uint32x2_t v) {
+  return __riscv_pget_u32x2_u32(v, 1);
+}

>From 8b29c10ee97646bad295cffa4ab755d5859e788a Mon Sep 17 00:00:00 2001
From: XChy <xxs_chy at outlook.com>
Date: Sun, 6 Sep 2026 21:00:06 +0800
Subject: [PATCH 2/3] format

---
 .../riscv_packed_simd.c                       | 20 +++++--------------
 1 file changed, 5 insertions(+), 15 deletions(-)

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 3a1045a8b94f1..48fcf036794ff 100644
--- a/cross-project-tests/intrinsic-header-tests/riscv_packed_simd.c
+++ b/cross-project-tests/intrinsic-header-tests/riscv_packed_simd.c
@@ -4175,21 +4175,15 @@ int64_t test_mulsu_w11_i64(int32x2_t a, uint32x2_t b) {
 
 // CHECK-LABEL: test_pget_i8x4_i8:
 // CHECK:       srai
-int8_t test_pget_i8x4_i8(int8x4_t v) {
-  return __riscv_pget_i8x4_i8(v, 3);
-}
+int8_t test_pget_i8x4_i8(int8x4_t v) { return __riscv_pget_i8x4_i8(v, 3); }
 
 // CHECK-LABEL: test_pget_i8x4_i8_idx0:
 // CHECK:       sext.b
-int8_t test_pget_i8x4_i8_idx0(int8x4_t v) {
-  return __riscv_pget_i8x4_i8(v, 0);
-}
+int8_t test_pget_i8x4_i8_idx0(int8x4_t v) { return __riscv_pget_i8x4_i8(v, 0); }
 
 // CHECK-LABEL: test_pget_u8x4_u8:
 // CHECK:       srli
-uint8_t test_pget_u8x4_u8(uint8x4_t v) {
-  return __riscv_pget_u8x4_u8(v, 3);
-}
+uint8_t test_pget_u8x4_u8(uint8x4_t v) { return __riscv_pget_u8x4_u8(v, 3); }
 
 // CHECK-LABEL: test_pget_u8x4_u8_idx0:
 // CHECK:       zext.b
@@ -4223,15 +4217,11 @@ uint16_t test_pget_u16x2_u16_idx0(uint16x2_t v) {
 
 // CHECK-LABEL: test_pget_i8x8_i8:
 // CHECK:       srai
-int8_t test_pget_i8x8_i8(int8x8_t v) {
-  return __riscv_pget_i8x8_i8(v, 7);
-}
+int8_t test_pget_i8x8_i8(int8x8_t v) { return __riscv_pget_i8x8_i8(v, 7); }
 
 // CHECK-LABEL: test_pget_u8x8_u8:
 // CHECK:       srli
-uint8_t test_pget_u8x8_u8(uint8x8_t v) {
-  return __riscv_pget_u8x8_u8(v, 7);
-}
+uint8_t test_pget_u8x8_u8(uint8x8_t v) { return __riscv_pget_u8x8_u8(v, 7); }
 
 // CHECK-LABEL: test_pget_i16x4_i16:
 // CHECK:       srai

>From fee480d96ef5d3ebe5549615ff66368306608e3c Mon Sep 17 00:00:00 2001
From: XChy <xxs_chy at outlook.com>
Date: Tue, 8 Sep 2026 02:50:44 +0800
Subject: [PATCH 3/3] add test

---
 clang/lib/Headers/riscv_packed_simd.h         |  4 +--
 .../RISCV/rvp-pget-index-out-of-range.c       | 30 +++++++++++++++++++
 2 files changed, 32 insertions(+), 2 deletions(-)
 create mode 100644 clang/test/CodeGen/RISCV/rvp-pget-index-out-of-range.c

diff --git a/clang/lib/Headers/riscv_packed_simd.h b/clang/lib/Headers/riscv_packed_simd.h
index 7f75a5ef3e5fd..37ac140780d02 100644
--- a/clang/lib/Headers/riscv_packed_simd.h
+++ b/clang/lib/Headers/riscv_packed_simd.h
@@ -67,8 +67,8 @@ typedef uint32_t uint32x2_t __attribute__((__vector_size__(8)));
   }
 
 #define __packed_extract(name, rty, ty, max_idx)                               \
-  static __inline__ rty __DEFAULT_FN_ATTRS __riscv_##name(                     \
-      ty __v, const unsigned __idx)                                            \
+  static __inline__ rty __DEFAULT_FN_ATTRS __riscv_##name(ty __v,              \
+                                                          unsigned __idx)      \
       __attribute__((__enable_if__(                                            \
           __idx <= (max_idx),                                                  \
           "index must be a constant integer from 0 to " #max_idx))) {          \
diff --git a/clang/test/CodeGen/RISCV/rvp-pget-index-out-of-range.c b/clang/test/CodeGen/RISCV/rvp-pget-index-out-of-range.c
new file mode 100644
index 0000000000000..cb2c5b5540491
--- /dev/null
+++ b/clang/test/CodeGen/RISCV/rvp-pget-index-out-of-range.c
@@ -0,0 +1,30 @@
+// REQUIRES: riscv-registered-target
+// RUN: %clang_cc1 -triple riscv32 -target-feature +experimental-p \
+// RUN:   -fsyntax-only -verify -verify-ignore-unexpected=note %s
+// RUN: %clang_cc1 -triple riscv64 -target-feature +experimental-p \
+// RUN:   -fsyntax-only -verify -verify-ignore-unexpected=note %s
+
+#include <riscv_packed_simd.h>
+
+// expected-note@*:* 2 {{candidate disabled: index must be a constant integer from 0 to 3}}
+// expected-note@*:* {{candidate disabled: index must be a constant integer from 0 to 1}}
+// expected-note@*:* {{candidate disabled: index must be a constant integer from 0 to 7}}
+int8_t test_pget_nonconstant(int8x4_t v, unsigned idx) {
+  // expected-error at +1 {{no matching function for call to '__riscv_pget_i8x4_i8'}}
+  return __riscv_pget_i8x4_i8(v, idx);
+}
+
+int16_t test_pget_i16x2_out_of_range(int16x2_t v) {
+  // expected-error at +1 {{no matching function for call to '__riscv_pget_i16x2_i16'}}
+  return __riscv_pget_i16x2_i16(v, 2);
+}
+
+uint8_t test_pget_u8x4_out_of_range(uint8x4_t v) {
+  // expected-error at +1 {{no matching function for call to '__riscv_pget_u8x4_u8'}}
+  return __riscv_pget_u8x4_u8(v, 4);
+}
+
+uint8_t test_pget_u8x8_out_of_range(uint8x8_t v) {
+  // expected-error at +1 {{no matching function for call to '__riscv_pget_u8x8_u8'}}
+  return __riscv_pget_u8x8_u8(v, 8);
+}



More information about the cfe-commits mailing list