[llvm] [VectorCombine] Bail out on all-poison leaves in shuffle transform (PR #206503)
Nikita Popov via llvm-commits
llvm-commits at lists.llvm.org
Mon Jun 29 07:52:28 PDT 2026
https://github.com/nikic created https://github.com/llvm/llvm-project/pull/206503
foldShufflesOfLengthChangingShuffles() skips undef sources when determining Y, so if all the leaves are undef, we can end up with Y being nullptr after the loop. Bail out in this degenerate case.
>From 51f89c85257fcc218995960546f2eca01ee5bcd9 Mon Sep 17 00:00:00 2001
From: Nikita Popov <npopov at redhat.com>
Date: Mon, 29 Jun 2026 16:49:57 +0200
Subject: [PATCH] [VectorCombine] Bail out on all-poison leaves in shuffle
transform
foldShufflesOfLengthChangingShuffles() skips undef sources when
determining Y, so if all the leaves are undef, we can end up with
Y being nullptr after the loop. Bail out in that case.
---
.../lib/Transforms/Vectorize/VectorCombine.cpp | 4 ++++
.../shuffles-of-length-changing-shuffles.ll | 18 ++++++++++++++++++
2 files changed, 22 insertions(+)
diff --git a/llvm/lib/Transforms/Vectorize/VectorCombine.cpp b/llvm/lib/Transforms/Vectorize/VectorCombine.cpp
index c1d4c528a6158..41badb27b3aad 100644
--- a/llvm/lib/Transforms/Vectorize/VectorCombine.cpp
+++ b/llvm/lib/Transforms/Vectorize/VectorCombine.cpp
@@ -3250,6 +3250,10 @@ bool VectorCombine::foldShufflesOfLengthChangingShuffles(Instruction &I) {
if (ChainLength <= 1)
return false;
+ // Bail out if all leaves were poison.
+ if (!Y)
+ return false;
+
if (llvm::all_of(Mask, [&](int M) {
return M < 0 || M >= static_cast<int>(NumTrunkElts);
})) {
diff --git a/llvm/test/Transforms/VectorCombine/AMDGPU/shuffles-of-length-changing-shuffles.ll b/llvm/test/Transforms/VectorCombine/AMDGPU/shuffles-of-length-changing-shuffles.ll
index 3e5a43849cccd..93faba7a7ae36 100644
--- a/llvm/test/Transforms/VectorCombine/AMDGPU/shuffles-of-length-changing-shuffles.ll
+++ b/llvm/test/Transforms/VectorCombine/AMDGPU/shuffles-of-length-changing-shuffles.ll
@@ -44,3 +44,21 @@ define <4 x i8> @shrinking0(<4 x i8> %a, <8 x i8> %b) {
%merge1 = shufflevector <4 x i8> %merge0, <4 x i8> %shrink1, <4 x i32> <i32 0, i32 2, i32 6, i32 7>
ret <4 x i8> %merge1
}
+
+define <4 x i32> @all_poison_leaves(<4 x i32> %a, <4 x i32> %b) {
+; OPT-LABEL: define <4 x i32> @all_poison_leaves(
+; OPT-SAME: <4 x i32> [[A:%.*]], <4 x i32> [[B:%.*]]) #[[ATTR0]] {
+; OPT-NEXT: [[Q:%.*]] = shufflevector <4 x i32> [[A]], <4 x i32> [[B]], <4 x i32> <i32 0, i32 1, i32 4, i32 5>
+; OPT-NEXT: [[L2:%.*]] = shufflevector <2 x i32> poison, <2 x i32> poison, <4 x i32> <i32 0, i32 1, i32 0, i32 1>
+; OPT-NEXT: [[P:%.*]] = shufflevector <4 x i32> [[Q]], <4 x i32> [[L2]], <4 x i32> <i32 0, i32 1, i32 4, i32 5>
+; OPT-NEXT: [[L1:%.*]] = shufflevector <2 x i32> poison, <2 x i32> poison, <4 x i32> <i32 0, i32 1, i32 0, i32 1>
+; OPT-NEXT: [[I:%.*]] = shufflevector <4 x i32> [[P]], <4 x i32> [[L1]], <4 x i32> <i32 0, i32 1, i32 4, i32 5>
+; OPT-NEXT: ret <4 x i32> [[I]]
+;
+ %Q = shufflevector <4 x i32> %a, <4 x i32> %b, <4 x i32> <i32 0, i32 1, i32 4, i32 5>
+ %L2 = shufflevector <2 x i32> poison, <2 x i32> poison, <4 x i32> <i32 0, i32 1, i32 0, i32 1>
+ %P = shufflevector <4 x i32> %Q, <4 x i32> %L2, <4 x i32> <i32 0, i32 1, i32 4, i32 5>
+ %L1 = shufflevector <2 x i32> poison, <2 x i32> poison, <4 x i32> <i32 0, i32 1, i32 0, i32 1>
+ %I = shufflevector <4 x i32> %P, <4 x i32> %L1, <4 x i32> <i32 0, i32 1, i32 4, i32 5>
+ ret <4 x i32> %I
+}
More information about the llvm-commits
mailing list