[llvm] DAG: Canonicalize undef shuffle operands and results to poison (PR #212102)
Matt Arsenault via llvm-commits
llvm-commits at lists.llvm.org
Sun Jul 26 01:17:01 PDT 2026
https://github.com/arsenm created https://github.com/llvm/llvm-project/pull/212102
getVectorShuffle canonicalizes fully-undefined results and unused operands.
Make sure these use poison to avoid degrading poison to undef, defending against
future regressions.
Co-Authored-By: Claude (Claude-Opus-4.8) <noreply at anthropic.com>
>From 6aa57c1b9468b82ec8fbc48f53d006dee853f251 Mon Sep 17 00:00:00 2001
From: Matt Arsenault <Matthew.Arsenault at amd.com>
Date: Sun, 26 Jul 2026 09:55:23 +0200
Subject: [PATCH] DAG: Canonicalize undef shuffle operands and results to
poison
getVectorShuffle canonicalizes fully-undefined results and unused operands.
Make sure these use poison to avoid degrading poison to undef, defending against
future regressions.
Co-Authored-By: Claude (Claude-Opus-4.8) <noreply at anthropic.com>
---
.../lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 26 ++++++++++++-------
.../vector-interleaved-load-i16-stride-5.ll | 4 +--
2 files changed, 18 insertions(+), 12 deletions(-)
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index 679fa3fe36e27..864c735fa478c 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -2258,8 +2258,11 @@ SDValue SelectionDAG::getVectorShuffle(EVT VT, const SDLoc &dl, SDValue N1,
"Invalid VECTOR_SHUFFLE");
// Canonicalize shuffle undef, undef -> undef
- if (N1.isUndef() && N2.isUndef())
+ if (N1.isUndef() && N2.isUndef()) {
+ if (N1.getOpcode() == ISD::POISON && N2.getOpcode() == ISD::POISON)
+ return getPOISON(VT);
return getUNDEF(VT);
+ }
// Validate that all indices in Mask are within the range of the elements
// input to the shuffle.
@@ -2271,9 +2274,9 @@ SDValue SelectionDAG::getVectorShuffle(EVT VT, const SDLoc &dl, SDValue N1,
// Copy the mask so we can do any needed cleanup.
SmallVector<int, 8> MaskVec(Mask);
- // Canonicalize shuffle v, v -> v, undef
+ // Canonicalize shuffle v, v -> v, poison
if (N1 == N2) {
- N2 = getUNDEF(VT);
+ N2 = getPOISON(VT);
for (int i = 0; i != NElts; ++i)
if (MaskVec[i] >= NElts) MaskVec[i] -= NElts;
}
@@ -2312,8 +2315,8 @@ SDValue SelectionDAG::getVectorShuffle(EVT VT, const SDLoc &dl, SDValue N1,
BlendSplat(N2BV, NElts);
}
- // Canonicalize all index into lhs, -> shuffle lhs, undef
- // Canonicalize all index into rhs, -> shuffle rhs, undef
+ // Canonicalize all index into lhs, -> shuffle lhs, poison
+ // Canonicalize all index into rhs, -> shuffle rhs, poison
bool AllLHS = true, AllRHS = true;
bool N2Undef = N2.isUndef();
for (int i = 0; i != NElts; ++i) {
@@ -2327,18 +2330,21 @@ SDValue SelectionDAG::getVectorShuffle(EVT VT, const SDLoc &dl, SDValue N1,
}
}
if (AllLHS && AllRHS)
- return getUNDEF(VT);
+ return getPOISON(VT);
if (AllLHS && !N2Undef)
- N2 = getUNDEF(VT);
+ N2 = getPOISON(VT);
if (AllRHS) {
- N1 = getUNDEF(VT);
+ N1 = getPOISON(VT);
commuteShuffle(N1, N2, MaskVec);
}
// Reset our undef status after accounting for the mask.
N2Undef = N2.isUndef();
// Re-check whether both sides ended up undef.
- if (N1.isUndef() && N2Undef)
+ if (N1.isUndef() && N2Undef) {
+ if (N1.getOpcode() == ISD::POISON && N2.getOpcode() == ISD::POISON)
+ return getPOISON(VT);
return getUNDEF(VT);
+ }
// If Identity shuffle return that node.
bool Identity = true, AllSame = true;
@@ -2364,7 +2370,7 @@ SDValue SelectionDAG::getVectorShuffle(EVT VT, const SDLoc &dl, SDValue N1,
SDValue Splat = BV->getSplatValue(&UndefElements);
// If this is a splat of an undef, shuffling it is also undef.
if (Splat && Splat.isUndef())
- return getUNDEF(VT);
+ return Splat.getOpcode() == ISD::POISON ? getPOISON(VT) : getUNDEF(VT);
bool SameNumElts =
V.getValueType().getVectorNumElements() == VT.getVectorNumElements();
diff --git a/llvm/test/CodeGen/X86/vector-interleaved-load-i16-stride-5.ll b/llvm/test/CodeGen/X86/vector-interleaved-load-i16-stride-5.ll
index 26769278148f9..5d7627d42d67a 100644
--- a/llvm/test/CodeGen/X86/vector-interleaved-load-i16-stride-5.ll
+++ b/llvm/test/CodeGen/X86/vector-interleaved-load-i16-stride-5.ll
@@ -8368,7 +8368,7 @@ define void @load_i16_stride5_vf64(ptr %in.vec, ptr %out.vec0, ptr %out.vec1, pt
; AVX512-FCP-LABEL: load_i16_stride5_vf64:
; AVX512-FCP: # %bb.0:
; AVX512-FCP-NEXT: subq $648, %rsp # imm = 0x288
-; AVX512-FCP-NEXT: vmovdqa {{.*#+}} xmm0 = [4,5,14,15,4,5,6,7,8,9,10,11,12,13,14,15]
+; AVX512-FCP-NEXT: vmovq {{.*#+}} xmm0 = [4,5,14,15,4,5,6,7,0,0,0,0,0,0,0,0]
; AVX512-FCP-NEXT: vmovdqa 496(%rdi), %xmm1
; AVX512-FCP-NEXT: vpshufb %xmm0, %xmm1, %xmm2
; AVX512-FCP-NEXT: vmovdqa64 %xmm1, %xmm31
@@ -9272,7 +9272,7 @@ define void @load_i16_stride5_vf64(ptr %in.vec, ptr %out.vec0, ptr %out.vec1, pt
; AVX512DQ-FCP-LABEL: load_i16_stride5_vf64:
; AVX512DQ-FCP: # %bb.0:
; AVX512DQ-FCP-NEXT: subq $648, %rsp # imm = 0x288
-; AVX512DQ-FCP-NEXT: vmovdqa {{.*#+}} xmm0 = [4,5,14,15,4,5,6,7,8,9,10,11,12,13,14,15]
+; AVX512DQ-FCP-NEXT: vmovq {{.*#+}} xmm0 = [4,5,14,15,4,5,6,7,0,0,0,0,0,0,0,0]
; AVX512DQ-FCP-NEXT: vmovdqa 496(%rdi), %xmm1
; AVX512DQ-FCP-NEXT: vpshufb %xmm0, %xmm1, %xmm2
; AVX512DQ-FCP-NEXT: vmovdqa64 %xmm1, %xmm31
More information about the llvm-commits
mailing list