https://github.com/krzysz00 updated https://github.com/llvm/llvm-project/pull/200931
>From 59e5e3abf556a7dbf90dd278720779824eb759fc Mon Sep 17 00:00:00 2001 From: Krzysztof Drewniak <[email protected]> Date: Fri, 29 May 2026 21:49:54 +0000 Subject: [PATCH] [SelectionDAG] Look through freeze in undef demanded checks There were cycles where the freeze combiner and thet demanded-elements simplification code would get into fights about whethere the operands to a shuffle or a concat should be `freeze undef` or `undef` once the simplifier had concluded zero elements were demanded from some operation. This PR prevents such cases. AI note: an LLM generated the code and the test, I've read them Co-Authored-By: OpenAI Codex <[email protected]> --- .../CodeGen/SelectionDAG/TargetLowering.cpp | 18 +++++++++++------- .../dagcombine-freeze-undef-demanded-elts.ll | 3 ++- llvm/test/CodeGen/X86/pr91005.ll | 3 ++- 3 files changed, 15 insertions(+), 9 deletions(-) diff --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp index 55602b0496a87..f240b4510d8f9 100644 --- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp @@ -714,8 +714,10 @@ SDValue TargetLowering::SimplifyMultipleUseDemandedBits( if (Depth >= SelectionDAG::MaxRecursionDepth) return SDValue(); - // Ignore UNDEFs. - if (Op.isUndef()) + // Ignore undef/poison, including frozen undef/poison. Replacing a freeze of + // undef/poison with another undef node is unnecessary and can fight with + // freeze sinking. + if (peekThroughFreeze(Op).isUndef()) return SDValue(); // Not demanding any bits/elts from Op. @@ -1181,7 +1183,7 @@ bool TargetLowering::SimplifyDemandedBits( SDLoc dl(Op); // Undef operand. - if (Op.isUndef()) + if (peekThroughFreeze(Op).isUndef()) return false; // We can't simplify target constants. @@ -3233,6 +3235,8 @@ bool TargetLowering::SimplifyDemandedVectorElts( KnownUndef.setAllBits(); return false; } + if (peekThroughFreeze(Op).isUndef()) + return false; // If Op has other users, assume that all elements are needed. if (!AssumeSingleUse && !Op.getNode()->hasOneUse()) @@ -3407,7 +3411,7 @@ bool TargetLowering::SimplifyDemandedVectorElts( SmallVector<SDValue, 32> Ops(Op->ops()); bool Updated = false; for (unsigned i = 0; i != NumElts; ++i) { - if (!DemandedElts[i] && !Ops[i].isUndef()) { + if (!DemandedElts[i] && !peekThroughFreeze(Ops[i]).isUndef()) { Ops[i] = TLO.DAG.getUNDEF(Ops[0].getValueType()); KnownUndef.setBit(i); Updated = true; @@ -3484,7 +3488,7 @@ bool TargetLowering::SimplifyDemandedVectorElts( return true; // If none of the src operand elements are demanded, replace it with undef. - if (!DemandedSrcElts && !Src.isUndef()) + if (!DemandedSrcElts && !peekThroughFreeze(Src).isUndef()) return TLO.CombineTo(Op, TLO.DAG.getNode(ISD::INSERT_SUBVECTOR, DL, VT, TLO.DAG.getUNDEF(VT), Sub, Op.getOperand(2))); @@ -3629,8 +3633,8 @@ bool TargetLowering::SimplifyDemandedVectorElts( // If either side isn't demanded, replace it by UNDEF. We handle this // explicitly here to also simplify in case of multiple uses (on the // contrary to the SimplifyDemandedVectorElts calls below). - bool FoldLHS = !DemandedLHS && !LHS.isUndef(); - bool FoldRHS = !DemandedRHS && !RHS.isUndef(); + bool FoldLHS = !DemandedLHS && !peekThroughFreeze(LHS).isUndef(); + bool FoldRHS = !DemandedRHS && !peekThroughFreeze(RHS).isUndef(); if (FoldLHS || FoldRHS) { LHS = FoldLHS ? TLO.DAG.getUNDEF(LHS.getValueType()) : LHS; RHS = FoldRHS ? TLO.DAG.getUNDEF(RHS.getValueType()) : RHS; diff --git a/llvm/test/CodeGen/X86/dagcombine-freeze-undef-demanded-elts.ll b/llvm/test/CodeGen/X86/dagcombine-freeze-undef-demanded-elts.ll index fbf9945a73cb9..cc77a703a00f5 100644 --- a/llvm/test/CodeGen/X86/dagcombine-freeze-undef-demanded-elts.ll +++ b/llvm/test/CodeGen/X86/dagcombine-freeze-undef-demanded-elts.ll @@ -10,7 +10,8 @@ define void @freeze_undef_demanded_elts(ptr %p) minsize { ; CHECK-NEXT: movl $31744, %eax # imm = 0x7C00 ; CHECK-NEXT: vmovd %eax, %xmm0 ; CHECK-NEXT: vpcmpeqw %xmm0, %xmm0, %xmm0 -; CHECK-NEXT: vpinsrw $0, {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm1 +; CHECK-NEXT: movzwl {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %eax +; CHECK-NEXT: vmovd %eax, %xmm1 ; CHECK-NEXT: vpand %xmm1, %xmm0, %xmm0 ; CHECK-NEXT: vcvtph2ps %xmm0, %xmm0 ; CHECK-NEXT: vpxor %xmm1, %xmm1, %xmm1 diff --git a/llvm/test/CodeGen/X86/pr91005.ll b/llvm/test/CodeGen/X86/pr91005.ll index de3642b2bd05b..f9727e6b03ab3 100644 --- a/llvm/test/CodeGen/X86/pr91005.ll +++ b/llvm/test/CodeGen/X86/pr91005.ll @@ -10,7 +10,8 @@ define void @PR91005(ptr %0) minsize { ; CHECK-NEXT: movl $31744, %eax # imm = 0x7C00 ; CHECK-NEXT: vmovd %eax, %xmm0 ; CHECK-NEXT: vpcmpeqw %xmm0, %xmm0, %xmm0 -; CHECK-NEXT: vpinsrw $0, {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm1 +; CHECK-NEXT: movzwl {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %eax +; CHECK-NEXT: vmovd %eax, %xmm1 ; CHECK-NEXT: vpand %xmm1, %xmm0, %xmm0 ; CHECK-NEXT: vcvtph2ps %xmm0, %xmm0 ; CHECK-NEXT: vpxor %xmm1, %xmm1, %xmm1 _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
