[llvm-branch-commits] [llvm] 8eddfe6 - [SLP] Only consider BuildVector inserts into the same object. (#212269)
Tobias Hieta via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Tue Jul 28 02:43:55 PDT 2026
Author: Florian Hahn
Date: 2026-07-28T11:43:45+02:00
New Revision: 8eddfe681bae133c1c396220638abd9636c171e1
URL: https://github.com/llvm/llvm-project/commit/8eddfe681bae133c1c396220638abd9636c171e1
DIFF: https://github.com/llvm/llvm-project/commit/8eddfe681bae133c1c396220638abd9636c171e1.diff
LOG: [SLP] Only consider BuildVector inserts into the same object. (#212269)
When following insertelement instruction for a BuildVector sequence, we
may discover a user that inserts into a different vector.
Bail out when that happens instead of crashing.
PR: https://github.com/llvm/llvm-project/pull/212269
(cherry picked from commit 07aa3b710f2622f662cab7a53ddf1288c725a9be)
Added:
llvm/test/Transforms/SLPVectorizer/AArch64/buildvector-used-by-insertvalue.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 7e22ba3bd149c..80091308116f7 100644
--- a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
+++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
@@ -23694,6 +23694,7 @@ Value *BoUpSLP::vectorizeTree(TreeEntry *E) {
// Follow all insert element instructions from the current buildvector
// sequence.
Instruction *Ins = VL0;
+ Instruction *Op;
do {
std::optional<unsigned> InsertIdx = getElementIndex(Ins);
if (!InsertIdx)
@@ -23702,9 +23703,10 @@ Value *BoUpSLP::vectorizeTree(TreeEntry *E) {
InsertMask[*InsertIdx] = *InsertIdx;
if (!Ins->hasOneUse())
break;
+ Op = Ins;
Ins =
dyn_cast_or_null<Instruction>(Ins->getUniqueUndroppableUser());
- } while (Ins);
+ } while (Ins && Ins->getOperand(0) == Op);
SmallBitVector UseMask =
buildUseMask(NumElts, InsertMask, UseMask::UndefsAsMask);
SmallBitVector IsFirstPoison =
diff --git a/llvm/test/Transforms/SLPVectorizer/AArch64/buildvector-used-by-insertvalue.ll b/llvm/test/Transforms/SLPVectorizer/AArch64/buildvector-used-by-insertvalue.ll
new file mode 100644
index 0000000000000..ac7dd2c00e8a7
--- /dev/null
+++ b/llvm/test/Transforms/SLPVectorizer/AArch64/buildvector-used-by-insertvalue.ll
@@ -0,0 +1,59 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
+; RUN: opt -passes=slp-vectorizer -S %s | FileCheck %s
+
+target triple = "aarch64-unknown-linux-gnu"
+
+%struct.f4x3 = type { [4 x <3 x float>] }
+
+; The buildvector for <3 x float> is consumed by an insertvalue that places it
+; at aggregate index 3.
+define %struct.f4x3 @buildvector_used_by_insertvalue(ptr %p, float %c) {
+; CHECK-LABEL: define %struct.f4x3 @buildvector_used_by_insertvalue(
+; CHECK-SAME: ptr [[P:%.*]], float [[C:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[TMP0:%.*]] = load <2 x double>, ptr [[P]], align 8
+; CHECK-NEXT: [[TMP1:%.*]] = fptrunc <2 x double> [[TMP0]] to <2 x float>
+; CHECK-NEXT: [[TMP2:%.*]] = shufflevector <2 x float> [[TMP1]], <2 x float> poison, <3 x i32> <i32 0, i32 1, i32 poison>
+; CHECK-NEXT: [[INS_11:%.*]] = shufflevector <3 x float> zeroinitializer, <3 x float> [[TMP2]], <3 x i32> <i32 3, i32 4, i32 2>
+; CHECK-NEXT: [[INS_2:%.*]] = insertelement <3 x float> [[INS_11]], float [[C]], i32 0
+; CHECK-NEXT: [[RES:%.*]] = insertvalue [[STRUCT_F4X3:%.*]] zeroinitializer, <3 x float> [[INS_2]], 0, 3
+; CHECK-NEXT: ret [[STRUCT_F4X3]] [[RES]]
+;
+entry:
+ %p.1 = getelementptr inbounds i8, ptr %p, i64 8
+ %l.0 = load double, ptr %p, align 8
+ %l.1 = load double, ptr %p.1, align 8
+ %conv.0 = fptrunc double %l.0 to float
+ %ins.0 = insertelement <3 x float> zeroinitializer, float %conv.0, i32 0
+ %conv.1 = fptrunc double %l.1 to float
+ %ins.1 = insertelement <3 x float> %ins.0, float %conv.1, i32 1
+ %ins.2 = insertelement <3 x float> %ins.1, float %c, i32 0
+ %res = insertvalue %struct.f4x3 zeroinitializer, <3 x float> %ins.2, 0, 3
+ ret %struct.f4x3 %res
+}
+
+; Same buildvector, but stored instead of placed into an aggregate.
+define void @buildvector_used_by_store(ptr %p, float %c, ptr %q) {
+; CHECK-LABEL: define void @buildvector_used_by_store(
+; CHECK-SAME: ptr [[P:%.*]], float [[C:%.*]], ptr [[Q:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[TMP0:%.*]] = load <2 x double>, ptr [[P]], align 8
+; CHECK-NEXT: [[TMP1:%.*]] = fptrunc <2 x double> [[TMP0]] to <2 x float>
+; CHECK-NEXT: [[TMP2:%.*]] = shufflevector <2 x float> [[TMP1]], <2 x float> poison, <3 x i32> <i32 0, i32 1, i32 poison>
+; CHECK-NEXT: [[INS_11:%.*]] = shufflevector <3 x float> zeroinitializer, <3 x float> [[TMP2]], <3 x i32> <i32 3, i32 4, i32 2>
+; CHECK-NEXT: [[INS_2:%.*]] = insertelement <3 x float> [[INS_11]], float [[C]], i32 0
+; CHECK-NEXT: store <3 x float> [[INS_2]], ptr [[Q]], align 16
+; CHECK-NEXT: ret void
+;
+entry:
+ %p.1 = getelementptr inbounds i8, ptr %p, i64 8
+ %l.0 = load double, ptr %p, align 8
+ %l.1 = load double, ptr %p.1, align 8
+ %conv.0 = fptrunc double %l.0 to float
+ %ins.0 = insertelement <3 x float> zeroinitializer, float %conv.0, i32 0
+ %conv.1 = fptrunc double %l.1 to float
+ %ins.1 = insertelement <3 x float> %ins.0, float %conv.1, i32 1
+ %ins.2 = insertelement <3 x float> %ins.1, float %c, i32 0
+ store <3 x float> %ins.2, ptr %q, align 16
+ ret void
+}
More information about the llvm-branch-commits
mailing list