llvmorg-github-actions[bot] wrote:

<!--LLVM PR SUMMARY COMMENT-->

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

Author: SiHuaN (sihuan)

<details>
<summary>Changes</summary>

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.


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


3 Files Affected:

- (modified) clang/lib/Headers/riscv_packed_simd.h (+25) 
- (modified) clang/test/CodeGen/RISCV/rvp-intrinsics.c (+250) 
- (modified) cross-project-tests/intrinsic-header-tests/riscv_packed_simd.c 
(+54) 


``````````diff
diff --git a/clang/lib/Headers/riscv_packed_simd.h 
b/clang/lib/Headers/riscv_packed_simd.h
index 8c20d00e68652..7571cbe284f6b 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) {           
\
@@ -1114,6 +1131,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)
@@ -1309,6 +1332,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 b2b2b1b9a777b..edf15f7b5a408 100644
--- a/clang/test/CodeGen/RISCV/rvp-intrinsics.c
+++ b/clang/test/CodeGen/RISCV/rvp-intrinsics.c
@@ -11864,3 +11864,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 f3857cedc3b5a..70b6124eb48fd 100644
--- a/cross-project-tests/intrinsic-header-tests/riscv_packed_simd.c
+++ b/cross-project-tests/intrinsic-header-tests/riscv_packed_simd.c
@@ -4771,3 +4771,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);
+}

``````````

</details>


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

Reply via email to