https://github.com/TelGome updated 
https://github.com/llvm/llvm-project/pull/223313

>From 2413df269058660a5573217b52183ff12ddd0a87 Mon Sep 17 00:00:00 2001
From: Dongyan Chen <[email protected]>
Date: Sun, 13 Sep 2026 17:26:28 +0800
Subject: [PATCH 1/3] [RISCV][P-ext] Support Packed Load

---
 clang/lib/Headers/riscv_packed_simd.h         |  43 ++++
 clang/test/CodeGen/RISCV/rvp-intrinsics.c     | 200 ++++++++++++++++++
 clang/test/Sema/riscv-pld-pointer-types.c     |  42 ++++
 .../riscv_packed_simd.c                       |  80 +++++++
 4 files changed, 365 insertions(+)
 create mode 100644 clang/test/Sema/riscv-pld-pointer-types.c

diff --git a/clang/lib/Headers/riscv_packed_simd.h 
b/clang/lib/Headers/riscv_packed_simd.h
index 51ab085559c52..0dabc92667a50 100644
--- a/clang/lib/Headers/riscv_packed_simd.h
+++ b/clang/lib/Headers/riscv_packed_simd.h
@@ -30,6 +30,29 @@ typedef uint16_t uint16x4_t 
__attribute__((__vector_size__(8)));
 typedef int32_t int32x2_t __attribute__((__vector_size__(8)));
 typedef uint32_t uint32x2_t __attribute__((__vector_size__(8)));
 
+/* Unaligned views of the packed types, used by the load/store intrinsics to
+ * express that the pointer may have arbitrary alignment. */
+typedef int8_t __packed_i8x4_unaligned
+    __attribute__((__vector_size__(4), __aligned__(1)));
+typedef uint8_t __packed_u8x4_unaligned
+    __attribute__((__vector_size__(4), __aligned__(1)));
+typedef int16_t __packed_i16x2_unaligned
+    __attribute__((__vector_size__(4), __aligned__(1)));
+typedef uint16_t __packed_u16x2_unaligned
+    __attribute__((__vector_size__(4), __aligned__(1)));
+typedef int8_t __packed_i8x8_unaligned
+    __attribute__((__vector_size__(8), __aligned__(1)));
+typedef uint8_t __packed_u8x8_unaligned
+    __attribute__((__vector_size__(8), __aligned__(1)));
+typedef int16_t __packed_i16x4_unaligned
+    __attribute__((__vector_size__(8), __aligned__(1)));
+typedef uint16_t __packed_u16x4_unaligned
+    __attribute__((__vector_size__(8), __aligned__(1)));
+typedef int32_t __packed_i32x2_unaligned
+    __attribute__((__vector_size__(8), __aligned__(1)));
+typedef uint32_t __packed_u32x2_unaligned
+    __attribute__((__vector_size__(8), __aligned__(1)));
+
 #define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__))
 
 #define __packed_splat2(ty, x) ((ty){(x), (x)})
@@ -328,6 +351,11 @@ typedef uint32_t uint32x2_t 
__attribute__((__vector_size__(8)));
     return __v;                                                                
\
   }
 
+#define __packed_load(name, ty, elt_ty, ua_ty)                                 
\
+  static __inline__ ty __DEFAULT_FN_ATTRS __riscv_##name(elt_ty *__p) {        
\
+    return *(ua_ty *)__p;                                                      
\
+  }
+
 // clang-format off: macro call sites have no trailing semicolons, which
 // confuses clang-format into a deeply nested expression.
 
@@ -1076,6 +1104,20 @@ __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)
 
+/* Packed Load (32-bit) */
+__packed_load(pld_i8x4, int8x4_t, int8_t, __packed_i8x4_unaligned)
+__packed_load(pld_u8x4, uint8x4_t, uint8_t, __packed_u8x4_unaligned)
+__packed_load(pld_i16x2, int16x2_t, int16_t, __packed_i16x2_unaligned)
+__packed_load(pld_u16x2, uint16x2_t, uint16_t, __packed_u16x2_unaligned)
+
+/* Packed Load (64-bit) */
+__packed_load(pld_i8x8, int8x8_t, int8_t, __packed_i8x8_unaligned)
+__packed_load(pld_u8x8, uint8x8_t, uint8_t, __packed_u8x8_unaligned)
+__packed_load(pld_i16x4, int16x4_t, int16_t, __packed_i16x4_unaligned)
+__packed_load(pld_u16x4, uint16x4_t, uint16_t, __packed_u16x4_unaligned)
+__packed_load(pld_i32x2, int32x2_t, int32_t, __packed_i32x2_unaligned)
+__packed_load(pld_u32x2, uint32x2_t, uint32_t, __packed_u32x2_unaligned)
+
 /* Reinterpret Casts, Packed <-> Scalar (32-bit) */
 __packed_reinterpret(u8x4_u32, uint32_t, uint8x4_t)
 __packed_reinterpret(u16x2_u32, uint32_t, uint16x2_t)
@@ -1227,6 +1269,7 @@ __packed_reinterpret(u32x2_i32x2, int32x2_t, uint32x2_t)
 #undef __packed_ternary_builtin_cast
 #undef __packed_extract
 #undef __packed_insert
+#undef __packed_load
 #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 fde2d41d107f2..714368ddf3a35 100644
--- a/clang/test/CodeGen/RISCV/rvp-intrinsics.c
+++ b/clang/test/CodeGen/RISCV/rvp-intrinsics.c
@@ -11209,3 +11209,203 @@ int32x2_t test_pset_i32_i32x2(int32x2_t v, int32_t e) 
{
 uint32x2_t test_pset_u32_u32x2(uint32x2_t v, uint32_t e) {
   return __riscv_pset_u32_u32x2(v, e, 0);
 }
+
+/* Packed Load (32-bit) */
+// RV32-LABEL: define dso_local i32 @test_pld_i8x4(
+// RV32-SAME: ptr noundef [[P:%.*]]) #[[ATTR0]] {
+// RV32-NEXT:  [[ENTRY:.*:]]
+// RV32-NEXT:    [[TMP0:%.*]] = load i32, ptr [[P]], align 1
+// RV32-NEXT:    ret i32 [[TMP0]]
+//
+// RV64-LABEL: define dso_local i32 @test_pld_i8x4(
+// RV64-SAME: ptr noundef [[P:%.*]]) #[[ATTR0]] {
+// RV64-NEXT:  [[ENTRY:.*:]]
+// RV64-NEXT:    [[TMP0:%.*]] = load i32, ptr [[P]], align 1
+// RV64-NEXT:    ret i32 [[TMP0]]
+//
+int8x4_t test_pld_i8x4(int8_t *p) {
+  return __riscv_pld_i8x4(p);
+}
+
+// RV32-LABEL: define dso_local i32 @test_pld_u8x4(
+// RV32-SAME: ptr noundef [[P:%.*]]) #[[ATTR0]] {
+// RV32-NEXT:  [[ENTRY:.*:]]
+// RV32-NEXT:    [[TMP0:%.*]] = load i32, ptr [[P]], align 1
+// RV32-NEXT:    ret i32 [[TMP0]]
+//
+// RV64-LABEL: define dso_local i32 @test_pld_u8x4(
+// RV64-SAME: ptr noundef [[P:%.*]]) #[[ATTR0]] {
+// RV64-NEXT:  [[ENTRY:.*:]]
+// RV64-NEXT:    [[TMP0:%.*]] = load i32, ptr [[P]], align 1
+// RV64-NEXT:    ret i32 [[TMP0]]
+//
+uint8x4_t test_pld_u8x4(uint8_t *p) {
+  return __riscv_pld_u8x4(p);
+}
+
+// RV32-LABEL: define dso_local i32 @test_pld_i16x2(
+// RV32-SAME: ptr noundef [[P:%.*]]) #[[ATTR0]] {
+// RV32-NEXT:  [[ENTRY:.*:]]
+// RV32-NEXT:    [[TMP0:%.*]] = load i32, ptr [[P]], align 1
+// RV32-NEXT:    ret i32 [[TMP0]]
+//
+// RV64-LABEL: define dso_local i32 @test_pld_i16x2(
+// RV64-SAME: ptr noundef [[P:%.*]]) #[[ATTR0]] {
+// RV64-NEXT:  [[ENTRY:.*:]]
+// RV64-NEXT:    [[TMP0:%.*]] = load i32, ptr [[P]], align 1
+// RV64-NEXT:    ret i32 [[TMP0]]
+//
+int16x2_t test_pld_i16x2(int16_t *p) {
+  return __riscv_pld_i16x2(p);
+}
+
+// RV32-LABEL: define dso_local i32 @test_pld_u16x2(
+// RV32-SAME: ptr noundef [[P:%.*]]) #[[ATTR0]] {
+// RV32-NEXT:  [[ENTRY:.*:]]
+// RV32-NEXT:    [[TMP0:%.*]] = load i32, ptr [[P]], align 1
+// RV32-NEXT:    ret i32 [[TMP0]]
+//
+// RV64-LABEL: define dso_local i32 @test_pld_u16x2(
+// RV64-SAME: ptr noundef [[P:%.*]]) #[[ATTR0]] {
+// RV64-NEXT:  [[ENTRY:.*:]]
+// RV64-NEXT:    [[TMP0:%.*]] = load i32, ptr [[P]], align 1
+// RV64-NEXT:    ret i32 [[TMP0]]
+//
+uint16x2_t test_pld_u16x2(uint16_t *p) {
+  return __riscv_pld_u16x2(p);
+}
+
+/* Packed Load (64-bit) */
+// RV32-LABEL: define dso_local i64 @test_pld_i8x8(
+// RV32-SAME: ptr noundef [[P:%.*]]) #[[ATTR0]] {
+// RV32-NEXT:  [[ENTRY:.*:]]
+// RV32-NEXT:    [[TMP0:%.*]] = load i64, ptr [[P]], align 1
+// RV32-NEXT:    ret i64 [[TMP0]]
+//
+// RV64-LABEL: define dso_local i64 @test_pld_i8x8(
+// RV64-SAME: ptr noundef [[P:%.*]]) #[[ATTR0]] {
+// RV64-NEXT:  [[ENTRY:.*:]]
+// RV64-NEXT:    [[TMP0:%.*]] = load i64, ptr [[P]], align 1
+// RV64-NEXT:    ret i64 [[TMP0]]
+//
+int8x8_t test_pld_i8x8(int8_t *p) {
+  return __riscv_pld_i8x8(p);
+}
+
+// RV32-LABEL: define dso_local i64 @test_pld_u8x8(
+// RV32-SAME: ptr noundef [[P:%.*]]) #[[ATTR0]] {
+// RV32-NEXT:  [[ENTRY:.*:]]
+// RV32-NEXT:    [[TMP0:%.*]] = load i64, ptr [[P]], align 1
+// RV32-NEXT:    ret i64 [[TMP0]]
+//
+// RV64-LABEL: define dso_local i64 @test_pld_u8x8(
+// RV64-SAME: ptr noundef [[P:%.*]]) #[[ATTR0]] {
+// RV64-NEXT:  [[ENTRY:.*:]]
+// RV64-NEXT:    [[TMP0:%.*]] = load i64, ptr [[P]], align 1
+// RV64-NEXT:    ret i64 [[TMP0]]
+//
+uint8x8_t test_pld_u8x8(uint8_t *p) {
+  return __riscv_pld_u8x8(p);
+}
+
+// RV32-LABEL: define dso_local i64 @test_pld_i16x4(
+// RV32-SAME: ptr noundef [[P:%.*]]) #[[ATTR0]] {
+// RV32-NEXT:  [[ENTRY:.*:]]
+// RV32-NEXT:    [[TMP0:%.*]] = load i64, ptr [[P]], align 1
+// RV32-NEXT:    ret i64 [[TMP0]]
+//
+// RV64-LABEL: define dso_local i64 @test_pld_i16x4(
+// RV64-SAME: ptr noundef [[P:%.*]]) #[[ATTR0]] {
+// RV64-NEXT:  [[ENTRY:.*:]]
+// RV64-NEXT:    [[TMP0:%.*]] = load i64, ptr [[P]], align 1
+// RV64-NEXT:    ret i64 [[TMP0]]
+//
+int16x4_t test_pld_i16x4(int16_t *p) {
+  return __riscv_pld_i16x4(p);
+}
+
+// RV32-LABEL: define dso_local i64 @test_pld_u16x4(
+// RV32-SAME: ptr noundef [[P:%.*]]) #[[ATTR0]] {
+// RV32-NEXT:  [[ENTRY:.*:]]
+// RV32-NEXT:    [[TMP0:%.*]] = load i64, ptr [[P]], align 1
+// RV32-NEXT:    ret i64 [[TMP0]]
+//
+// RV64-LABEL: define dso_local i64 @test_pld_u16x4(
+// RV64-SAME: ptr noundef [[P:%.*]]) #[[ATTR0]] {
+// RV64-NEXT:  [[ENTRY:.*:]]
+// RV64-NEXT:    [[TMP0:%.*]] = load i64, ptr [[P]], align 1
+// RV64-NEXT:    ret i64 [[TMP0]]
+//
+uint16x4_t test_pld_u16x4(uint16_t *p) {
+  return __riscv_pld_u16x4(p);
+}
+
+// RV32-LABEL: define dso_local i64 @test_pld_i32x2(
+// RV32-SAME: ptr noundef [[P:%.*]]) #[[ATTR0]] {
+// RV32-NEXT:  [[ENTRY:.*:]]
+// RV32-NEXT:    [[TMP0:%.*]] = load i64, ptr [[P]], align 1
+// RV32-NEXT:    ret i64 [[TMP0]]
+//
+// RV64-LABEL: define dso_local i64 @test_pld_i32x2(
+// RV64-SAME: ptr noundef [[P:%.*]]) #[[ATTR0]] {
+// RV64-NEXT:  [[ENTRY:.*:]]
+// RV64-NEXT:    [[TMP0:%.*]] = load i64, ptr [[P]], align 1
+// RV64-NEXT:    ret i64 [[TMP0]]
+//
+int32x2_t test_pld_i32x2(int32_t *p) {
+  return __riscv_pld_i32x2(p);
+}
+
+// RV32-LABEL: define dso_local i64 @test_pld_u32x2(
+// RV32-SAME: ptr noundef [[P:%.*]]) #[[ATTR0]] {
+// RV32-NEXT:  [[ENTRY:.*:]]
+// RV32-NEXT:    [[TMP0:%.*]] = load i64, ptr [[P]], align 1
+// RV32-NEXT:    ret i64 [[TMP0]]
+//
+// RV64-LABEL: define dso_local i64 @test_pld_u32x2(
+// RV64-SAME: ptr noundef [[P:%.*]]) #[[ATTR0]] {
+// RV64-NEXT:  [[ENTRY:.*:]]
+// RV64-NEXT:    [[TMP0:%.*]] = load i64, ptr [[P]], align 1
+// RV64-NEXT:    ret i64 [[TMP0]]
+//
+uint32x2_t test_pld_u32x2(uint32_t *p) {
+  return __riscv_pld_u32x2(p);
+}
+
+/* Packed Load with provable alignment (cf. the P-ext spec's note on
+ * __builtin_assume_aligned) */
+// RV32-LABEL: define dso_local i32 @test_pld_i8x4_aligned(
+// RV32-SAME: ptr noundef [[P:%.*]]) #[[ATTR0]] {
+// RV32-NEXT:  [[ENTRY:.*:]]
+// RV32-NEXT:    call void @llvm.assume(i1 true) [ "align"(ptr [[P]], i32 4) ]
+// RV32-NEXT:    [[TMP0:%.*]] = load i32, ptr [[P]], align 1
+// RV32-NEXT:    ret i32 [[TMP0]]
+//
+// RV64-LABEL: define dso_local i32 @test_pld_i8x4_aligned(
+// RV64-SAME: ptr noundef [[P:%.*]]) #[[ATTR0]] {
+// RV64-NEXT:  [[ENTRY:.*:]]
+// RV64-NEXT:    call void @llvm.assume(i1 true) [ "align"(ptr [[P]], i64 4) ]
+// RV64-NEXT:    [[TMP0:%.*]] = load i32, ptr [[P]], align 1
+// RV64-NEXT:    ret i32 [[TMP0]]
+//
+int8x4_t test_pld_i8x4_aligned(int8_t *p) {
+  return __riscv_pld_i8x4(__builtin_assume_aligned(p, 4));
+}
+
+// RV32-LABEL: define dso_local i64 @test_pld_i32x2_aligned(
+// RV32-SAME: ptr noundef [[P:%.*]]) #[[ATTR0]] {
+// RV32-NEXT:  [[ENTRY:.*:]]
+// RV32-NEXT:    call void @llvm.assume(i1 true) [ "align"(ptr [[P]], i32 8) ]
+// RV32-NEXT:    [[TMP0:%.*]] = load i64, ptr [[P]], align 1
+// RV32-NEXT:    ret i64 [[TMP0]]
+//
+// RV64-LABEL: define dso_local i64 @test_pld_i32x2_aligned(
+// RV64-SAME: ptr noundef [[P:%.*]]) #[[ATTR0]] {
+// RV64-NEXT:  [[ENTRY:.*:]]
+// RV64-NEXT:    call void @llvm.assume(i1 true) [ "align"(ptr [[P]], i64 8) ]
+// RV64-NEXT:    [[TMP0:%.*]] = load i64, ptr [[P]], align 1
+// RV64-NEXT:    ret i64 [[TMP0]]
+//
+int32x2_t test_pld_i32x2_aligned(int32_t *p) {
+  return __riscv_pld_i32x2(__builtin_assume_aligned(p, 8));
+}
diff --git a/clang/test/Sema/riscv-pld-pointer-types.c 
b/clang/test/Sema/riscv-pld-pointer-types.c
new file mode 100644
index 0000000000000..d4e739694ca94
--- /dev/null
+++ b/clang/test/Sema/riscv-pld-pointer-types.c
@@ -0,0 +1,42 @@
+// 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_pld_* intrinsics take a pointer to the element type; passing a
+// pointer to an unrelated type is ill-formed.
+
+int8x4_t test_pld_i8x4_ok(int8_t *p) {
+  return __riscv_pld_i8x4(p);
+}
+
+int8x4_t test_pld_i8x4_void_ptr(void *p) {
+  return __riscv_pld_i8x4(p);
+}
+
+int8x4_t test_pld_i8x4_array(void) {
+  int8_t a[4] = {1, 2, 3, 4};
+  return __riscv_pld_i8x4(a);
+}
+
+int8x4_t test_pld_i8x4_wrong_pointer_type(float *p) {
+  // expected-error@+1 {{incompatible pointer types passing 'float *' to 
parameter of type 'int8_t *' (aka 'signed char *')}}
+  return __riscv_pld_i8x4(p);
+}
+
+uint16x2_t test_pld_u16x2_wrong_pointer_type(uint32_t *p) {
+  // expected-error@+1 {{incompatible pointer types passing 'uint32_t *' (aka 
'unsigned int *') to parameter of type 'uint16_t *' (aka 'unsigned short *')}}
+  return __riscv_pld_u16x2(p);
+}
+
+int32x2_t test_pld_i32x2_wrong_pointer_type(int8x4_t *p) {
+  // expected-error@+1 {{incompatible pointer types passing 'int8x4_t *' to 
parameter of type 'int32_t *' (aka 'int *')}}
+  return __riscv_pld_i32x2(p);
+}
+
+int16x4_t test_pld_i16x4_const_discards_qualifiers(const int16_t *p) {
+  // expected-warning@+1 {{passing 'const int16_t *' (aka 'const short *') to 
parameter of type 'int16_t *' (aka 'short *') discards qualifiers}}
+  return __riscv_pld_i16x4(p);
+}
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 ecb52df9e12b5..790da23c40cd0 100644
--- a/cross-project-tests/intrinsic-header-tests/riscv_packed_simd.c
+++ b/cross-project-tests/intrinsic-header-tests/riscv_packed_simd.c
@@ -4525,3 +4525,83 @@ int32x2_t test_pset_i32_i32x2(int32x2_t v, int32_t e) {
 uint32x2_t test_pset_u32_u32x2(uint32x2_t v, uint32_t e) {
   return __riscv_pset_u32_u32x2(v, e, 0);
 }
+
+/* Packed Load: the load is emitted with align 1, so the backend either emits
+ * a single lw/ld (targets with fast misaligned GPR loads) or splits it into
+ * per-byte loads. The generic target used here takes the split path. */
+
+// CHECK-LABEL: test_pld_i8x4:
+// CHECK-COUNT-4: lbu{{[[:space:]]}}
+int8x4_t test_pld_i8x4(int8_t *p) { return __riscv_pld_i8x4(p); }
+
+// CHECK-LABEL: test_pld_u8x4:
+// CHECK-COUNT-4: lbu{{[[:space:]]}}
+uint8x4_t test_pld_u8x4(uint8_t *p) { return __riscv_pld_u8x4(p); }
+
+// CHECK-LABEL: test_pld_i16x2:
+// CHECK-COUNT-4: lbu{{[[:space:]]}}
+int16x2_t test_pld_i16x2(int16_t *p) { return __riscv_pld_i16x2(p); }
+
+// CHECK-LABEL: test_pld_u16x2:
+// CHECK-COUNT-4: lbu{{[[:space:]]}}
+uint16x2_t test_pld_u16x2(uint16_t *p) { return __riscv_pld_u16x2(p); }
+
+// CHECK-LABEL: test_pld_i8x8:
+// RV32-COUNT-8: lbu{{[[:space:]]}}
+// RV64-COUNT-8: lbu{{[[:space:]]}}
+int8x8_t test_pld_i8x8(int8_t *p) { return __riscv_pld_i8x8(p); }
+
+// CHECK-LABEL: test_pld_u8x8:
+// CHECK-COUNT-8: lbu{{[[:space:]]}}
+uint8x8_t test_pld_u8x8(uint8_t *p) { return __riscv_pld_u8x8(p); }
+
+// CHECK-LABEL: test_pld_i16x4:
+// CHECK-COUNT-8: lbu{{[[:space:]]}}
+int16x4_t test_pld_i16x4(int16_t *p) { return __riscv_pld_i16x4(p); }
+
+// CHECK-LABEL: test_pld_u16x4:
+// CHECK-COUNT-8: lbu{{[[:space:]]}}
+uint16x4_t test_pld_u16x4(uint16_t *p) { return __riscv_pld_u16x4(p); }
+
+// CHECK-LABEL: test_pld_i32x2:
+// CHECK-COUNT-8: lbu{{[[:space:]]}}
+int32x2_t test_pld_i32x2(int32_t *p) { return __riscv_pld_i32x2(p); }
+
+// CHECK-LABEL: test_pld_u32x2:
+// CHECK-COUNT-8: lbu{{[[:space:]]}}
+uint32x2_t test_pld_u32x2(uint32_t *p) { return __riscv_pld_u32x2(p); }
+
+/* Packed Load with provable alignment: __builtin_assume_aligned restores a
+ * known alignment, so the load is not split. */
+
+// CHECK-LABEL: test_pld_i8x4_aligned:
+// CHECK:         lw
+// CHECK-NOT:     lbu
+int8x4_t test_pld_i8x4_aligned(int8_t *p) {
+  return __riscv_pld_i8x4(__builtin_assume_aligned(p, 4));
+}
+
+// CHECK-LABEL: test_pld_u16x2_aligned:
+// CHECK:         lw
+// CHECK-NOT:     lbu
+uint16x2_t test_pld_u16x2_aligned(uint16_t *p) {
+  return __riscv_pld_u16x2(__builtin_assume_aligned(p, 4));
+}
+
+// CHECK-LABEL: test_pld_i8x8_aligned:
+// RV32:         lw
+// RV32-NOT:     lbu
+// RV64:         ld
+// RV64-NOT:     lbu
+int8x8_t test_pld_i8x8_aligned(int8_t *p) {
+  return __riscv_pld_i8x8(__builtin_assume_aligned(p, 8));
+}
+
+// CHECK-LABEL: test_pld_u32x2_aligned:
+// RV32:         lw
+// RV32-NOT:     lbu
+// RV64:         ld
+// RV64-NOT:     lbu
+uint32x2_t test_pld_u32x2_aligned(uint32_t *p) {
+  return __riscv_pld_u32x2(__builtin_assume_aligned(p, 8));
+}

>From d261c667d81831d211f0534f37d927bb5d91547c Mon Sep 17 00:00:00 2001
From: Dongyan Chen <[email protected]>
Date: Tue, 15 Sep 2026 14:55:49 +0800
Subject: [PATCH 2/3] Move unaligned load typedef into function scope

Declare the aligned(1) view type inside __packed_load instead of
exposing ten __packed_*_unaligned typedefs in the global namespace.
---
 clang/lib/Headers/riscv_packed_simd.h | 46 +++++++--------------------
 1 file changed, 12 insertions(+), 34 deletions(-)

diff --git a/clang/lib/Headers/riscv_packed_simd.h 
b/clang/lib/Headers/riscv_packed_simd.h
index 0dabc92667a50..29cfc2b16c6ef 100644
--- a/clang/lib/Headers/riscv_packed_simd.h
+++ b/clang/lib/Headers/riscv_packed_simd.h
@@ -30,29 +30,6 @@ typedef uint16_t uint16x4_t 
__attribute__((__vector_size__(8)));
 typedef int32_t int32x2_t __attribute__((__vector_size__(8)));
 typedef uint32_t uint32x2_t __attribute__((__vector_size__(8)));
 
-/* Unaligned views of the packed types, used by the load/store intrinsics to
- * express that the pointer may have arbitrary alignment. */
-typedef int8_t __packed_i8x4_unaligned
-    __attribute__((__vector_size__(4), __aligned__(1)));
-typedef uint8_t __packed_u8x4_unaligned
-    __attribute__((__vector_size__(4), __aligned__(1)));
-typedef int16_t __packed_i16x2_unaligned
-    __attribute__((__vector_size__(4), __aligned__(1)));
-typedef uint16_t __packed_u16x2_unaligned
-    __attribute__((__vector_size__(4), __aligned__(1)));
-typedef int8_t __packed_i8x8_unaligned
-    __attribute__((__vector_size__(8), __aligned__(1)));
-typedef uint8_t __packed_u8x8_unaligned
-    __attribute__((__vector_size__(8), __aligned__(1)));
-typedef int16_t __packed_i16x4_unaligned
-    __attribute__((__vector_size__(8), __aligned__(1)));
-typedef uint16_t __packed_u16x4_unaligned
-    __attribute__((__vector_size__(8), __aligned__(1)));
-typedef int32_t __packed_i32x2_unaligned
-    __attribute__((__vector_size__(8), __aligned__(1)));
-typedef uint32_t __packed_u32x2_unaligned
-    __attribute__((__vector_size__(8), __aligned__(1)));
-
 #define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__))
 
 #define __packed_splat2(ty, x) ((ty){(x), (x)})
@@ -351,8 +328,9 @@ typedef uint32_t __packed_u32x2_unaligned
     return __v;                                                                
\
   }
 
-#define __packed_load(name, ty, elt_ty, ua_ty)                                 
\
+#define __packed_load(name, ty, elt_ty)                                        
\
   static __inline__ ty __DEFAULT_FN_ATTRS __riscv_##name(elt_ty *__p) {        
\
+    typedef ty __attribute__((__aligned__(1))) ua_ty;                          
\
     return *(ua_ty *)__p;                                                      
\
   }
 
@@ -1105,18 +1083,18 @@ __packed_extract(pget_i32x2_i32, int32_t, int32x2_t, 1)
 __packed_extract(pget_u32x2_u32, uint32_t, uint32x2_t, 1)
 
 /* Packed Load (32-bit) */
-__packed_load(pld_i8x4, int8x4_t, int8_t, __packed_i8x4_unaligned)
-__packed_load(pld_u8x4, uint8x4_t, uint8_t, __packed_u8x4_unaligned)
-__packed_load(pld_i16x2, int16x2_t, int16_t, __packed_i16x2_unaligned)
-__packed_load(pld_u16x2, uint16x2_t, uint16_t, __packed_u16x2_unaligned)
+__packed_load(pld_i8x4, int8x4_t, int8_t)
+__packed_load(pld_u8x4, uint8x4_t, uint8_t)
+__packed_load(pld_i16x2, int16x2_t, int16_t)
+__packed_load(pld_u16x2, uint16x2_t, uint16_t)
 
 /* Packed Load (64-bit) */
-__packed_load(pld_i8x8, int8x8_t, int8_t, __packed_i8x8_unaligned)
-__packed_load(pld_u8x8, uint8x8_t, uint8_t, __packed_u8x8_unaligned)
-__packed_load(pld_i16x4, int16x4_t, int16_t, __packed_i16x4_unaligned)
-__packed_load(pld_u16x4, uint16x4_t, uint16_t, __packed_u16x4_unaligned)
-__packed_load(pld_i32x2, int32x2_t, int32_t, __packed_i32x2_unaligned)
-__packed_load(pld_u32x2, uint32x2_t, uint32_t, __packed_u32x2_unaligned)
+__packed_load(pld_i8x8, int8x8_t, int8_t)
+__packed_load(pld_u8x8, uint8x8_t, uint8_t)
+__packed_load(pld_i16x4, int16x4_t, int16_t)
+__packed_load(pld_u16x4, uint16x4_t, uint16_t)
+__packed_load(pld_i32x2, int32x2_t, int32_t)
+__packed_load(pld_u32x2, uint32x2_t, uint32_t)
 
 /* Reinterpret Casts, Packed <-> Scalar (32-bit) */
 __packed_reinterpret(u8x4_u32, uint32_t, uint8x4_t)

>From db15b45edf06286182657929fd70f2f7819e2a9b Mon Sep 17 00:00:00 2001
From: Dongyan Chen <[email protected]>
Date: Wed, 16 Sep 2026 09:19:37 +0800
Subject: [PATCH 3/3] Use per-target CHECK prefixes for packed load tests

---
 .../riscv_packed_simd.c                       | 31 ++++++++++++-------
 1 file changed, 20 insertions(+), 11 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 790da23c40cd0..03ba3ba759241 100644
--- a/cross-project-tests/intrinsic-header-tests/riscv_packed_simd.c
+++ b/cross-project-tests/intrinsic-header-tests/riscv_packed_simd.c
@@ -4531,19 +4531,23 @@ uint32x2_t test_pset_u32_u32x2(uint32x2_t v, uint32_t 
e) {
  * per-byte loads. The generic target used here takes the split path. */
 
 // CHECK-LABEL: test_pld_i8x4:
-// CHECK-COUNT-4: lbu{{[[:space:]]}}
+// RV32-COUNT-4: lbu{{[[:space:]]}}
+// RV64-COUNT-4: lbu{{[[:space:]]}}
 int8x4_t test_pld_i8x4(int8_t *p) { return __riscv_pld_i8x4(p); }
 
 // CHECK-LABEL: test_pld_u8x4:
-// CHECK-COUNT-4: lbu{{[[:space:]]}}
+// RV32-COUNT-4: lbu{{[[:space:]]}}
+// RV64-COUNT-4: lbu{{[[:space:]]}}
 uint8x4_t test_pld_u8x4(uint8_t *p) { return __riscv_pld_u8x4(p); }
 
 // CHECK-LABEL: test_pld_i16x2:
-// CHECK-COUNT-4: lbu{{[[:space:]]}}
+// RV32-COUNT-4: lbu{{[[:space:]]}}
+// RV64-COUNT-4: lbu{{[[:space:]]}}
 int16x2_t test_pld_i16x2(int16_t *p) { return __riscv_pld_i16x2(p); }
 
 // CHECK-LABEL: test_pld_u16x2:
-// CHECK-COUNT-4: lbu{{[[:space:]]}}
+// RV32-COUNT-4: lbu{{[[:space:]]}}
+// RV64-COUNT-4: lbu{{[[:space:]]}}
 uint16x2_t test_pld_u16x2(uint16_t *p) { return __riscv_pld_u16x2(p); }
 
 // CHECK-LABEL: test_pld_i8x8:
@@ -4552,23 +4556,28 @@ uint16x2_t test_pld_u16x2(uint16_t *p) { return 
__riscv_pld_u16x2(p); }
 int8x8_t test_pld_i8x8(int8_t *p) { return __riscv_pld_i8x8(p); }
 
 // CHECK-LABEL: test_pld_u8x8:
-// CHECK-COUNT-8: lbu{{[[:space:]]}}
+// RV32-COUNT-8: lbu{{[[:space:]]}}
+// RV64-COUNT-8: lbu{{[[:space:]]}}
 uint8x8_t test_pld_u8x8(uint8_t *p) { return __riscv_pld_u8x8(p); }
 
 // CHECK-LABEL: test_pld_i16x4:
-// CHECK-COUNT-8: lbu{{[[:space:]]}}
+// RV32-COUNT-8: lbu{{[[:space:]]}}
+// RV64-COUNT-8: lbu{{[[:space:]]}}
 int16x4_t test_pld_i16x4(int16_t *p) { return __riscv_pld_i16x4(p); }
 
 // CHECK-LABEL: test_pld_u16x4:
-// CHECK-COUNT-8: lbu{{[[:space:]]}}
+// RV32-COUNT-8: lbu{{[[:space:]]}}
+// RV64-COUNT-8: lbu{{[[:space:]]}}
 uint16x4_t test_pld_u16x4(uint16_t *p) { return __riscv_pld_u16x4(p); }
 
 // CHECK-LABEL: test_pld_i32x2:
-// CHECK-COUNT-8: lbu{{[[:space:]]}}
+// RV32-COUNT-8: lbu{{[[:space:]]}}
+// RV64-COUNT-8: lbu{{[[:space:]]}}
 int32x2_t test_pld_i32x2(int32_t *p) { return __riscv_pld_i32x2(p); }
 
 // CHECK-LABEL: test_pld_u32x2:
-// CHECK-COUNT-8: lbu{{[[:space:]]}}
+// RV32-COUNT-8: lbu{{[[:space:]]}}
+// RV64-COUNT-8: lbu{{[[:space:]]}}
 uint32x2_t test_pld_u32x2(uint32_t *p) { return __riscv_pld_u32x2(p); }
 
 /* Packed Load with provable alignment: __builtin_assume_aligned restores a
@@ -4589,7 +4598,7 @@ uint16x2_t test_pld_u16x2_aligned(uint16_t *p) {
 }
 
 // CHECK-LABEL: test_pld_i8x8_aligned:
-// RV32:         lw
+// RV32-COUNT-2: lw
 // RV32-NOT:     lbu
 // RV64:         ld
 // RV64-NOT:     lbu
@@ -4598,7 +4607,7 @@ int8x8_t test_pld_i8x8_aligned(int8_t *p) {
 }
 
 // CHECK-LABEL: test_pld_u32x2_aligned:
-// RV32:         lw
+// RV32-COUNT-2: lw
 // RV32-NOT:     lbu
 // RV64:         ld
 // RV64-NOT:     lbu

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

Reply via email to