[llvm-branch-commits] [llvm] [SelectionDAG] Look through ISD::FREEZE in SimplifyDemanded checks (PR #200931)

Krzysztof Drewniak via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Tue Jun 2 23:14:22 PDT 2026


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 <Krzysztof.Drewniak at amd.com>
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 <codex at openai.com>
---
 .../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



More information about the llvm-branch-commits mailing list