[llvm] [RISCV][SLP] Precommit strided-load alignment tests (NFC) (PR #222863)

via llvm-commits llvm-commits at lists.llvm.org
Fri Sep 11 00:14:23 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-llvm-transforms

Author: Kiva (imkiva)

<details>
<summary>Changes</summary>

Record SLP's current handling of adjacent load groups with different alignments on RV32 and RV64.

The RV64 strict-alignment case currently forms a widened i64 strided load with align 4 and a 28-byte stride. Mark this as a FIXME for the follow-up legality fix. Naturally aligned strided loads are also covered.

Precommit coverage for #<!-- -->222520.

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


1 Files Affected:

- (added) llvm/test/Transforms/SLPVectorizer/RISCV/strided-load-common-alignment.ll (+102) 


``````````diff
diff --git a/llvm/test/Transforms/SLPVectorizer/RISCV/strided-load-common-alignment.ll b/llvm/test/Transforms/SLPVectorizer/RISCV/strided-load-common-alignment.ll
new file mode 100644
index 0000000000000..81203dbb5a047
--- /dev/null
+++ b/llvm/test/Transforms/SLPVectorizer/RISCV/strided-load-common-alignment.ll
@@ -0,0 +1,102 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
+; RUN: opt -S -passes=slp-vectorizer -mtriple=riscv64 -mattr=+v,-unaligned-vector-mem < %s | FileCheck %s --check-prefix=RV64
+; RUN: opt -S -passes=slp-vectorizer -mtriple=riscv32 -mattr=+v,-unaligned-vector-mem < %s | FileCheck %s --check-prefix=RV32
+; RUN: opt -S -passes=slp-vectorizer -mtriple=riscv64 -mattr=+v,+unaligned-vector-mem < %s | FileCheck %s --check-prefix=UNALIGNED
+;
+; The first load's alignment does not describe every group. Widening each
+; adjacent pair to i64 would leave the group at byte offset 28 misaligned.
+; FIXME: Do not form an i64 strided load in the RV64 strict-alignment case.
+
+define void @gather_fields(ptr %base, ptr %out) {
+; RV64-LABEL: define void @gather_fields(
+; RV64-SAME: ptr [[BASE:%.*]], ptr [[OUT:%.*]]) #[[ATTR0:[0-9]+]] {
+; RV64-NEXT:    [[TMP1:%.*]] = call <2 x i64> @llvm.experimental.vp.strided.load.v2i64.p0.i64(ptr align 4 [[BASE]], i64 28, <2 x i1> splat (i1 true), i32 2)
+; RV64-NEXT:    [[TMP5:%.*]] = bitcast <2 x i64> [[TMP1]] to <4 x i32>
+; RV64-NEXT:    [[TMP6:%.*]] = add <4 x i32> [[TMP5]], splat (i32 3)
+; RV64-NEXT:    store <4 x i32> [[TMP6]], ptr [[OUT]], align 4
+; RV64-NEXT:    ret void
+;
+; RV32-LABEL: define void @gather_fields(
+; RV32-SAME: ptr [[BASE:%.*]], ptr [[OUT:%.*]]) #[[ATTR0:[0-9]+]] {
+; RV32-NEXT:    [[P2:%.*]] = getelementptr inbounds i32, ptr [[BASE]], i64 7
+; RV32-NEXT:    [[Q2:%.*]] = getelementptr inbounds i32, ptr [[OUT]], i64 2
+; RV32-NEXT:    [[TMP1:%.*]] = load <2 x i32>, ptr [[BASE]], align 16
+; RV32-NEXT:    [[TMP3:%.*]] = add <2 x i32> [[TMP1]], splat (i32 3)
+; RV32-NEXT:    [[TMP2:%.*]] = load <2 x i32>, ptr [[P2]], align 4
+; RV32-NEXT:    [[TMP4:%.*]] = add <2 x i32> [[TMP2]], splat (i32 3)
+; RV32-NEXT:    store <2 x i32> [[TMP3]], ptr [[OUT]], align 4
+; RV32-NEXT:    store <2 x i32> [[TMP4]], ptr [[Q2]], align 4
+; RV32-NEXT:    ret void
+;
+; UNALIGNED-LABEL: define void @gather_fields(
+; UNALIGNED-SAME: ptr [[BASE:%.*]], ptr [[OUT:%.*]]) #[[ATTR0:[0-9]+]] {
+; UNALIGNED-NEXT:    [[TMP1:%.*]] = call <2 x i64> @llvm.experimental.vp.strided.load.v2i64.p0.i64(ptr align 4 [[BASE]], i64 28, <2 x i1> splat (i1 true), i32 2)
+; UNALIGNED-NEXT:    [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to <4 x i32>
+; UNALIGNED-NEXT:    [[TMP3:%.*]] = add <4 x i32> [[TMP2]], splat (i32 3)
+; UNALIGNED-NEXT:    store <4 x i32> [[TMP3]], ptr [[OUT]], align 4
+; UNALIGNED-NEXT:    ret void
+;
+  %p1 = getelementptr inbounds i32, ptr %base, i64 1
+  %p2 = getelementptr inbounds i32, ptr %base, i64 7
+  %p3 = getelementptr inbounds i32, ptr %base, i64 8
+  %a = load i32, ptr %base, align 16
+  %b = load i32, ptr %p1, align 4
+  %c = load i32, ptr %p2, align 4
+  %d = load i32, ptr %p3, align 16
+  %v0 = add i32 %a, 3
+  %v1 = add i32 %b, 3
+  %v2 = add i32 %c, 3
+  %v3 = add i32 %d, 3
+  %q1 = getelementptr inbounds i32, ptr %out, i64 1
+  %q2 = getelementptr inbounds i32, ptr %out, i64 2
+  %q3 = getelementptr inbounds i32, ptr %out, i64 3
+  store i32 %v0, ptr %out, align 4
+  store i32 %v1, ptr %q1, align 4
+  store i32 %v2, ptr %q2, align 4
+  store i32 %v3, ptr %q3, align 4
+  ret void
+}
+
+; Naturally aligned strided loads remain legal.
+define void @aligned_values(ptr %base, ptr %out) {
+; RV64-LABEL: define void @aligned_values(
+; RV64-SAME: ptr [[BASE:%.*]], ptr [[OUT:%.*]]) #[[ATTR0]] {
+; RV64-NEXT:    [[TMP1:%.*]] = call <4 x i64> @llvm.experimental.vp.strided.load.v4i64.p0.i64(ptr align 8 [[BASE]], i64 64, <4 x i1> splat (i1 true), i32 4)
+; RV64-NEXT:    [[TMP2:%.*]] = add <4 x i64> [[TMP1]], splat (i64 3)
+; RV64-NEXT:    store <4 x i64> [[TMP2]], ptr [[OUT]], align 8
+; RV64-NEXT:    ret void
+;
+; RV32-LABEL: define void @aligned_values(
+; RV32-SAME: ptr [[BASE:%.*]], ptr [[OUT:%.*]]) #[[ATTR0]] {
+; RV32-NEXT:    [[TMP1:%.*]] = call <4 x i64> @llvm.experimental.vp.strided.load.v4i64.p0.i32(ptr align 8 [[BASE]], i32 64, <4 x i1> splat (i1 true), i32 4)
+; RV32-NEXT:    [[TMP2:%.*]] = add <4 x i64> [[TMP1]], splat (i64 3)
+; RV32-NEXT:    store <4 x i64> [[TMP2]], ptr [[OUT]], align 8
+; RV32-NEXT:    ret void
+;
+; UNALIGNED-LABEL: define void @aligned_values(
+; UNALIGNED-SAME: ptr [[BASE:%.*]], ptr [[OUT:%.*]]) #[[ATTR0]] {
+; UNALIGNED-NEXT:    [[TMP1:%.*]] = call <4 x i64> @llvm.experimental.vp.strided.load.v4i64.p0.i64(ptr align 8 [[BASE]], i64 64, <4 x i1> splat (i1 true), i32 4)
+; UNALIGNED-NEXT:    [[TMP2:%.*]] = add <4 x i64> [[TMP1]], splat (i64 3)
+; UNALIGNED-NEXT:    store <4 x i64> [[TMP2]], ptr [[OUT]], align 8
+; UNALIGNED-NEXT:    ret void
+;
+  %p1 = getelementptr inbounds i64, ptr %base, i64 8
+  %p2 = getelementptr inbounds i64, ptr %base, i64 16
+  %p3 = getelementptr inbounds i64, ptr %base, i64 24
+  %a = load i64, ptr %base, align 16
+  %b = load i64, ptr %p1, align 8
+  %c = load i64, ptr %p2, align 8
+  %d = load i64, ptr %p3, align 8
+  %v0 = add i64 %a, 3
+  %v1 = add i64 %b, 3
+  %v2 = add i64 %c, 3
+  %v3 = add i64 %d, 3
+  %q1 = getelementptr inbounds i64, ptr %out, i64 1
+  %q2 = getelementptr inbounds i64, ptr %out, i64 2
+  %q3 = getelementptr inbounds i64, ptr %out, i64 3
+  store i64 %v0, ptr %out, align 8
+  store i64 %v1, ptr %q1, align 8
+  store i64 %v2, ptr %q2, align 8
+  store i64 %v3, ptr %q3, align 8
+  ret void
+}

``````````

</details>


https://github.com/llvm/llvm-project/pull/222863


More information about the llvm-commits mailing list