[llvm-branch-commits] [llvm] [DAG] isGuaranteedNotToBeUndefOrPoison - add ISD::CONCAT_VECTORS handling (PR #200932)

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


https://github.com/krzysz00 updated https://github.com/llvm/llvm-project/pull/200932

>From f203fd221dd0b656b437c2f6f5bddffe5a77eaf7 Mon Sep 17 00:00:00 2001
From: Krzysztof Drewniak <Krzysztof.Drewniak at amd.com>
Date: Fri, 29 May 2026 22:08:20 +0000
Subject: [PATCH] [SelectionDAG] Track demanded concat elements in noundef
 checks

Teach isGuaranteedNotToBeUndefOrPoison to distribute fixed-length
demanded element masks across CONCAT_VECTORS operands. This is part of
the series of fixes needed to resolve a SelectionDAG hang by making it
possible to prove certain values don't need to be frozen.

AI note: an LLM generated the code and the test, I've read them

Co-Authored-By: OpenAI Codex <codex at openai.com>
---
 .../lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 23 +++++++++++++++++++
 .../dagcombine-freeze-concat-demanded-elts.ll |  5 +---
 2 files changed, 24 insertions(+), 4 deletions(-)

diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index 75d550801315b..057b3df5a4627 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -5665,6 +5665,29 @@ bool SelectionDAG::isGuaranteedNotToBeUndefOrPoison(SDValue Op,
     }
     return true;
 
+  case ISD::CONCAT_VECTORS: {
+    EVT VT = Op.getValueType();
+    if (!VT.isFixedLengthVector())
+      return all_of(Op->ops(), [&](SDValue V) {
+        return isGuaranteedNotToBeUndefOrPoison(V, Kind, Depth + 1);
+      });
+
+    assert(DemandedElts.getBitWidth() == VT.getVectorNumElements() &&
+           "Unexpected demanded element mask width");
+
+    EVT SubVT = Op.getOperand(0).getValueType();
+    unsigned NumSubElts = SubVT.getVectorNumElements();
+    for (unsigned i = 0, e = Op.getNumOperands(); i != e; ++i) {
+      APInt DemandedSubElts =
+          DemandedElts.extractBits(NumSubElts, i * NumSubElts);
+      if (!!DemandedSubElts &&
+          !isGuaranteedNotToBeUndefOrPoison(Op.getOperand(i), DemandedSubElts,
+                                            Kind, Depth + 1))
+        return false;
+    }
+    return true;
+  }
+
   case ISD::EXTRACT_SUBVECTOR: {
     SDValue Src = Op.getOperand(0);
     if (Src.getValueType().isScalableVector())
diff --git a/llvm/test/CodeGen/X86/dagcombine-freeze-concat-demanded-elts.ll b/llvm/test/CodeGen/X86/dagcombine-freeze-concat-demanded-elts.ll
index 5988e1b6150df..a0ea86c9c7830 100644
--- a/llvm/test/CodeGen/X86/dagcombine-freeze-concat-demanded-elts.ll
+++ b/llvm/test/CodeGen/X86/dagcombine-freeze-concat-demanded-elts.ll
@@ -6,10 +6,7 @@ declare <4 x i32> @llvm.vector.extract.v4i32.v8i32(<8 x i32>, i64 immarg)
 define <4 x i32> @freeze_lshr_extract_concat_high_demanded(<4 x i32> %a, <4 x i32> %b) {
 ; CHECK-LABEL: freeze_lshr_extract_concat_high_demanded:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    vinserti128 $1, %xmm1, %ymm0, %ymm0
-; CHECK-NEXT:    vpsrld $1, %ymm0, %ymm0
-; CHECK-NEXT:    vextracti128 $1, %ymm0, %xmm0
-; CHECK-NEXT:    vzeroupper
+; CHECK-NEXT:    vpsrld $1, %xmm1, %xmm0
 ; CHECK-NEXT:    retq
   %poisonable = add nsw <4 x i32> %a, <i32 2147483647, i32 2147483647, i32 2147483647, i32 2147483647>
   %wide = shufflevector <4 x i32> %poisonable, <4 x i32> %b, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>



More information about the llvm-branch-commits mailing list