[llvm] [X86] LowerAVXCONCAT_VECTORS - collect all subvector operands before ReplaceAllUsesWith call (PR #218381)
Simon Pilgrim via llvm-commits
llvm-commits at lists.llvm.org
Mon Aug 24 04:51:28 PDT 2026
https://github.com/RKSimon created https://github.com/llvm/llvm-project/pull/218381
We can end up referencing a node replaced with ISD::DELETED_NODE
Fixes #218379
>From ac28e4e2c41ffce2aad0827d42cb9a39aa1910d0 Mon Sep 17 00:00:00 2001
From: Simon Pilgrim <llvm-dev at redking.me.uk>
Date: Mon, 24 Aug 2026 12:49:34 +0100
Subject: [PATCH] [X86] LowerAVXCONCAT_VECTORS - collect all subvector operands
before ReplaceAllUsesWith call
We can end up referencing a node replaced with ISD::DELETED_NODE
Fixes #218379
---
llvm/lib/Target/X86/X86ISelLowering.cpp | 46 +++++++++----------
.../X86/vector-shuffle-combining-avx512f.ll | 43 +++++++++++++++++
2 files changed, 64 insertions(+), 25 deletions(-)
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index a0c92a22b7e2f..2d699adb4020d 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -9879,30 +9879,31 @@ static SDValue LowerAVXCONCAT_VECTORS(SDValue Op, const SDLoc &dl,
assert((ResVT.is256BitVector() || ResVT.is512BitVector()) &&
"Value type must be 256-/512-bit wide");
+ SmallVector<SDValue, 4> Ops(Op->ops());
+ MVT SubVT = Ops[0].getSimpleValueType();
unsigned NumOperands = Op.getNumOperands();
+
unsigned NumFreezeUndef = 0;
unsigned NumZero = 0;
unsigned NumNonZero = 0;
unsigned NonZeros = 0;
SmallSet<SDValue, 4> Undefs;
- for (unsigned i = 0; i != NumOperands; ++i) {
- SDValue SubVec = Op.getOperand(i);
+ for (auto [I, SubVec] : enumerate(Ops)) {
if (SubVec.isUndef())
continue;
if (ISD::isFreezeUndef(SubVec.getNode())) {
- // If the freeze(undef) has multiple uses then we must fold to zero.
- if (SubVec.hasOneUse()) {
- ++NumFreezeUndef;
- } else {
- ++NumZero;
- Undefs.insert(SubVec);
- }
- }
- else if (ISD::isBuildVectorAllZeros(SubVec.getNode()))
+ // If the freeze(undef) has multiple uses then we must fold to zero.
+ if (SubVec.hasOneUse()) {
+ ++NumFreezeUndef;
+ } else {
+ ++NumZero;
+ Undefs.insert(SubVec);
+ }
+ } else if (ISD::isBuildVectorAllZeros(SubVec.getNode())) {
++NumZero;
- else {
- assert(i < sizeof(NonZeros) * CHAR_BIT); // Ensure the shift is in range.
- NonZeros |= 1 << i;
+ } else {
+ assert(I < sizeof(NonZeros) * CHAR_BIT); // Ensure the shift is in range.
+ NonZeros |= 1 << I;
++NumNonZero;
}
}
@@ -9910,11 +9911,10 @@ static SDValue LowerAVXCONCAT_VECTORS(SDValue Op, const SDLoc &dl,
// If we have more than 2 non-zeros, build each half separately.
if (NumNonZero > 2) {
MVT HalfVT = ResVT.getHalfNumVectorElementsVT();
- ArrayRef<SDUse> Ops = Op->ops();
SDValue Lo = DAG.getNode(ISD::CONCAT_VECTORS, dl, HalfVT,
- Ops.slice(0, NumOperands/2));
+ ArrayRef<SDValue>(Ops).slice(0, NumOperands / 2));
SDValue Hi = DAG.getNode(ISD::CONCAT_VECTORS, dl, HalfVT,
- Ops.slice(NumOperands/2));
+ ArrayRef<SDValue>(Ops).slice(NumOperands / 2));
return DAG.getNode(ISD::CONCAT_VECTORS, dl, ResVT, Lo, Hi);
}
@@ -9925,17 +9925,13 @@ static SDValue LowerAVXCONCAT_VECTORS(SDValue Op, const SDLoc &dl,
// Replace Undef operands with ZeroVector.
for (SDValue U : Undefs)
- DAG.ReplaceAllUsesWith(
- U, getZeroVector(U.getSimpleValueType(), Subtarget, DAG, dl));
+ DAG.ReplaceAllUsesWith(U, getZeroVector(SubVT, Subtarget, DAG, dl));
- MVT SubVT = Op.getOperand(0).getSimpleValueType();
unsigned NumSubElems = SubVT.getVectorNumElements();
- for (unsigned i = 0; i != NumOperands; ++i) {
- if ((NonZeros & (1 << i)) == 0)
+ for (auto [I, SubVec] : enumerate(Ops)) {
+ if ((NonZeros & (1 << I)) == 0)
continue;
-
- Vec = DAG.getNode(ISD::INSERT_SUBVECTOR, dl, ResVT, Vec, Op.getOperand(i),
- DAG.getVectorIdxConstant(i * NumSubElems, dl));
+ Vec = DAG.getInsertSubvector(dl, Vec, SubVec, I * NumSubElems);
}
return Vec;
diff --git a/llvm/test/CodeGen/X86/vector-shuffle-combining-avx512f.ll b/llvm/test/CodeGen/X86/vector-shuffle-combining-avx512f.ll
index 3a83f04526ac5..ae6fa4298ddec 100644
--- a/llvm/test/CodeGen/X86/vector-shuffle-combining-avx512f.ll
+++ b/llvm/test/CodeGen/X86/vector-shuffle-combining-avx512f.ll
@@ -1194,3 +1194,46 @@ define <8 x i64> @PR179008(ptr %p0) {
%shuf = shufflevector <8 x i64> %load, <8 x i64> <i64 poison, i64 poison, i64 poison, i64 poison, i64 poison, i64 0, i64 0, i64 0>, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 13, i32 14, i32 15>
ret <8 x i64> %shuf
}
+
+define <16 x float> @PR218379(ptr %p0, ptr %p1) nounwind {
+; X86-LABEL: PR218379:
+; X86: # %bb.0:
+; X86-NEXT: pushl %edi
+; X86-NEXT: pushl %esi
+; X86-NEXT: movl {{[0-9]+}}(%esp), %esi
+; X86-NEXT: movl {{[0-9]+}}(%esp), %edi
+; X86-NEXT: calll 0
+; X86-NEXT: vmovaps %ymm0, %ymm0
+; X86-NEXT: vmovaps %zmm0, (%edi)
+; X86-NEXT: vmovaps %zmm0, (%esi)
+; X86-NEXT: vxorps %xmm0, %xmm0, %xmm0
+; X86-NEXT: popl %esi
+; X86-NEXT: popl %edi
+; X86-NEXT: retl
+;
+; X64-LABEL: PR218379:
+; X64: # %bb.0:
+; X64-NEXT: pushq %r14
+; X64-NEXT: pushq %rbx
+; X64-NEXT: pushq %rax
+; X64-NEXT: movq %rsi, %rbx
+; X64-NEXT: movq %rdi, %r14
+; X64-NEXT: xorl %eax, %eax
+; X64-NEXT: callq *%rax
+; X64-NEXT: vmovaps %ymm0, %ymm0
+; X64-NEXT: vmovaps %zmm0, (%r14)
+; X64-NEXT: vmovaps %zmm0, (%rbx)
+; X64-NEXT: vxorps %xmm0, %xmm0, %xmm0
+; X64-NEXT: addq $8, %rsp
+; X64-NEXT: popq %rbx
+; X64-NEXT: popq %r14
+; X64-NEXT: retq
+ %call = call <8 x float> null()
+ %fr = freeze <8 x float> poison
+ %shuffle = shufflevector <8 x float> %call, <8 x float> %fr, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
+ store <16 x float> %shuffle, ptr %p0
+ %shuffle1 = shufflevector <8 x float> %call, <8 x float> zeroinitializer, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
+ store <16 x float> %shuffle1, ptr %p1
+ %shuffle2 = shufflevector <8 x float> zeroinitializer, <8 x float> %fr, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 0, i32 1, i32 2, i32 3, i32 4, i32 5>
+ ret <16 x float> %shuffle2
+}
More information about the llvm-commits
mailing list