llvmorg-github-actions[bot] wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-x86

Author: Hongyu Chen (XChy)

<details>
<summary>Changes</summary>

See also 
https://github.com/riscv/riscv-p-spec/blob/master/P-ext-intrinsics.adoc#packed-store.

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


4 Files Affected:

- (modified) clang/lib/Headers/riscv_packed_simd.h (+22) 
- (modified) clang/test/CodeGen/RISCV/rvp-intrinsics.c (+183) 
- (added) clang/test/Sema/riscv-pst-pointer-types.c (+41) 
- (modified) cross-project-tests/intrinsic-header-tests/riscv_packed_simd.c 
(+66) 


``````````diff
diff --git a/clang/lib/Headers/riscv_packed_simd.h 
b/clang/lib/Headers/riscv_packed_simd.h
index e04c51b3208f92..dc057d8ef26086 100644
--- a/clang/lib/Headers/riscv_packed_simd.h
+++ b/clang/lib/Headers/riscv_packed_simd.h
@@ -75,6 +75,13 @@ typedef uint32_t uint32x2_t 
__attribute__((__vector_size__(8)));
     return __v[__idx];                                                         
\
   }
 
+#define __packed_store(name, ty, elt_ty)                                       
\
+  static __inline__ void __DEFAULT_FN_ATTRS __riscv_##name(elt_ty *__p,        
\
+                                                           ty __v) {           
\
+    typedef ty __attribute__((__aligned__(1))) ua_ty;                          
\
+    *(ua_ty *)__p = __v;                                                       
\
+  }
+
 #define __packed_binary_builtin(name, ty, builtin)                             
\
   static __inline__ ty __DEFAULT_FN_ATTRS __riscv_##name(ty __rs1, ty __rs2) { 
\
     return builtin(__rs1, __rs2);                                              
\
@@ -1038,6 +1045,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 Store (32-bit) */
+__packed_store(pst_i8x4, int8x4_t, int8_t)
+__packed_store(pst_u8x4, uint8x4_t, uint8_t)
+__packed_store(pst_i16x2, int16x2_t, int16_t)
+__packed_store(pst_u16x2, uint16x2_t, uint16_t)
+
+/* Packed Store (64-bit) */
+__packed_store(pst_i8x8, int8x8_t, int8_t)
+__packed_store(pst_u8x8, uint8x8_t, uint8_t)
+__packed_store(pst_i16x4, int16x4_t, int16_t)
+__packed_store(pst_u16x4, uint16x4_t, uint16_t)
+__packed_store(pst_i32x2, int32x2_t, int32_t)
+__packed_store(pst_u32x2, uint32x2_t, uint32_t)
+
 /* 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)
@@ -1155,6 +1176,7 @@ __packed_reinterpret(u32x2_i32x2, int32x2_t, uint32x2_t)
 #undef __packed_scalar_binary_op
 #undef __packed_binary_op
 #undef __packed_unary_op
+#undef __packed_store
 #undef __packed_binary_builtin
 #undef __packed_binary_builtin_mixed
 #undef __packed_ternary_builtin
diff --git a/clang/test/CodeGen/RISCV/rvp-intrinsics.c 
b/clang/test/CodeGen/RISCV/rvp-intrinsics.c
index 954e8eb77e41ea..41d23d2d6bcffb 100644
--- a/clang/test/CodeGen/RISCV/rvp-intrinsics.c
+++ b/clang/test/CodeGen/RISCV/rvp-intrinsics.c
@@ -11005,3 +11005,186 @@ int32_t test_pget_i32x2_i32(int32x2_t v) {
 uint32_t test_pget_u32x2_u32(uint32x2_t v) {
   return __riscv_pget_u32x2_u32(v, 1);
 }
+
+/* Packed Store (32-bit) */
+
+// RV32-LABEL: define dso_local void @test_pst_i8x4(
+// RV32-SAME: ptr noundef [[P:%.*]], i32 noundef [[V_COERCE:%.*]]) #[[ATTR0]] {
+// RV32-NEXT:  [[ENTRY:.*:]]
+// RV32-NEXT:    store i32 [[V_COERCE]], ptr [[P]], align 1
+// RV32-NEXT:    ret void
+//
+// RV64-LABEL: define dso_local void @test_pst_i8x4(
+// RV64-SAME: ptr noundef [[P:%.*]], i32 noundef [[V_COERCE:%.*]]) #[[ATTR0]] {
+// RV64-NEXT:  [[ENTRY:.*:]]
+// RV64-NEXT:    store i32 [[V_COERCE]], ptr [[P]], align 1
+// RV64-NEXT:    ret void
+//
+void test_pst_i8x4(int8_t *p, int8x4_t v) { __riscv_pst_i8x4(p, v); }
+
+// RV32-LABEL: define dso_local void @test_pst_u8x4(
+// RV32-SAME: ptr noundef [[P:%.*]], i32 noundef [[V_COERCE:%.*]]) #[[ATTR0]] {
+// RV32-NEXT:  [[ENTRY:.*:]]
+// RV32-NEXT:    store i32 [[V_COERCE]], ptr [[P]], align 1
+// RV32-NEXT:    ret void
+//
+// RV64-LABEL: define dso_local void @test_pst_u8x4(
+// RV64-SAME: ptr noundef [[P:%.*]], i32 noundef [[V_COERCE:%.*]]) #[[ATTR0]] {
+// RV64-NEXT:  [[ENTRY:.*:]]
+// RV64-NEXT:    store i32 [[V_COERCE]], ptr [[P]], align 1
+// RV64-NEXT:    ret void
+//
+void test_pst_u8x4(uint8_t *p, uint8x4_t v) { __riscv_pst_u8x4(p, v); }
+
+// RV32-LABEL: define dso_local void @test_pst_i16x2(
+// RV32-SAME: ptr noundef [[P:%.*]], i32 noundef [[V_COERCE:%.*]]) #[[ATTR0]] {
+// RV32-NEXT:  [[ENTRY:.*:]]
+// RV32-NEXT:    store i32 [[V_COERCE]], ptr [[P]], align 1
+// RV32-NEXT:    ret void
+//
+// RV64-LABEL: define dso_local void @test_pst_i16x2(
+// RV64-SAME: ptr noundef [[P:%.*]], i32 noundef [[V_COERCE:%.*]]) #[[ATTR0]] {
+// RV64-NEXT:  [[ENTRY:.*:]]
+// RV64-NEXT:    store i32 [[V_COERCE]], ptr [[P]], align 1
+// RV64-NEXT:    ret void
+//
+void test_pst_i16x2(int16_t *p, int16x2_t v) { __riscv_pst_i16x2(p, v); }
+
+// RV32-LABEL: define dso_local void @test_pst_u16x2(
+// RV32-SAME: ptr noundef [[P:%.*]], i32 noundef [[V_COERCE:%.*]]) #[[ATTR0]] {
+// RV32-NEXT:  [[ENTRY:.*:]]
+// RV32-NEXT:    store i32 [[V_COERCE]], ptr [[P]], align 1
+// RV32-NEXT:    ret void
+//
+// RV64-LABEL: define dso_local void @test_pst_u16x2(
+// RV64-SAME: ptr noundef [[P:%.*]], i32 noundef [[V_COERCE:%.*]]) #[[ATTR0]] {
+// RV64-NEXT:  [[ENTRY:.*:]]
+// RV64-NEXT:    store i32 [[V_COERCE]], ptr [[P]], align 1
+// RV64-NEXT:    ret void
+//
+void test_pst_u16x2(uint16_t *p, uint16x2_t v) { __riscv_pst_u16x2(p, v); }
+
+/* Packed Store (64-bit) */
+
+// RV32-LABEL: define dso_local void @test_pst_i8x8(
+// RV32-SAME: ptr noundef [[P:%.*]], i64 noundef [[V_COERCE:%.*]]) #[[ATTR0]] {
+// RV32-NEXT:  [[ENTRY:.*:]]
+// RV32-NEXT:    store i64 [[V_COERCE]], ptr [[P]], align 1
+// RV32-NEXT:    ret void
+//
+// RV64-LABEL: define dso_local void @test_pst_i8x8(
+// RV64-SAME: ptr noundef [[P:%.*]], i64 noundef [[V_COERCE:%.*]]) #[[ATTR0]] {
+// RV64-NEXT:  [[ENTRY:.*:]]
+// RV64-NEXT:    store i64 [[V_COERCE]], ptr [[P]], align 1
+// RV64-NEXT:    ret void
+//
+void test_pst_i8x8(int8_t *p, int8x8_t v) { __riscv_pst_i8x8(p, v); }
+
+// RV32-LABEL: define dso_local void @test_pst_u8x8(
+// RV32-SAME: ptr noundef [[P:%.*]], i64 noundef [[V_COERCE:%.*]]) #[[ATTR0]] {
+// RV32-NEXT:  [[ENTRY:.*:]]
+// RV32-NEXT:    store i64 [[V_COERCE]], ptr [[P]], align 1
+// RV32-NEXT:    ret void
+//
+// RV64-LABEL: define dso_local void @test_pst_u8x8(
+// RV64-SAME: ptr noundef [[P:%.*]], i64 noundef [[V_COERCE:%.*]]) #[[ATTR0]] {
+// RV64-NEXT:  [[ENTRY:.*:]]
+// RV64-NEXT:    store i64 [[V_COERCE]], ptr [[P]], align 1
+// RV64-NEXT:    ret void
+//
+void test_pst_u8x8(uint8_t *p, uint8x8_t v) { __riscv_pst_u8x8(p, v); }
+
+// RV32-LABEL: define dso_local void @test_pst_i16x4(
+// RV32-SAME: ptr noundef [[P:%.*]], i64 noundef [[V_COERCE:%.*]]) #[[ATTR0]] {
+// RV32-NEXT:  [[ENTRY:.*:]]
+// RV32-NEXT:    store i64 [[V_COERCE]], ptr [[P]], align 1
+// RV32-NEXT:    ret void
+//
+// RV64-LABEL: define dso_local void @test_pst_i16x4(
+// RV64-SAME: ptr noundef [[P:%.*]], i64 noundef [[V_COERCE:%.*]]) #[[ATTR0]] {
+// RV64-NEXT:  [[ENTRY:.*:]]
+// RV64-NEXT:    store i64 [[V_COERCE]], ptr [[P]], align 1
+// RV64-NEXT:    ret void
+//
+void test_pst_i16x4(int16_t *p, int16x4_t v) { __riscv_pst_i16x4(p, v); }
+
+// RV32-LABEL: define dso_local void @test_pst_u16x4(
+// RV32-SAME: ptr noundef [[P:%.*]], i64 noundef [[V_COERCE:%.*]]) #[[ATTR0]] {
+// RV32-NEXT:  [[ENTRY:.*:]]
+// RV32-NEXT:    store i64 [[V_COERCE]], ptr [[P]], align 1
+// RV32-NEXT:    ret void
+//
+// RV64-LABEL: define dso_local void @test_pst_u16x4(
+// RV64-SAME: ptr noundef [[P:%.*]], i64 noundef [[V_COERCE:%.*]]) #[[ATTR0]] {
+// RV64-NEXT:  [[ENTRY:.*:]]
+// RV64-NEXT:    store i64 [[V_COERCE]], ptr [[P]], align 1
+// RV64-NEXT:    ret void
+//
+void test_pst_u16x4(uint16_t *p, uint16x4_t v) { __riscv_pst_u16x4(p, v); }
+
+// RV32-LABEL: define dso_local void @test_pst_i32x2(
+// RV32-SAME: ptr noundef [[P:%.*]], i64 noundef [[V_COERCE:%.*]]) #[[ATTR0]] {
+// RV32-NEXT:  [[ENTRY:.*:]]
+// RV32-NEXT:    store i64 [[V_COERCE]], ptr [[P]], align 1
+// RV32-NEXT:    ret void
+//
+// RV64-LABEL: define dso_local void @test_pst_i32x2(
+// RV64-SAME: ptr noundef [[P:%.*]], i64 noundef [[V_COERCE:%.*]]) #[[ATTR0]] {
+// RV64-NEXT:  [[ENTRY:.*:]]
+// RV64-NEXT:    store i64 [[V_COERCE]], ptr [[P]], align 1
+// RV64-NEXT:    ret void
+//
+void test_pst_i32x2(int32_t *p, int32x2_t v) { __riscv_pst_i32x2(p, v); }
+
+// RV32-LABEL: define dso_local void @test_pst_u32x2(
+// RV32-SAME: ptr noundef [[P:%.*]], i64 noundef [[V_COERCE:%.*]]) #[[ATTR0]] {
+// RV32-NEXT:  [[ENTRY:.*:]]
+// RV32-NEXT:    store i64 [[V_COERCE]], ptr [[P]], align 1
+// RV32-NEXT:    ret void
+//
+// RV64-LABEL: define dso_local void @test_pst_u32x2(
+// RV64-SAME: ptr noundef [[P:%.*]], i64 noundef [[V_COERCE:%.*]]) #[[ATTR0]] {
+// RV64-NEXT:  [[ENTRY:.*:]]
+// RV64-NEXT:    store i64 [[V_COERCE]], ptr [[P]], align 1
+// RV64-NEXT:    ret void
+//
+void test_pst_u32x2(uint32_t *p, uint32x2_t v) { __riscv_pst_u32x2(p, v); }
+
+/* Packed Store with provable alignment (cf. the P-ext spec's note on
+ * __builtin_assume_aligned) */
+
+// RV32-LABEL: define dso_local void @test_pst_i8x4_aligned(
+// RV32-SAME: ptr noundef [[P:%.*]], i32 noundef [[V_COERCE:%.*]]) #[[ATTR0]] {
+// RV32-NEXT:  [[ENTRY:.*:]]
+// RV32-NEXT:    call void @llvm.assume(i1 true) [ "align"(ptr [[P]], i32 4) ]
+// RV32-NEXT:    store i32 [[V_COERCE]], ptr [[P]], align 1
+// RV32-NEXT:    ret void
+//
+// RV64-LABEL: define dso_local void @test_pst_i8x4_aligned(
+// RV64-SAME: ptr noundef [[P:%.*]], i32 noundef [[V_COERCE:%.*]]) #[[ATTR0]] {
+// RV64-NEXT:  [[ENTRY:.*:]]
+// RV64-NEXT:    call void @llvm.assume(i1 true) [ "align"(ptr [[P]], i64 4) ]
+// RV64-NEXT:    store i32 [[V_COERCE]], ptr [[P]], align 1
+// RV64-NEXT:    ret void
+//
+void test_pst_i8x4_aligned(int8_t *p, int8x4_t v) {
+  __riscv_pst_i8x4(__builtin_assume_aligned(p, 4), v);
+}
+
+// RV32-LABEL: define dso_local void @test_pst_i32x2_aligned(
+// RV32-SAME: ptr noundef [[P:%.*]], i64 noundef [[V_COERCE:%.*]]) #[[ATTR0]] {
+// RV32-NEXT:  [[ENTRY:.*:]]
+// RV32-NEXT:    call void @llvm.assume(i1 true) [ "align"(ptr [[P]], i32 8) ]
+// RV32-NEXT:    store i64 [[V_COERCE]], ptr [[P]], align 1
+// RV32-NEXT:    ret void
+//
+// RV64-LABEL: define dso_local void @test_pst_i32x2_aligned(
+// RV64-SAME: ptr noundef [[P:%.*]], i64 noundef [[V_COERCE:%.*]]) #[[ATTR0]] {
+// RV64-NEXT:  [[ENTRY:.*:]]
+// RV64-NEXT:    call void @llvm.assume(i1 true) [ "align"(ptr [[P]], i64 8) ]
+// RV64-NEXT:    store i64 [[V_COERCE]], ptr [[P]], align 1
+// RV64-NEXT:    ret void
+//
+void test_pst_i32x2_aligned(int32_t *p, int32x2_t v) {
+  __riscv_pst_i32x2(__builtin_assume_aligned(p, 8), v);
+}
diff --git a/clang/test/Sema/riscv-pst-pointer-types.c 
b/clang/test/Sema/riscv-pst-pointer-types.c
new file mode 100644
index 00000000000000..48e82b57101887
--- /dev/null
+++ b/clang/test/Sema/riscv-pst-pointer-types.c
@@ -0,0 +1,41 @@
+// 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>
+
+// The __riscv_pst_* intrinsics take a pointer to the element type; passing a
+// pointer to an unrelated type is ill-formed.
+
+void test_pst_i8x4_ok(int8_t *p, int8x4_t v) { __riscv_pst_i8x4(p, v); }
+
+void test_pst_i8x4_void_ptr(void *p, int8x4_t v) {
+  __riscv_pst_i8x4(p, v);
+}
+
+void test_pst_i8x4_array(int8x4_t v) {
+  int8_t a[4];
+  __riscv_pst_i8x4(a, v);
+}
+
+void test_pst_i8x4_wrong_pointer_type(float *p, int8x4_t v) {
+  // expected-error@+1 {{incompatible pointer types passing 'float *' to 
parameter of type 'int8_t *' (aka 'signed char *')}}
+  __riscv_pst_i8x4(p, v);
+}
+
+void test_pst_u16x2_wrong_pointer_type(uint32_t *p, uint16x2_t v) {
+  // expected-error@+1 {{incompatible pointer types passing 'uint32_t *' (aka 
'unsigned int *') to parameter of type 'uint16_t *' (aka 'unsigned short *')}}
+  __riscv_pst_u16x2(p, v);
+}
+
+void test_pst_i32x2_wrong_pointer_type(int8x4_t *p, int32x2_t v) {
+  // expected-error@+1 {{incompatible pointer types passing 'int8x4_t *' to 
parameter of type 'int32_t *' (aka 'int *')}}
+  __riscv_pst_i32x2(p, v);
+}
+
+void test_pst_i16x4_const_discards_qualifiers(const int16_t *p,
+                                              int16x4_t v) {
+  // expected-warning@+1 {{passing 'const int16_t *' (aka 'const short *') to 
parameter of type 'int16_t *' (aka 'short *') discards qualifiers}}
+  __riscv_pst_i16x4(p, v);
+}
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 f222e66ff1dd5a..7fc08120e93ad5 100644
--- a/cross-project-tests/intrinsic-header-tests/riscv_packed_simd.c
+++ b/cross-project-tests/intrinsic-header-tests/riscv_packed_simd.c
@@ -4459,3 +4459,69 @@ int64_t test_maccsu_w00_i64(int64_t rd, int32x2_t a, 
uint32x2_t b) {
 int64_t test_maccsu_w11_i64(int64_t rd, int32x2_t a, uint32x2_t b) {
   return __riscv_maccsu_w11_i64(rd, a, b);
 }
+
+// CHECK-LABEL: test_pst_i8x4:
+// CHECK-COUNT-4: sb{{[[:space:]]}}
+void test_pst_i8x4(int8_t *p, int8x4_t v) { __riscv_pst_i8x4(p, v); }
+
+// CHECK-LABEL: test_pst_u8x4:
+// CHECK-COUNT-4: sb{{[[:space:]]}}
+void test_pst_u8x4(uint8_t *p, uint8x4_t v) { __riscv_pst_u8x4(p, v); }
+
+// CHECK-LABEL: test_pst_i16x2:
+// CHECK-COUNT-4: sb{{[[:space:]]}}
+void test_pst_i16x2(int16_t *p, int16x2_t v) { __riscv_pst_i16x2(p, v); }
+
+// CHECK-LABEL: test_pst_u16x2:
+// CHECK-COUNT-4: sb{{[[:space:]]}}
+void test_pst_u16x2(uint16_t *p, uint16x2_t v) { __riscv_pst_u16x2(p, v); }
+
+// CHECK-LABEL: test_pst_i8x8:
+// CHECK-COUNT-8: sb{{[[:space:]]}}
+void test_pst_i8x8(int8_t *p, int8x8_t v) { __riscv_pst_i8x8(p, v); }
+
+// CHECK-LABEL: test_pst_u8x8:
+// CHECK-COUNT-8: sb{{[[:space:]]}}
+void test_pst_u8x8(uint8_t *p, uint8x8_t v) { __riscv_pst_u8x8(p, v); }
+
+// CHECK-LABEL: test_pst_i16x4:
+// CHECK-COUNT-8: sb{{[[:space:]]}}
+void test_pst_i16x4(int16_t *p, int16x4_t v) { __riscv_pst_i16x4(p, v); }
+
+// CHECK-LABEL: test_pst_u16x4:
+// CHECK-COUNT-8: sb{{[[:space:]]}}
+void test_pst_u16x4(uint16_t *p, uint16x4_t v) { __riscv_pst_u16x4(p, v); }
+
+// CHECK-LABEL: test_pst_i32x2:
+// CHECK-COUNT-8: sb{{[[:space:]]}}
+void test_pst_i32x2(int32_t *p, int32x2_t v) { __riscv_pst_i32x2(p, v); }
+
+// CHECK-LABEL: test_pst_u32x2:
+// CHECK-COUNT-8: sb{{[[:space:]]}}
+void test_pst_u32x2(uint32_t *p, uint32x2_t v) { __riscv_pst_u32x2(p, v); }
+
+// CHECK-LABEL: test_pst_i8x4_aligned:
+// CHECK:         sw
+void test_pst_i8x4_aligned(int8_t *p, int8x4_t v) {
+  __riscv_pst_i8x4(__builtin_assume_aligned(p, 4), v);
+}
+
+// CHECK-LABEL: test_pst_u16x2_aligned:
+// CHECK:         sw
+void test_pst_u16x2_aligned(uint16_t *p, uint16x2_t v) {
+  __riscv_pst_u16x2(__builtin_assume_aligned(p, 4), v);
+}
+
+// CHECK-LABEL: test_pst_i8x8_aligned:
+// RV32-COUNT-2: sw
+// RV64:         sd
+void test_pst_i8x8_aligned(int8_t *p, int8x8_t v) {
+  __riscv_pst_i8x8(__builtin_assume_aligned(p, 8), v);
+}
+
+// CHECK-LABEL: test_pst_u32x2_aligned:
+// RV32-COUNT-2: sw
+// RV64:         sd
+void test_pst_u32x2_aligned(uint32_t *p, uint32x2_t v) {
+  __riscv_pst_u32x2(__builtin_assume_aligned(p, 8), v);
+}

``````````

</details>


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

Reply via email to