[llvm] [SLP][NFC]Add a test with missed vectorization, NFC (PR #222141)

via llvm-commits llvm-commits at lists.llvm.org
Tue Sep 8 13:55:54 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-llvm-transforms

Author: Alexey Bataev (alexey-bataev)

<details>
<summary>Changes</summary>



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


1 Files Affected:

- (added) llvm/test/Transforms/SLPVectorizer/AArch64/splat-gather-subtree-drop.ll (+144) 


``````````diff
diff --git a/llvm/test/Transforms/SLPVectorizer/AArch64/splat-gather-subtree-drop.ll b/llvm/test/Transforms/SLPVectorizer/AArch64/splat-gather-subtree-drop.ll
new file mode 100644
index 0000000000000..c6677935dacda
--- /dev/null
+++ b/llvm/test/Transforms/SLPVectorizer/AArch64/splat-gather-subtree-drop.ll
@@ -0,0 +1,144 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
+; RUN: opt -S -passes=slp-vectorizer -mtriple=aarch64-unknown-linux-gnu -mcpu=neoverse-v2 < %s | FileCheck %s
+
+; The splat subtree for the zexts is not worth keeping: the splat gathers are
+; cheaper as plain insertion sequences, and the paired arithmetic must still
+; be vectorized.
+
+define i32 @test1(ptr %p, ptr %q, i32 %seed) {
+; CHECK-LABEL: define i32 @test1(
+; CHECK-SAME: ptr [[P:%.*]], ptr [[Q:%.*]], i32 [[SEED:%.*]]) #[[ATTR0:[0-9]+]] {
+; CHECK-NEXT:  [[ENTRY:.*:]]
+; CHECK-NEXT:    [[V0:%.*]] = load i8, ptr [[P]], align 1
+; CHECK-NEXT:    [[V1:%.*]] = zext i8 [[V0]] to i32
+; CHECK-NEXT:    [[V2:%.*]] = add nuw nsw i32 [[V1]], 1
+; CHECK-NEXT:    [[V3:%.*]] = load i8, ptr [[Q]], align 1
+; CHECK-NEXT:    [[V4:%.*]] = zext i8 [[V3]] to i32
+; CHECK-NEXT:    [[V5:%.*]] = or i32 [[V2]], [[V4]]
+; CHECK-NEXT:    [[V6:%.*]] = and i32 [[V4]], 1
+; CHECK-NEXT:    [[V7:%.*]] = add nuw nsw i32 [[V6]], 1
+; CHECK-NEXT:    [[V8:%.*]] = xor i32 [[V7]], 1
+; CHECK-NEXT:    [[V9:%.*]] = add nuw nsw i32 [[V5]], 1
+; CHECK-NEXT:    [[V10:%.*]] = and i32 [[V5]], 1
+; CHECK-NEXT:    [[V11:%.*]] = xor i32 [[V9]], [[V10]]
+; CHECK-NEXT:    [[V12:%.*]] = or i32 [[V8]], [[V11]]
+; CHECK-NEXT:    [[V13:%.*]] = add nsw i32 [[V1]], -2
+; CHECK-NEXT:    [[V14:%.*]] = or i32 [[V13]], [[V4]]
+; CHECK-NEXT:    [[V15:%.*]] = and i32 [[SEED]], 1
+; CHECK-NEXT:    [[V16:%.*]] = add nuw nsw i32 [[V15]], 1
+; CHECK-NEXT:    [[V17:%.*]] = xor i32 [[V16]], 1
+; CHECK-NEXT:    [[V18:%.*]] = add nsw i32 [[V14]], 1
+; CHECK-NEXT:    [[V19:%.*]] = and i32 [[V14]], 1
+; CHECK-NEXT:    [[V20:%.*]] = xor i32 [[V18]], [[V19]]
+; CHECK-NEXT:    [[V21:%.*]] = or i32 [[V17]], [[V20]]
+; CHECK-NEXT:    [[V22:%.*]] = or i32 [[V12]], [[V21]]
+; CHECK-NEXT:    ret i32 [[V22]]
+;
+entry:
+  %v0 = load i8, ptr %p, align 1
+  %v1 = zext i8 %v0 to i32
+  %v2 = add nuw nsw i32 %v1, 1
+  %v3 = load i8, ptr %q, align 1
+  %v4 = zext i8 %v3 to i32
+  %v5 = or i32 %v2, %v4
+  %v6 = and i32 %v4, 1
+  %v7 = add nuw nsw i32 %v6, 1
+  %v8 = xor i32 %v7, 1
+  %v9 = add nuw nsw i32 %v5, 1
+  %v10 = and i32 %v5, 1
+  %v11 = xor i32 %v9, %v10
+  %v12 = or i32 %v8, %v11
+  %v13 = add nsw i32 %v1, -2
+  %v14 = or i32 %v13, %v4
+  %v15 = and i32 %seed, 1
+  %v16 = add nuw nsw i32 %v15, 1
+  %v17 = xor i32 %v16, 1
+  %v18 = add nsw i32 %v14, 1
+  %v19 = and i32 %v14, 1
+  %v20 = xor i32 %v18, %v19
+  %v21 = or i32 %v17, %v20
+  %v22 = or i32 %v12, %v21
+  ret i32 %v22
+}
+
+; The splat subtree for %s0/%s1 is trimmed away, but that must not make the
+; revert comparison keep the trimmed alt-shuffle node: the paired arithmetic
+; must still be vectorized.
+
+define void @test2(ptr %out, ptr %in, i64 %n, double %a0, double %a1, double %a2, double %a3, double %a10, double %a11) {
+; CHECK-LABEL: define void @test2(
+; CHECK-SAME: ptr [[OUT:%.*]], ptr [[IN:%.*]], i64 [[N:%.*]], double [[A0:%.*]], double [[A1:%.*]], double [[A2:%.*]], double [[A3:%.*]], double [[A10:%.*]], double [[A11:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT:  [[ENTRY:.*]]:
+; CHECK-NEXT:    br label %[[BODY:.*]]
+; CHECK:       [[BODY]]:
+; CHECK-NEXT:    [[I:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[NEXT:%.*]], %[[BODY]] ]
+; CHECK-NEXT:    [[X0:%.*]] = load double, ptr [[IN]], align 8
+; CHECK-NEXT:    [[P1:%.*]] = getelementptr double, ptr [[IN]], i64 1
+; CHECK-NEXT:    [[X1:%.*]] = load double, ptr [[P1]], align 8
+; CHECK-NEXT:    [[P2:%.*]] = getelementptr double, ptr [[IN]], i64 2
+; CHECK-NEXT:    [[X2:%.*]] = load double, ptr [[P2]], align 8
+; CHECK-NEXT:    [[P3:%.*]] = getelementptr double, ptr [[IN]], i64 3
+; CHECK-NEXT:    [[X3:%.*]] = load double, ptr [[P3]], align 8
+; CHECK-NEXT:    [[S0:%.*]] = fdiv double [[A0]], [[A1]]
+; CHECK-NEXT:    [[S1:%.*]] = fsub double [[A2]], [[A3]]
+; CHECK-NEXT:    [[V0_0:%.*]] = fadd double [[X0]], [[A10]]
+; CHECK-NEXT:    [[V1_0:%.*]] = fsub double [[X1]], [[A11]]
+; CHECK-NEXT:    [[V0_1:%.*]] = fsub double [[V0_0]], [[S1]]
+; CHECK-NEXT:    [[V1_1:%.*]] = fsub double [[V1_0]], [[S1]]
+; CHECK-NEXT:    [[V0_2:%.*]] = fsub double [[V0_1]], [[S0]]
+; CHECK-NEXT:    [[V1_2:%.*]] = fsub double [[V1_1]], [[S0]]
+; CHECK-NEXT:    [[V0_3:%.*]] = fadd double [[V0_2]], [[A10]]
+; CHECK-NEXT:    [[V1_3:%.*]] = fadd double [[V1_2]], [[A11]]
+; CHECK-NEXT:    [[V0_4:%.*]] = fsub double [[V0_3]], [[S0]]
+; CHECK-NEXT:    [[V1_4:%.*]] = fsub double [[V1_3]], [[S0]]
+; CHECK-NEXT:    [[V0_5:%.*]] = fadd double [[V0_4]], [[S0]]
+; CHECK-NEXT:    [[V1_5:%.*]] = fadd double [[V1_4]], [[S0]]
+; CHECK-NEXT:    [[V0_6:%.*]] = fsub double [[V0_5]], [[X2]]
+; CHECK-NEXT:    [[V1_6:%.*]] = fsub double [[V1_5]], [[X3]]
+; CHECK-NEXT:    store double [[V0_6]], ptr [[OUT]], align 8
+; CHECK-NEXT:    [[O1:%.*]] = getelementptr double, ptr [[OUT]], i64 1
+; CHECK-NEXT:    store double [[V1_6]], ptr [[O1]], align 8
+; CHECK-NEXT:    [[NEXT]] = add i64 [[I]], 1
+; CHECK-NEXT:    [[MORE:%.*]] = icmp ult i64 [[NEXT]], [[N]]
+; CHECK-NEXT:    br i1 [[MORE]], label %[[BODY]], label %[[EXIT:.*]]
+; CHECK:       [[EXIT]]:
+; CHECK-NEXT:    ret void
+;
+entry:
+  br label %body
+
+body:
+  %i = phi i64 [ 0, %entry ], [ %next, %body ]
+  %x0 = load double, ptr %in, align 8
+  %p1 = getelementptr double, ptr %in, i64 1
+  %x1 = load double, ptr %p1, align 8
+  %p2 = getelementptr double, ptr %in, i64 2
+  %x2 = load double, ptr %p2, align 8
+  %p3 = getelementptr double, ptr %in, i64 3
+  %x3 = load double, ptr %p3, align 8
+  %s0 = fdiv double %a0, %a1
+  %s1 = fsub double %a2, %a3
+  %v0_0 = fadd double %x0, %a10
+  %v1_0 = fsub double %x1, %a11
+  %v0_1 = fsub double %v0_0, %s1
+  %v1_1 = fsub double %v1_0, %s1
+  %v0_2 = fsub double %v0_1, %s0
+  %v1_2 = fsub double %v1_1, %s0
+  %v0_3 = fadd double %v0_2, %a10
+  %v1_3 = fadd double %v1_2, %a11
+  %v0_4 = fsub double %v0_3, %s0
+  %v1_4 = fsub double %v1_3, %s0
+  %v0_5 = fadd double %v0_4, %s0
+  %v1_5 = fadd double %v1_4, %s0
+  %v0_6 = fsub double %v0_5, %x2
+  %v1_6 = fsub double %v1_5, %x3
+  store double %v0_6, ptr %out, align 8
+  %o1 = getelementptr double, ptr %out, i64 1
+  store double %v1_6, ptr %o1, align 8
+  %next = add i64 %i, 1
+  %more = icmp ult i64 %next, %n
+  br i1 %more, label %body, label %exit
+
+exit:
+  ret void
+}

``````````

</details>


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


More information about the llvm-commits mailing list