Author: SiHuaN
Date: 2026-09-18T11:09:04+08:00
New Revision: ac0c8eb5aa55af2387b6c925de26e159b7a8a271

URL: 
https://github.com/llvm/llvm-project/commit/ac0c8eb5aa55af2387b6c925de26e159b7a8a271
DIFF: 
https://github.com/llvm/llvm-project/commit/ac0c8eb5aa55af2387b6c925de26e159b7a8a271.diff

LOG: [Clang][RISCV] Add packed subvector extract intrinsics (#224429)

Add the Packed Subvector Extract intrinsics:

- `__riscv_pget_i8x8_i8x4`
- `__riscv_pget_u8x8_u8x4`
- `__riscv_pget_i16x4_i16x2`
- `__riscv_pget_u16x4_u16x2`

Each extracts the 32-bit packed subvector selected by a constant index
(0 = low, 1 = high) from a 64-bit packed vector. The index is
range-checked with `__enable_if__`, as for the element extract
intrinsics.

This is header-only: the shuffle is selected without backend changes, so
no new IR intrinsics or builtins are required.

Added: 
    

Modified: 
    clang/lib/Headers/riscv_packed_simd.h
    clang/test/CodeGen/RISCV/rvp-intrinsics.c
    cross-project-tests/intrinsic-header-tests/riscv_packed_simd.c

Removed: 
    


################################################################################
diff  --git a/clang/lib/Headers/riscv_packed_simd.h 
b/clang/lib/Headers/riscv_packed_simd.h
index cfa673e365d9f..db6d0d37c2e8a 100644
--- a/clang/lib/Headers/riscv_packed_simd.h
+++ b/clang/lib/Headers/riscv_packed_simd.h
@@ -75,6 +75,23 @@ typedef uint32_t uint32x2_t 
__attribute__((__vector_size__(8)));
     return __v[__idx];                                                         
\
   }
 
+#define __packed_subvector_extract8(name, rty, ty)                             
\
+  static __inline__ rty __DEFAULT_FN_ATTRS __riscv_##name(ty __v,              
\
+                                                          unsigned __idx)      
\
+      __attribute__((__enable_if__(                                            
\
+          __idx <= 1, "index must be a constant integer from 0 to 1"))) {      
\
+    return __idx ? __builtin_shufflevector(__v, __v, 4, 5, 6, 7)               
\
+                 : __builtin_shufflevector(__v, __v, 0, 1, 2, 3);              
\
+  }
+#define __packed_subvector_extract4(name, rty, ty)                             
\
+  static __inline__ rty __DEFAULT_FN_ATTRS __riscv_##name(ty __v,              
\
+                                                          unsigned __idx)      
\
+      __attribute__((__enable_if__(                                            
\
+          __idx <= 1, "index must be a constant integer from 0 to 1"))) {      
\
+    return __idx ? __builtin_shufflevector(__v, __v, 2, 3)                     
\
+                 : __builtin_shufflevector(__v, __v, 0, 1);                    
\
+  }
+
 #define __packed_store(name, ty, elt_ty)                                       
\
   static __inline__ void __DEFAULT_FN_ATTRS __riscv_##name(elt_ty *__p,        
\
                                                            ty __v) {           
\
@@ -1132,6 +1149,12 @@ __packed_concat4(pjoin2_u8x8, uint8x8_t, uint8x4_t)
 __packed_concat2(pjoin2_i16x4, int16x4_t, int16x2_t)
 __packed_concat2(pjoin2_u16x4, uint16x4_t, uint16x2_t)
 
+/* Packed Subvector Extract */
+__packed_subvector_extract8(pget_i8x8_i8x4, int8x4_t, int8x8_t)
+__packed_subvector_extract8(pget_u8x8_u8x4, uint8x4_t, uint8x8_t)
+__packed_subvector_extract4(pget_i16x4_i16x2, int16x2_t, int16x4_t)
+__packed_subvector_extract4(pget_u16x4_u16x2, uint16x2_t, uint16x4_t)
+
 /* Packed Store (32-bit) */
 __packed_store(pst_i8x4, int8x4_t, int8_t)
 __packed_store(pst_u8x4, uint8x4_t, uint8_t)
@@ -1327,6 +1350,8 @@ __packed_reinterpret(u32x2_i32x2, int32x2_t, uint32x2_t)
 #undef __packed_abdsum
 #undef __packed_ternary_builtin_cast
 #undef __packed_extract
+#undef __packed_subvector_extract8
+#undef __packed_subvector_extract4
 #undef __packed_insert
 #undef __packed_join2
 #undef __packed_join4

diff  --git a/clang/test/CodeGen/RISCV/rvp-intrinsics.c 
b/clang/test/CodeGen/RISCV/rvp-intrinsics.c
index 412c63a182b11..c6721dbeb5db8 100644
--- a/clang/test/CodeGen/RISCV/rvp-intrinsics.c
+++ b/clang/test/CodeGen/RISCV/rvp-intrinsics.c
@@ -11990,3 +11990,253 @@ int16x4_t test_pjoin2_i16x4(int16x2_t lo, int16x2_t 
hi) {
 uint16x4_t test_pjoin2_u16x4(uint16x2_t lo, uint16x2_t hi) {
   return __riscv_pjoin2_u16x4(lo, hi);
 }
+
+/* Packed Subvector Extract */
+
+// RV32-LABEL: define dso_local i32 @test_pget_i8x8_i8x4(
+// RV32-SAME: i64 noundef [[V_COERCE:%.*]]) #[[ATTR0]] {
+// RV32-NEXT:  [[ENTRY:.*:]]
+// RV32-NEXT:    br i1 false, label %[[COND_TRUE_I:.*]], label 
%[[COND_FALSE_I:.*]]
+// RV32:       [[COND_TRUE_I]]:
+// RV32-NEXT:    br label %[[__RISCV_PGET_I8X8_I8X4_EXIT:.*]]
+// RV32:       [[COND_FALSE_I]]:
+// RV32-NEXT:    [[SHUFFLE2_I_EXTRACT:%.*]] = trunc i64 [[V_COERCE]] to i32
+// RV32-NEXT:    br label %[[__RISCV_PGET_I8X8_I8X4_EXIT]]
+// RV32:       [[__RISCV_PGET_I8X8_I8X4_EXIT]]:
+// RV32-NEXT:    [[TMP0:%.*]] = phi i32 [ poison, %[[COND_TRUE_I]] ], [ 
[[SHUFFLE2_I_EXTRACT]], %[[COND_FALSE_I]] ]
+// RV32-NEXT:    ret i32 [[TMP0]]
+//
+// RV64-LABEL: define dso_local i32 @test_pget_i8x8_i8x4(
+// RV64-SAME: i64 noundef [[V_COERCE:%.*]]) #[[ATTR0]] {
+// RV64-NEXT:  [[ENTRY:.*:]]
+// RV64-NEXT:    br i1 false, label %[[COND_TRUE_I:.*]], label 
%[[COND_FALSE_I:.*]]
+// RV64:       [[COND_TRUE_I]]:
+// RV64-NEXT:    br label %[[__RISCV_PGET_I8X8_I8X4_EXIT:.*]]
+// RV64:       [[COND_FALSE_I]]:
+// RV64-NEXT:    [[SHUFFLE2_I_EXTRACT:%.*]] = trunc i64 [[V_COERCE]] to i32
+// RV64-NEXT:    br label %[[__RISCV_PGET_I8X8_I8X4_EXIT]]
+// RV64:       [[__RISCV_PGET_I8X8_I8X4_EXIT]]:
+// RV64-NEXT:    [[TMP0:%.*]] = phi i32 [ poison, %[[COND_TRUE_I]] ], [ 
[[SHUFFLE2_I_EXTRACT]], %[[COND_FALSE_I]] ]
+// RV64-NEXT:    ret i32 [[TMP0]]
+//
+int8x4_t test_pget_i8x8_i8x4(int8x8_t v) {
+  return __riscv_pget_i8x8_i8x4(v, 0);
+}
+
+// RV32-LABEL: define dso_local i32 @test_pget_i8x8_i8x4_idx1(
+// RV32-SAME: i64 noundef [[V_COERCE:%.*]]) #[[ATTR0]] {
+// RV32-NEXT:  [[ENTRY:.*:]]
+// RV32-NEXT:    br i1 true, label %[[COND_TRUE_I:.*]], label 
%[[COND_FALSE_I:.*]]
+// RV32:       [[COND_TRUE_I]]:
+// RV32-NEXT:    [[SHUFFLE_I_BC:%.*]] = bitcast i64 [[V_COERCE]] to <2 x i32>
+// RV32-NEXT:    [[SHUFFLE_I_EXTRACT:%.*]] = extractelement <2 x i32> 
[[SHUFFLE_I_BC]], i64 1
+// RV32-NEXT:    br label %[[__RISCV_PGET_I8X8_I8X4_EXIT:.*]]
+// RV32:       [[COND_FALSE_I]]:
+// RV32-NEXT:    br label %[[__RISCV_PGET_I8X8_I8X4_EXIT]]
+// RV32:       [[__RISCV_PGET_I8X8_I8X4_EXIT]]:
+// RV32-NEXT:    [[TMP0:%.*]] = phi i32 [ [[SHUFFLE_I_EXTRACT]], 
%[[COND_TRUE_I]] ], [ poison, %[[COND_FALSE_I]] ]
+// RV32-NEXT:    ret i32 [[TMP0]]
+//
+// RV64-LABEL: define dso_local i32 @test_pget_i8x8_i8x4_idx1(
+// RV64-SAME: i64 noundef [[V_COERCE:%.*]]) #[[ATTR0]] {
+// RV64-NEXT:  [[ENTRY:.*:]]
+// RV64-NEXT:    br i1 true, label %[[COND_TRUE_I:.*]], label 
%[[COND_FALSE_I:.*]]
+// RV64:       [[COND_TRUE_I]]:
+// RV64-NEXT:    [[EXTELT_OFFSET:%.*]] = lshr i64 [[V_COERCE]], 32
+// RV64-NEXT:    [[SHUFFLE_I_EXTRACT:%.*]] = trunc nuw i64 [[EXTELT_OFFSET]] 
to i32
+// RV64-NEXT:    br label %[[__RISCV_PGET_I8X8_I8X4_EXIT:.*]]
+// RV64:       [[COND_FALSE_I]]:
+// RV64-NEXT:    br label %[[__RISCV_PGET_I8X8_I8X4_EXIT]]
+// RV64:       [[__RISCV_PGET_I8X8_I8X4_EXIT]]:
+// RV64-NEXT:    [[TMP0:%.*]] = phi i32 [ [[SHUFFLE_I_EXTRACT]], 
%[[COND_TRUE_I]] ], [ poison, %[[COND_FALSE_I]] ]
+// RV64-NEXT:    ret i32 [[TMP0]]
+//
+int8x4_t test_pget_i8x8_i8x4_idx1(int8x8_t v) {
+  return __riscv_pget_i8x8_i8x4(v, 1);
+}
+
+// RV32-LABEL: define dso_local i32 @test_pget_u8x8_u8x4(
+// RV32-SAME: i64 noundef [[V_COERCE:%.*]]) #[[ATTR0]] {
+// RV32-NEXT:  [[ENTRY:.*:]]
+// RV32-NEXT:    br i1 false, label %[[COND_TRUE_I:.*]], label 
%[[COND_FALSE_I:.*]]
+// RV32:       [[COND_TRUE_I]]:
+// RV32-NEXT:    br label %[[__RISCV_PGET_U8X8_U8X4_EXIT:.*]]
+// RV32:       [[COND_FALSE_I]]:
+// RV32-NEXT:    [[SHUFFLE2_I_EXTRACT:%.*]] = trunc i64 [[V_COERCE]] to i32
+// RV32-NEXT:    br label %[[__RISCV_PGET_U8X8_U8X4_EXIT]]
+// RV32:       [[__RISCV_PGET_U8X8_U8X4_EXIT]]:
+// RV32-NEXT:    [[TMP0:%.*]] = phi i32 [ poison, %[[COND_TRUE_I]] ], [ 
[[SHUFFLE2_I_EXTRACT]], %[[COND_FALSE_I]] ]
+// RV32-NEXT:    ret i32 [[TMP0]]
+//
+// RV64-LABEL: define dso_local i32 @test_pget_u8x8_u8x4(
+// RV64-SAME: i64 noundef [[V_COERCE:%.*]]) #[[ATTR0]] {
+// RV64-NEXT:  [[ENTRY:.*:]]
+// RV64-NEXT:    br i1 false, label %[[COND_TRUE_I:.*]], label 
%[[COND_FALSE_I:.*]]
+// RV64:       [[COND_TRUE_I]]:
+// RV64-NEXT:    br label %[[__RISCV_PGET_U8X8_U8X4_EXIT:.*]]
+// RV64:       [[COND_FALSE_I]]:
+// RV64-NEXT:    [[SHUFFLE2_I_EXTRACT:%.*]] = trunc i64 [[V_COERCE]] to i32
+// RV64-NEXT:    br label %[[__RISCV_PGET_U8X8_U8X4_EXIT]]
+// RV64:       [[__RISCV_PGET_U8X8_U8X4_EXIT]]:
+// RV64-NEXT:    [[TMP0:%.*]] = phi i32 [ poison, %[[COND_TRUE_I]] ], [ 
[[SHUFFLE2_I_EXTRACT]], %[[COND_FALSE_I]] ]
+// RV64-NEXT:    ret i32 [[TMP0]]
+//
+uint8x4_t test_pget_u8x8_u8x4(uint8x8_t v) {
+  return __riscv_pget_u8x8_u8x4(v, 0);
+}
+
+// RV32-LABEL: define dso_local i32 @test_pget_u8x8_u8x4_idx1(
+// RV32-SAME: i64 noundef [[V_COERCE:%.*]]) #[[ATTR0]] {
+// RV32-NEXT:  [[ENTRY:.*:]]
+// RV32-NEXT:    br i1 true, label %[[COND_TRUE_I:.*]], label 
%[[COND_FALSE_I:.*]]
+// RV32:       [[COND_TRUE_I]]:
+// RV32-NEXT:    [[SHUFFLE_I_BC:%.*]] = bitcast i64 [[V_COERCE]] to <2 x i32>
+// RV32-NEXT:    [[SHUFFLE_I_EXTRACT:%.*]] = extractelement <2 x i32> 
[[SHUFFLE_I_BC]], i64 1
+// RV32-NEXT:    br label %[[__RISCV_PGET_U8X8_U8X4_EXIT:.*]]
+// RV32:       [[COND_FALSE_I]]:
+// RV32-NEXT:    br label %[[__RISCV_PGET_U8X8_U8X4_EXIT]]
+// RV32:       [[__RISCV_PGET_U8X8_U8X4_EXIT]]:
+// RV32-NEXT:    [[TMP0:%.*]] = phi i32 [ [[SHUFFLE_I_EXTRACT]], 
%[[COND_TRUE_I]] ], [ poison, %[[COND_FALSE_I]] ]
+// RV32-NEXT:    ret i32 [[TMP0]]
+//
+// RV64-LABEL: define dso_local i32 @test_pget_u8x8_u8x4_idx1(
+// RV64-SAME: i64 noundef [[V_COERCE:%.*]]) #[[ATTR0]] {
+// RV64-NEXT:  [[ENTRY:.*:]]
+// RV64-NEXT:    br i1 true, label %[[COND_TRUE_I:.*]], label 
%[[COND_FALSE_I:.*]]
+// RV64:       [[COND_TRUE_I]]:
+// RV64-NEXT:    [[EXTELT_OFFSET:%.*]] = lshr i64 [[V_COERCE]], 32
+// RV64-NEXT:    [[SHUFFLE_I_EXTRACT:%.*]] = trunc nuw i64 [[EXTELT_OFFSET]] 
to i32
+// RV64-NEXT:    br label %[[__RISCV_PGET_U8X8_U8X4_EXIT:.*]]
+// RV64:       [[COND_FALSE_I]]:
+// RV64-NEXT:    br label %[[__RISCV_PGET_U8X8_U8X4_EXIT]]
+// RV64:       [[__RISCV_PGET_U8X8_U8X4_EXIT]]:
+// RV64-NEXT:    [[TMP0:%.*]] = phi i32 [ [[SHUFFLE_I_EXTRACT]], 
%[[COND_TRUE_I]] ], [ poison, %[[COND_FALSE_I]] ]
+// RV64-NEXT:    ret i32 [[TMP0]]
+//
+uint8x4_t test_pget_u8x8_u8x4_idx1(uint8x8_t v) {
+  return __riscv_pget_u8x8_u8x4(v, 1);
+}
+
+// RV32-LABEL: define dso_local i32 @test_pget_i16x4_i16x2(
+// RV32-SAME: i64 noundef [[V_COERCE:%.*]]) #[[ATTR0]] {
+// RV32-NEXT:  [[ENTRY:.*:]]
+// RV32-NEXT:    br i1 false, label %[[COND_TRUE_I:.*]], label 
%[[COND_FALSE_I:.*]]
+// RV32:       [[COND_TRUE_I]]:
+// RV32-NEXT:    br label %[[__RISCV_PGET_I16X4_I16X2_EXIT:.*]]
+// RV32:       [[COND_FALSE_I]]:
+// RV32-NEXT:    [[SHUFFLE2_I_EXTRACT:%.*]] = trunc i64 [[V_COERCE]] to i32
+// RV32-NEXT:    br label %[[__RISCV_PGET_I16X4_I16X2_EXIT]]
+// RV32:       [[__RISCV_PGET_I16X4_I16X2_EXIT]]:
+// RV32-NEXT:    [[TMP0:%.*]] = phi i32 [ poison, %[[COND_TRUE_I]] ], [ 
[[SHUFFLE2_I_EXTRACT]], %[[COND_FALSE_I]] ]
+// RV32-NEXT:    ret i32 [[TMP0]]
+//
+// RV64-LABEL: define dso_local i32 @test_pget_i16x4_i16x2(
+// RV64-SAME: i64 noundef [[V_COERCE:%.*]]) #[[ATTR0]] {
+// RV64-NEXT:  [[ENTRY:.*:]]
+// RV64-NEXT:    br i1 false, label %[[COND_TRUE_I:.*]], label 
%[[COND_FALSE_I:.*]]
+// RV64:       [[COND_TRUE_I]]:
+// RV64-NEXT:    br label %[[__RISCV_PGET_I16X4_I16X2_EXIT:.*]]
+// RV64:       [[COND_FALSE_I]]:
+// RV64-NEXT:    [[SHUFFLE2_I_EXTRACT:%.*]] = trunc i64 [[V_COERCE]] to i32
+// RV64-NEXT:    br label %[[__RISCV_PGET_I16X4_I16X2_EXIT]]
+// RV64:       [[__RISCV_PGET_I16X4_I16X2_EXIT]]:
+// RV64-NEXT:    [[TMP0:%.*]] = phi i32 [ poison, %[[COND_TRUE_I]] ], [ 
[[SHUFFLE2_I_EXTRACT]], %[[COND_FALSE_I]] ]
+// RV64-NEXT:    ret i32 [[TMP0]]
+//
+int16x2_t test_pget_i16x4_i16x2(int16x4_t v) {
+  return __riscv_pget_i16x4_i16x2(v, 0);
+}
+
+// RV32-LABEL: define dso_local i32 @test_pget_i16x4_i16x2_idx1(
+// RV32-SAME: i64 noundef [[V_COERCE:%.*]]) #[[ATTR0]] {
+// RV32-NEXT:  [[ENTRY:.*:]]
+// RV32-NEXT:    br i1 true, label %[[COND_TRUE_I:.*]], label 
%[[COND_FALSE_I:.*]]
+// RV32:       [[COND_TRUE_I]]:
+// RV32-NEXT:    [[SHUFFLE_I_BC:%.*]] = bitcast i64 [[V_COERCE]] to <2 x i32>
+// RV32-NEXT:    [[SHUFFLE_I_EXTRACT:%.*]] = extractelement <2 x i32> 
[[SHUFFLE_I_BC]], i64 1
+// RV32-NEXT:    br label %[[__RISCV_PGET_I16X4_I16X2_EXIT:.*]]
+// RV32:       [[COND_FALSE_I]]:
+// RV32-NEXT:    br label %[[__RISCV_PGET_I16X4_I16X2_EXIT]]
+// RV32:       [[__RISCV_PGET_I16X4_I16X2_EXIT]]:
+// RV32-NEXT:    [[TMP0:%.*]] = phi i32 [ [[SHUFFLE_I_EXTRACT]], 
%[[COND_TRUE_I]] ], [ poison, %[[COND_FALSE_I]] ]
+// RV32-NEXT:    ret i32 [[TMP0]]
+//
+// RV64-LABEL: define dso_local i32 @test_pget_i16x4_i16x2_idx1(
+// RV64-SAME: i64 noundef [[V_COERCE:%.*]]) #[[ATTR0]] {
+// RV64-NEXT:  [[ENTRY:.*:]]
+// RV64-NEXT:    br i1 true, label %[[COND_TRUE_I:.*]], label 
%[[COND_FALSE_I:.*]]
+// RV64:       [[COND_TRUE_I]]:
+// RV64-NEXT:    [[EXTELT_OFFSET:%.*]] = lshr i64 [[V_COERCE]], 32
+// RV64-NEXT:    [[SHUFFLE_I_EXTRACT:%.*]] = trunc nuw i64 [[EXTELT_OFFSET]] 
to i32
+// RV64-NEXT:    br label %[[__RISCV_PGET_I16X4_I16X2_EXIT:.*]]
+// RV64:       [[COND_FALSE_I]]:
+// RV64-NEXT:    br label %[[__RISCV_PGET_I16X4_I16X2_EXIT]]
+// RV64:       [[__RISCV_PGET_I16X4_I16X2_EXIT]]:
+// RV64-NEXT:    [[TMP0:%.*]] = phi i32 [ [[SHUFFLE_I_EXTRACT]], 
%[[COND_TRUE_I]] ], [ poison, %[[COND_FALSE_I]] ]
+// RV64-NEXT:    ret i32 [[TMP0]]
+//
+int16x2_t test_pget_i16x4_i16x2_idx1(int16x4_t v) {
+  return __riscv_pget_i16x4_i16x2(v, 1);
+}
+
+// RV32-LABEL: define dso_local i32 @test_pget_u16x4_u16x2(
+// RV32-SAME: i64 noundef [[V_COERCE:%.*]]) #[[ATTR0]] {
+// RV32-NEXT:  [[ENTRY:.*:]]
+// RV32-NEXT:    br i1 false, label %[[COND_TRUE_I:.*]], label 
%[[COND_FALSE_I:.*]]
+// RV32:       [[COND_TRUE_I]]:
+// RV32-NEXT:    br label %[[__RISCV_PGET_U16X4_U16X2_EXIT:.*]]
+// RV32:       [[COND_FALSE_I]]:
+// RV32-NEXT:    [[SHUFFLE2_I_EXTRACT:%.*]] = trunc i64 [[V_COERCE]] to i32
+// RV32-NEXT:    br label %[[__RISCV_PGET_U16X4_U16X2_EXIT]]
+// RV32:       [[__RISCV_PGET_U16X4_U16X2_EXIT]]:
+// RV32-NEXT:    [[TMP0:%.*]] = phi i32 [ poison, %[[COND_TRUE_I]] ], [ 
[[SHUFFLE2_I_EXTRACT]], %[[COND_FALSE_I]] ]
+// RV32-NEXT:    ret i32 [[TMP0]]
+//
+// RV64-LABEL: define dso_local i32 @test_pget_u16x4_u16x2(
+// RV64-SAME: i64 noundef [[V_COERCE:%.*]]) #[[ATTR0]] {
+// RV64-NEXT:  [[ENTRY:.*:]]
+// RV64-NEXT:    br i1 false, label %[[COND_TRUE_I:.*]], label 
%[[COND_FALSE_I:.*]]
+// RV64:       [[COND_TRUE_I]]:
+// RV64-NEXT:    br label %[[__RISCV_PGET_U16X4_U16X2_EXIT:.*]]
+// RV64:       [[COND_FALSE_I]]:
+// RV64-NEXT:    [[SHUFFLE2_I_EXTRACT:%.*]] = trunc i64 [[V_COERCE]] to i32
+// RV64-NEXT:    br label %[[__RISCV_PGET_U16X4_U16X2_EXIT]]
+// RV64:       [[__RISCV_PGET_U16X4_U16X2_EXIT]]:
+// RV64-NEXT:    [[TMP0:%.*]] = phi i32 [ poison, %[[COND_TRUE_I]] ], [ 
[[SHUFFLE2_I_EXTRACT]], %[[COND_FALSE_I]] ]
+// RV64-NEXT:    ret i32 [[TMP0]]
+//
+uint16x2_t test_pget_u16x4_u16x2(uint16x4_t v) {
+  return __riscv_pget_u16x4_u16x2(v, 0);
+}
+
+// RV32-LABEL: define dso_local i32 @test_pget_u16x4_u16x2_idx1(
+// RV32-SAME: i64 noundef [[V_COERCE:%.*]]) #[[ATTR0]] {
+// RV32-NEXT:  [[ENTRY:.*:]]
+// RV32-NEXT:    br i1 true, label %[[COND_TRUE_I:.*]], label 
%[[COND_FALSE_I:.*]]
+// RV32:       [[COND_TRUE_I]]:
+// RV32-NEXT:    [[SHUFFLE_I_BC:%.*]] = bitcast i64 [[V_COERCE]] to <2 x i32>
+// RV32-NEXT:    [[SHUFFLE_I_EXTRACT:%.*]] = extractelement <2 x i32> 
[[SHUFFLE_I_BC]], i64 1
+// RV32-NEXT:    br label %[[__RISCV_PGET_U16X4_U16X2_EXIT:.*]]
+// RV32:       [[COND_FALSE_I]]:
+// RV32-NEXT:    br label %[[__RISCV_PGET_U16X4_U16X2_EXIT]]
+// RV32:       [[__RISCV_PGET_U16X4_U16X2_EXIT]]:
+// RV32-NEXT:    [[TMP0:%.*]] = phi i32 [ [[SHUFFLE_I_EXTRACT]], 
%[[COND_TRUE_I]] ], [ poison, %[[COND_FALSE_I]] ]
+// RV32-NEXT:    ret i32 [[TMP0]]
+//
+// RV64-LABEL: define dso_local i32 @test_pget_u16x4_u16x2_idx1(
+// RV64-SAME: i64 noundef [[V_COERCE:%.*]]) #[[ATTR0]] {
+// RV64-NEXT:  [[ENTRY:.*:]]
+// RV64-NEXT:    br i1 true, label %[[COND_TRUE_I:.*]], label 
%[[COND_FALSE_I:.*]]
+// RV64:       [[COND_TRUE_I]]:
+// RV64-NEXT:    [[EXTELT_OFFSET:%.*]] = lshr i64 [[V_COERCE]], 32
+// RV64-NEXT:    [[SHUFFLE_I_EXTRACT:%.*]] = trunc nuw i64 [[EXTELT_OFFSET]] 
to i32
+// RV64-NEXT:    br label %[[__RISCV_PGET_U16X4_U16X2_EXIT:.*]]
+// RV64:       [[COND_FALSE_I]]:
+// RV64-NEXT:    br label %[[__RISCV_PGET_U16X4_U16X2_EXIT]]
+// RV64:       [[__RISCV_PGET_U16X4_U16X2_EXIT]]:
+// RV64-NEXT:    [[TMP0:%.*]] = phi i32 [ [[SHUFFLE_I_EXTRACT]], 
%[[COND_TRUE_I]] ], [ poison, %[[COND_FALSE_I]] ]
+// RV64-NEXT:    ret i32 [[TMP0]]
+//
+uint16x2_t test_pget_u16x4_u16x2_idx1(uint16x4_t v) {
+  return __riscv_pget_u16x4_u16x2(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 e68c9156311ba..14e64c3c3584b 100644
--- a/cross-project-tests/intrinsic-header-tests/riscv_packed_simd.c
+++ b/cross-project-tests/intrinsic-header-tests/riscv_packed_simd.c
@@ -4819,3 +4819,57 @@ int16x4_t test_pjoin2_i16x4(int16x2_t lo, int16x2_t hi) {
 uint16x4_t test_pjoin2_u16x4(uint16x2_t lo, uint16x2_t hi) {
   return __riscv_pjoin2_u16x4(lo, hi);
 }
+
+/* Packed Subvector Extract */
+
+// CHECK-LABEL: test_pget_i8x8_i8x4:
+// CHECK:         ret
+int8x4_t test_pget_i8x8_i8x4(int8x8_t v) {
+  return __riscv_pget_i8x8_i8x4(v, 0);
+}
+
+// CHECK-LABEL: test_pget_i8x8_i8x4_idx1:
+// RV32:         mv{{[[:space:]]}}
+// RV64:         srli{{[[:space:]]}}
+int8x4_t test_pget_i8x8_i8x4_idx1(int8x8_t v) {
+  return __riscv_pget_i8x8_i8x4(v, 1);
+}
+
+// CHECK-LABEL: test_pget_u8x8_u8x4:
+// CHECK:         ret
+uint8x4_t test_pget_u8x8_u8x4(uint8x8_t v) {
+  return __riscv_pget_u8x8_u8x4(v, 0);
+}
+
+// CHECK-LABEL: test_pget_u8x8_u8x4_idx1:
+// RV32:         mv{{[[:space:]]}}
+// RV64:         srli{{[[:space:]]}}
+uint8x4_t test_pget_u8x8_u8x4_idx1(uint8x8_t v) {
+  return __riscv_pget_u8x8_u8x4(v, 1);
+}
+
+// CHECK-LABEL: test_pget_i16x4_i16x2:
+// CHECK:         ret
+int16x2_t test_pget_i16x4_i16x2(int16x4_t v) {
+  return __riscv_pget_i16x4_i16x2(v, 0);
+}
+
+// CHECK-LABEL: test_pget_i16x4_i16x2_idx1:
+// RV32:         mv{{[[:space:]]}}
+// RV64:         srli{{[[:space:]]}}
+int16x2_t test_pget_i16x4_i16x2_idx1(int16x4_t v) {
+  return __riscv_pget_i16x4_i16x2(v, 1);
+}
+
+// CHECK-LABEL: test_pget_u16x4_u16x2:
+// CHECK:         ret
+uint16x2_t test_pget_u16x4_u16x2(uint16x4_t v) {
+  return __riscv_pget_u16x4_u16x2(v, 0);
+}
+
+// CHECK-LABEL: test_pget_u16x4_u16x2_idx1:
+// RV32:         mv{{[[:space:]]}}
+// RV64:         srli{{[[:space:]]}}
+uint16x2_t test_pget_u16x4_u16x2_idx1(uint16x4_t v) {
+  return __riscv_pget_u16x4_u16x2(v, 1);
+}


        
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to