[llvm] [SLP]Fix crash on deleted main op of copyable state in reductions (PR #228806)
Alexey Bataev via llvm-commits
llvm-commits at lists.llvm.org
Sat Oct 3 18:48:37 PDT 2026
https://github.com/alexey-bataev created https://github.com/llvm/llvm-project/pull/228806
Vectorizing one group of reduced values can erase the main operation of
a later group's copyable state, leaving it with dropped operands.
Fixes #228768
>From b50be892a7f85a91da8fab65589b39c1eaf6e884 Mon Sep 17 00:00:00 2001
From: Alexey Bataev <a.bataev at outlook.com>
Date: Sat, 3 Oct 2026 18:48:25 -0700
Subject: [PATCH] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20initia?=
=?UTF-8?q?l=20version?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Created using spr 1.3.7
---
.../Transforms/Vectorize/SLPVectorizer.cpp | 5 ++
.../reduction-erased-copyable-cast-main-op.ll | 56 +++++++++++++++++++
2 files changed, 61 insertions(+)
create mode 100644 llvm/test/Transforms/SLPVectorizer/X86/reduction-erased-copyable-cast-main-op.ll
diff --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
index 0981c124e3aec..a03dfe49a85f1 100644
--- a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
+++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
@@ -32679,6 +32679,11 @@ class HorizontalReduction {
for (unsigned I = 0, E = ReducedVals.size(); I < E; ++I) {
ArrayRef<Value *> OrigReducedVals = ReducedVals[I];
InstructionsState S = States[I];
+ // The main operation of a state with copyable elements may be deleted
+ // during previous vectorization attempts, the state is not usable then.
+ if (S && S.areInstructionsWithCopyableElements() &&
+ V.isDeleted(S.getMainOp()))
+ S = InstructionsState::invalid();
SmallVector<Value *> Candidates;
Candidates.reserve(2 * OrigReducedVals.size());
SmallVector<Value *> TrackedToOrig;
diff --git a/llvm/test/Transforms/SLPVectorizer/X86/reduction-erased-copyable-cast-main-op.ll b/llvm/test/Transforms/SLPVectorizer/X86/reduction-erased-copyable-cast-main-op.ll
new file mode 100644
index 0000000000000..ccc7f41977635
--- /dev/null
+++ b/llvm/test/Transforms/SLPVectorizer/X86/reduction-erased-copyable-cast-main-op.ll
@@ -0,0 +1,56 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
+; RUN: opt -S -passes=slp-vectorizer -mtriple=x86_64-unknown-linux-gnu < %s | FileCheck %s
+
+; The tree of the reduced ands erases the reduced zexts, including the main
+; operation of the zext group with a copyable constant.
+define i64 @test(ptr %p) {
+; CHECK-LABEL: define i64 @test(
+; CHECK-SAME: ptr [[P:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[V:%.*]] = load i8, ptr [[P]], align 1
+; CHECK-NEXT: [[TMP0:%.*]] = insertelement <4 x i8> poison, i8 [[V]], i64 0
+; CHECK-NEXT: [[TMP1:%.*]] = shufflevector <4 x i8> [[TMP0]], <4 x i8> poison, <4 x i32> zeroinitializer
+; CHECK-NEXT: [[TMP2:%.*]] = and <4 x i8> [[TMP1]], <i8 1, i8 -1, i8 -1, i8 -1>
+; CHECK-NEXT: [[TMP3:%.*]] = extractelement <4 x i8> [[TMP2]], i64 0
+; CHECK-NEXT: [[TMP4:%.*]] = zext i8 [[TMP3]] to i64
+; CHECK-NEXT: [[Z2:%.*]] = zext i8 [[V]] to i64
+; CHECK-NEXT: [[TMP5:%.*]] = mul <4 x i8> [[TMP2]], <i8 7, i8 7, i8 7, i8 1>
+; CHECK-NEXT: [[TMP6:%.*]] = and <4 x i8> [[TMP5]], <i8 5, i8 5, i8 5, i8 -1>
+; CHECK-NEXT: [[TMP7:%.*]] = zext <4 x i8> [[TMP6]] to <4 x i64>
+; CHECK-NEXT: [[TMP8:%.*]] = mul <4 x i64> [[TMP7]], <i64 3, i64 2, i64 2, i64 3>
+; CHECK-NEXT: [[TMP9:%.*]] = call i64 @llvm.vector.reduce.add.v4i64(<4 x i64> [[TMP8]])
+; CHECK-NEXT: [[TMP10:%.*]] = mul i64 [[TMP4]], 2
+; CHECK-NEXT: [[TMP11:%.*]] = mul i64 [[Z2]], 2
+; CHECK-NEXT: [[OP_RDX5:%.*]] = add i64 [[TMP10]], [[TMP11]]
+; CHECK-NEXT: [[OP_RDX6:%.*]] = add i64 [[OP_RDX5]], 1
+; CHECK-NEXT: [[OP_RDX7:%.*]] = add i64 [[OP_RDX6]], [[TMP9]]
+; CHECK-NEXT: ret i64 [[OP_RDX7]]
+;
+entry:
+ %v = load i8, ptr %p, align 1
+ %m = and i8 %v, 1
+ %z0 = zext i8 %m to i64
+ %mul0 = mul i64 %z0, 7
+ %a0 = and i64 %mul0, 5
+ %s0 = add i64 %a0, 1
+ %z1 = zext i8 %v to i64
+ %s1 = add i64 %s0, %z1
+ %z2 = zext i8 %v to i64
+ %s2 = add i64 %s1, %z2
+ %mul2 = mul i64 %z2, 7
+ %a2 = and i64 %mul2, 5
+ %s3 = add i64 %s2, %a2
+ %s4 = add i64 %s3, %z0
+ %s5 = add i64 %s4, %a0
+ %s6 = add i64 %s5, %z1
+ %mul1 = mul i64 %z1, 7
+ %a1 = and i64 %mul1, 5
+ %s7 = add i64 %s6, %a1
+ %s8 = add i64 %s7, %z2
+ %s9 = add i64 %s8, %a2
+ %s10 = add i64 %s9, %z0
+ %s11 = add i64 %s10, %a0
+ %s12 = add i64 %s11, %z1
+ %s13 = add i64 %s12, %a1
+ ret i64 %s13
+}
More information about the llvm-commits
mailing list