[llvm-branch-commits] [llvm] 6dfe167 - [SLP]Fix crash in canBuildSplitNode on struct-typed scalars
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Tue Sep 8 02:20:13 PDT 2026
Author: Alexey Bataev
Date: 2026-09-07T13:01:29Z
New Revision: 6dfe1677ab8dffbc6ec13d53a1e0215d75147689
URL: https://github.com/llvm/llvm-project/commit/6dfe1677ab8dffbc6ec13d53a1e0215d75147689
DIFF: https://github.com/llvm/llvm-project/commit/6dfe1677ab8dffbc6ec13d53a1e0215d75147689.diff
LOG: [SLP]Fix crash in canBuildSplitNode on struct-typed scalars
Split nodes require plain vector types for the cost model and codegen,
but getWidenedType on a struct scalar type returns a struct-of-vectors,
so the cast<VectorType> asserted. Bail out on struct-typed scalars, they
are not supported.
Fixes #221715
Reviewers:
Pull Request: https://github.com/llvm/llvm-project/pull/221721
(cherry picked from commit 42b846980eeacd8052d7a463e1aea8bb91aff248)
Added:
llvm/test/Transforms/SLPVectorizer/X86/split-node-struct-type.ll
Modified:
llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
index 3cba5769e0047..0c4d92085029f 100644
--- a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
+++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
@@ -11753,6 +11753,9 @@ bool BoUpSLP::canBuildSplitNode(ArrayRef<Value *> VL,
if (VL.size() <= SmallNodeSize || TTI->preferAlternateOpcodeVectorization() ||
!SplitAlternateInstructions)
return false;
+ // Split vectorization of struct types is not supported.
+ if (isa<StructType>(getValueType(VL.front(), SLPReVec)))
+ return false;
// Check if this is a duplicate of another split entry.
LLVM_DEBUG(dbgs() << "SLP: \tChecking bundle: " << *LocalState.getMainOp()
diff --git a/llvm/test/Transforms/SLPVectorizer/X86/split-node-struct-type.ll b/llvm/test/Transforms/SLPVectorizer/X86/split-node-struct-type.ll
new file mode 100644
index 0000000000000..8f9f8500b7208
--- /dev/null
+++ b/llvm/test/Transforms/SLPVectorizer/X86/split-node-struct-type.ll
@@ -0,0 +1,67 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
+; RUN: opt -S --passes=slp-vectorizer -mtriple=x86_64-unknown-linux-gnu < %s | FileCheck %s
+
+declare { ptr, i64 } @foo()
+
+define { ptr, i64 } @test({ ptr, i64 } %arg, ptr %p) {
+; CHECK-LABEL: define { ptr, i64 } @test(
+; CHECK-SAME: { ptr, i64 } [[ARG:%.*]], ptr [[P:%.*]]) {
+; CHECK-NEXT: [[BBL:.*:]]
+; CHECK-NEXT: br i1 false, label %[[BBL8:.*]], label %[[BBL1:.*]]
+; CHECK: [[BBL1]]:
+; CHECK-NEXT: [[INSERTVALUE:%.*]] = insertvalue { ptr, i64 } zeroinitializer, i64 0, 1
+; CHECK-NEXT: [[INSERTVALUE2:%.*]] = insertvalue { ptr, i64 } zeroinitializer, i64 0, 1
+; CHECK-NEXT: [[INSERTVALUE3:%.*]] = insertvalue { ptr, i64 } zeroinitializer, i64 0, 1
+; CHECK-NEXT: [[INSERTVALUE4:%.*]] = insertvalue { ptr, i64 } zeroinitializer, i64 0, 1
+; CHECK-NEXT: [[INSERTVALUE5:%.*]] = insertvalue { ptr, i64 } zeroinitializer, i64 0, 1
+; CHECK-NEXT: [[CALL:%.*]] = call { ptr, i64 } @foo()
+; CHECK-NEXT: [[CALL6:%.*]] = call { ptr, i64 } @foo()
+; CHECK-NEXT: [[CALL7:%.*]] = call { ptr, i64 } @foo()
+; CHECK-NEXT: br label %[[BBL11:.*]]
+; CHECK: [[BBL8]]:
+; CHECK-NEXT: [[LOAD:%.*]] = load volatile { ptr, i64 }, ptr [[P]], align 8
+; CHECK-NEXT: [[LOAD9:%.*]] = load { ptr, i64 }, ptr [[P]], align 8
+; CHECK-NEXT: [[LOAD10:%.*]] = load { ptr, i64 }, ptr [[P]], align 8
+; CHECK-NEXT: br label %[[BBL11]]
+; CHECK: [[BBL11]]:
+; CHECK-NEXT: [[PHI:%.*]] = phi { ptr, i64 } [ [[CALL6]], %[[BBL1]] ], [ zeroinitializer, %[[BBL8]] ]
+; CHECK-NEXT: [[PHI12:%.*]] = phi { ptr, i64 } [ [[INSERTVALUE5]], %[[BBL1]] ], [ zeroinitializer, %[[BBL8]] ]
+; CHECK-NEXT: [[PHI13:%.*]] = phi { ptr, i64 } [ [[INSERTVALUE3]], %[[BBL1]] ], [ [[LOAD9]], %[[BBL8]] ]
+; CHECK-NEXT: [[PHI14:%.*]] = phi { ptr, i64 } [ [[INSERTVALUE]], %[[BBL1]] ], [ [[ARG]], %[[BBL8]] ]
+; CHECK-NEXT: [[PHI15:%.*]] = phi { ptr, i64 } [ [[INSERTVALUE2]], %[[BBL1]] ], [ [[LOAD]], %[[BBL8]] ]
+; CHECK-NEXT: [[PHI16:%.*]] = phi { ptr, i64 } [ [[INSERTVALUE4]], %[[BBL1]] ], [ [[LOAD10]], %[[BBL8]] ]
+; CHECK-NEXT: [[PHI17:%.*]] = phi { ptr, i64 } [ [[CALL]], %[[BBL1]] ], [ zeroinitializer, %[[BBL8]] ]
+; CHECK-NEXT: [[PHI18:%.*]] = phi { ptr, i64 } [ [[CALL7]], %[[BBL1]] ], [ zeroinitializer, %[[BBL8]] ]
+; CHECK-NEXT: ret { ptr, i64 } [[PHI18]]
+;
+bbl:
+ br i1 false, label %bbl8, label %bbl1
+
+bbl1:
+ %insertvalue = insertvalue { ptr, i64 } zeroinitializer, i64 0, 1
+ %insertvalue2 = insertvalue { ptr, i64 } zeroinitializer, i64 0, 1
+ %insertvalue3 = insertvalue { ptr, i64 } zeroinitializer, i64 0, 1
+ %insertvalue4 = insertvalue { ptr, i64 } zeroinitializer, i64 0, 1
+ %insertvalue5 = insertvalue { ptr, i64 } zeroinitializer, i64 0, 1
+ %call = call { ptr, i64 } @foo()
+ %call6 = call { ptr, i64 } @foo()
+ %call7 = call { ptr, i64 } @foo()
+ br label %bbl11
+
+bbl8:
+ %load = load volatile { ptr, i64 }, ptr %p, align 8
+ %load9 = load { ptr, i64 }, ptr %p, align 8
+ %load10 = load { ptr, i64 }, ptr %p, align 8
+ br label %bbl11
+
+bbl11:
+ %phi = phi { ptr, i64 } [ %call6, %bbl1 ], [ zeroinitializer, %bbl8 ]
+ %phi12 = phi { ptr, i64 } [ %insertvalue5, %bbl1 ], [ zeroinitializer, %bbl8 ]
+ %phi13 = phi { ptr, i64 } [ %insertvalue3, %bbl1 ], [ %load9, %bbl8 ]
+ %phi14 = phi { ptr, i64 } [ %insertvalue, %bbl1 ], [ %arg, %bbl8 ]
+ %phi15 = phi { ptr, i64 } [ %insertvalue2, %bbl1 ], [ %load, %bbl8 ]
+ %phi16 = phi { ptr, i64 } [ %insertvalue4, %bbl1 ], [ %load10, %bbl8 ]
+ %phi17 = phi { ptr, i64 } [ %call, %bbl1 ], [ zeroinitializer, %bbl8 ]
+ %phi18 = phi { ptr, i64 } [ %call7, %bbl1 ], [ zeroinitializer, %bbl8 ]
+ ret { ptr, i64 } %phi18
+}
More information about the llvm-branch-commits
mailing list