[llvm] [SLP][NFC] Add tests for runtime strided loads during revectorization (PR #191875)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Apr 13 12:01:46 PDT 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-transforms
Author: Ryan Buchner (bababuck)
<details>
<summary>Changes</summary>
Depending on the case, we either miss optimizing re-vectorized runtime strided loads (and use a gather instead) or produces the incorrect strided load.
---
Full diff: https://github.com/llvm/llvm-project/pull/191875.diff
1 Files Affected:
- (modified) llvm/test/Transforms/SLPVectorizer/RISCV/revec-strided-load.ll (+101)
``````````diff
diff --git a/llvm/test/Transforms/SLPVectorizer/RISCV/revec-strided-load.ll b/llvm/test/Transforms/SLPVectorizer/RISCV/revec-strided-load.ll
index 6d62659c2fef1..33c7858ee701d 100644
--- a/llvm/test/Transforms/SLPVectorizer/RISCV/revec-strided-load.ll
+++ b/llvm/test/Transforms/SLPVectorizer/RISCV/revec-strided-load.ll
@@ -20,6 +20,55 @@ entry:
ret void
}
+define void @widened_strided_load_runtime(ptr %in0, ptr %out0, i64 %stride) {
+; CHECK-LABEL: @widened_strided_load_runtime(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[IN1:%.*]] = getelementptr <8 x i8>, ptr [[IN0:%.*]], i64 [[STRIDE:%.*]]
+; CHECK-NEXT: [[L0:%.*]] = load <8 x i8>, ptr [[IN0]], align 2
+; CHECK-NEXT: [[L1:%.*]] = load <8 x i8>, ptr [[IN1]], align 2
+; CHECK-NEXT: [[TMP0:%.*]] = shufflevector <8 x i8> [[L0]], <8 x i8> poison, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison>
+; CHECK-NEXT: [[TMP1:%.*]] = shufflevector <8 x i8> [[L1]], <8 x i8> poison, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison>
+; CHECK-NEXT: [[TMP2:%.*]] = shufflevector <16 x i8> [[TMP0]], <16 x i8> [[TMP1]], <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23>
+; CHECK-NEXT: store <16 x i8> [[TMP2]], ptr [[OUT0:%.*]], align 2
+; CHECK-NEXT: ret void
+;
+entry:
+ %in1 = getelementptr <8 x i8>, ptr %in0, i64 %stride
+ %l0 = load <8 x i8>, ptr %in0, align 2
+ %l1 = load <8 x i8>, ptr %in1, align 2
+ %out1 = getelementptr i8, ptr %out0, i64 8
+ store <8 x i8> %l0, ptr %out0, align 2
+ store <8 x i8> %l1, ptr %out1, align 2
+ ret void
+}
+
+; Base case of strided load, implicitly is widened
+define void @widened_strided_load_runtime_more_elements(ptr %in0, ptr %out0, i64 %stride) {
+; CHECK-LABEL: @widened_strided_load_runtime_more_elements(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[TMP0:%.*]] = mul i64 [[STRIDE:%.*]], 2
+; CHECK-NEXT: [[TMP1:%.*]] = call <8 x i8> @llvm.experimental.vp.strided.load.v8i8.p0.i64(ptr align 2 [[IN0:%.*]], i64 [[TMP0]], <8 x i1> splat (i1 true), i32 8)
+; CHECK-NEXT: store <8 x i8> [[TMP1]], ptr [[OUT0:%.*]], align 2
+; CHECK-NEXT: ret void
+;
+entry:
+ %in1 = getelementptr <2 x i8>, ptr %in0, i64 %stride
+ %in2 = getelementptr <2 x i8>, ptr %in1, i64 %stride
+ %in3 = getelementptr <2 x i8>, ptr %in2, i64 %stride
+ %l0 = load <2 x i8>, ptr %in0, align 2
+ %l1 = load <2 x i8>, ptr %in1, align 2
+ %l2 = load <2 x i8>, ptr %in2, align 2
+ %l3 = load <2 x i8>, ptr %in3, align 2
+ %out1 = getelementptr i8, ptr %out0, i64 2
+ %out2 = getelementptr i8, ptr %out0, i64 4
+ %out3 = getelementptr i8, ptr %out0, i64 6
+ store <2 x i8> %l0, ptr %out0, align 2
+ store <2 x i8> %l1, ptr %out1, align 2
+ store <2 x i8> %l2, ptr %out2, align 2
+ store <2 x i8> %l3, ptr %out3, align 2
+ ret void
+}
+
; Widened strided load pattern but vectorized types
define void @doubly_widened_strided_load(ptr %in0, ptr %out0) {
; CHECK-LABEL: @doubly_widened_strided_load(
@@ -47,6 +96,36 @@ entry:
ret void
}
+define void @doubly_widened_strided_load_runtime(ptr %in0, ptr %out0, i64 %stride) {
+; CHECK-LABEL: @doubly_widened_strided_load_runtime(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[IN2:%.*]] = getelementptr <2 x i8>, ptr [[IN0:%.*]], i64 [[STRIDE:%.*]]
+; CHECK-NEXT: [[TMP0:%.*]] = load <4 x i8>, ptr [[IN0]], align 2
+; CHECK-NEXT: [[TMP1:%.*]] = load <4 x i8>, ptr [[IN2]], align 2
+; CHECK-NEXT: [[TMP2:%.*]] = shufflevector <4 x i8> [[TMP0]], <4 x i8> poison, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 poison, i32 poison, i32 poison, i32 poison>
+; CHECK-NEXT: [[TMP3:%.*]] = shufflevector <4 x i8> [[TMP1]], <4 x i8> poison, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 poison, i32 poison, i32 poison, i32 poison>
+; CHECK-NEXT: [[TMP4:%.*]] = shufflevector <4 x i8> [[TMP0]], <4 x i8> [[TMP1]], <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
+; CHECK-NEXT: store <8 x i8> [[TMP4]], ptr [[OUT0:%.*]], align 2
+; CHECK-NEXT: ret void
+;
+entry:
+ %in1 = getelementptr <2 x i8>, ptr %in0, i64 1
+ %in2 = getelementptr <2 x i8>, ptr %in0, i64 %stride
+ %in3 = getelementptr <2 x i8>, ptr %in2, i64 1
+ %l0 = load <2 x i8>, ptr %in0, align 2
+ %l1 = load <2 x i8>, ptr %in1, align 2
+ %l2 = load <2 x i8>, ptr %in2, align 2
+ %l3 = load <2 x i8>, ptr %in3, align 2
+ %out1 = getelementptr i8, ptr %out0, i64 2
+ %out2 = getelementptr i8, ptr %out0, i64 4
+ %out3 = getelementptr i8, ptr %out0, i64 6
+ store <2 x i8> %l0, ptr %out0, align 2
+ store <2 x i8> %l1, ptr %out1, align 2
+ store <2 x i8> %l2, ptr %out2, align 2
+ store <2 x i8> %l3, ptr %out3, align 2
+ ret void
+}
+
; The resulting widened type isn't legal
define void @too_wide(ptr %in0, ptr %out0) {
; CHECK-LABEL: @too_wide(
@@ -70,6 +149,28 @@ entry:
ret void
}
+define void @too_wide_runtime(ptr %in0, ptr %out0, i64 %stride) {
+; CHECK-LABEL: @too_wide_runtime(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[IN1:%.*]] = getelementptr <8 x i16>, ptr [[IN0:%.*]], i64 [[STRIDE:%.*]]
+; CHECK-NEXT: [[L0:%.*]] = load <8 x i16>, ptr [[IN0]], align 2
+; CHECK-NEXT: [[L1:%.*]] = load <8 x i16>, ptr [[IN1]], align 2
+; CHECK-NEXT: [[TMP0:%.*]] = shufflevector <8 x i16> [[L0]], <8 x i16> poison, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison>
+; CHECK-NEXT: [[TMP1:%.*]] = shufflevector <8 x i16> [[L1]], <8 x i16> poison, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison>
+; CHECK-NEXT: [[TMP2:%.*]] = shufflevector <16 x i16> [[TMP0]], <16 x i16> [[TMP1]], <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23>
+; CHECK-NEXT: store <16 x i16> [[TMP2]], ptr [[OUT0:%.*]], align 2
+; CHECK-NEXT: ret void
+;
+entry:
+ %in1 = getelementptr <8 x i16>, ptr %in0, i64 %stride
+ %l0 = load <8 x i16>, ptr %in0, align 2
+ %l1 = load <8 x i16>, ptr %in1, align 2
+ %out1 = getelementptr i16, ptr %out0, i64 8
+ store <8 x i16> %l0, ptr %out0, align 2
+ store <8 x i16> %l1, ptr %out1, align 2
+ ret void
+}
+
; Stride size isn't aligned to the vector size
define void @non_aligned_stride(ptr %in0, ptr %out0) {
; CHECK-LABEL: @non_aligned_stride(
``````````
</details>
https://github.com/llvm/llvm-project/pull/191875
More information about the llvm-commits
mailing list