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 +} _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
