[llvm] [SLP]Extract vectorized source of gathered sub-fields (PR #226437)
Alexey Bataev via llvm-commits
llvm-commits at lists.llvm.org
Fri Sep 25 04:06:15 PDT 2026
https://github.com/alexey-bataev created https://github.com/llvm/llvm-project/pull/226437
The bitcast emitted for gathered sub-fields used the source scalar
directly, even if it was vectorized and erased, causes the crash,
register the bitcast as an external user of the vectorized source.
Fixes the crash reported in #224919.
>From f729b9a4b5c06211912bf57d2d07779449ced04d Mon Sep 17 00:00:00 2001
From: Alexey Bataev <a.bataev at outlook.com>
Date: Fri, 25 Sep 2026 04:06:01 -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 | 8 ++++
.../SLPVectorizer/X86/extracted-subfields.ll | 38 +++++++++++++++++++
2 files changed, 46 insertions(+)
diff --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
index b76cf0677c2f6e..9179562e6dbf33 100644
--- a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
+++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
@@ -22583,6 +22583,14 @@ class BoUpSLP::ShuffleInstructionBuilder final : public BaseShuffleAnalysis {
if (auto *I = dyn_cast<Instruction>(Vec)) {
R.GatherShuffleExtractSeq.insert(I);
R.CSEBlocks.insert(I->getParent());
+ // A vectorized source scalar is erased; extract it for the bitcast.
+ ArrayRef<TreeEntry *> TEs = R.getTreeEntries(Src);
+ const auto *It = find_if_not(TEs, [&](const TreeEntry *TE) {
+ return R.TransformedToGatherNodes.contains(TE) ||
+ R.DeletedNodes.contains(TE);
+ });
+ if (It != TEs.end())
+ R.ExternalUses.emplace_back(Src, I, **It, (*It)->findLaneForValue(Src));
}
Vec = createShuffle(Vec, /*V2=*/nullptr, Mask);
// The extracted fields are unsigned.
diff --git a/llvm/test/Transforms/SLPVectorizer/X86/extracted-subfields.ll b/llvm/test/Transforms/SLPVectorizer/X86/extracted-subfields.ll
index e10b2f18998487..1c43215b77d1bd 100644
--- a/llvm/test/Transforms/SLPVectorizer/X86/extracted-subfields.ll
+++ b/llvm/test/Transforms/SLPVectorizer/X86/extracted-subfields.ll
@@ -388,3 +388,41 @@ start:
store i16 %b3, ptr %out, align 2
ret i16 %a7
}
+
+define void @vectorized_src(ptr %p, ptr %a, i64 %x) {
+; CHECK-LABEL: define void @vectorized_src(
+; CHECK-SAME: ptr [[P:%.*]], ptr [[A:%.*]], i64 [[X:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8
+; CHECK-NEXT: [[TMP0:%.*]] = load <2 x i64>, ptr [[P]], align 8
+; CHECK-NEXT: [[LD1:%.*]] = load i64, ptr [[GEP]], align 8
+; CHECK-NEXT: [[TMP1:%.*]] = bitcast i64 [[LD1]] to <2 x i32>
+; CHECK-NEXT: [[TMP2:%.*]] = sitofp <2 x i32> [[TMP1]] to <2 x double>
+; CHECK-NEXT: [[TMP3:%.*]] = trunc <2 x i64> [[TMP0]] to <2 x i32>
+; CHECK-NEXT: [[TMP4:%.*]] = trunc i64 [[X]] to i32
+; CHECK-NEXT: [[TMP5:%.*]] = insertelement <2 x i32> [[TMP3]], i32 [[TMP4]], i64 1
+; CHECK-NEXT: [[TMP6:%.*]] = sitofp <2 x i32> [[TMP5]] to <2 x double>
+; CHECK-NEXT: [[TMP7:%.*]] = fsub <2 x double> [[TMP2]], [[TMP6]]
+; CHECK-NEXT: store <2 x double> [[TMP7]], ptr [[A]], align 8
+; CHECK-NEXT: ret void
+;
+entry:
+ %ld0 = load i64, ptr %p, align 8
+ %gep = getelementptr inbounds nuw i8, ptr %p, i64 8
+ %ld1 = load i64, ptr %gep, align 8
+ %t0 = trunc i64 %ld1 to i32
+ %c0 = sitofp i32 %t0 to double
+ %t1 = trunc i64 %ld0 to i32
+ %c1 = sitofp i32 %t1 to double
+ %sub0 = fsub double %c0, %c1
+ store double %sub0, ptr %a, align 8
+ %s = lshr i64 %ld1, 32
+ %t2 = trunc nuw i64 %s to i32
+ %c2 = sitofp i32 %t2 to double
+ %t3 = trunc i64 %x to i32
+ %c3 = sitofp i32 %t3 to double
+ %sub1 = fsub double %c2, %c3
+ %gep.a = getelementptr inbounds nuw i8, ptr %a, i64 8
+ store double %sub1, ptr %gep.a, align 8
+ ret void
+}
More information about the llvm-commits
mailing list