https://github.com/krzysz00 created 
https://github.com/llvm/llvm-project/pull/200934

Propagate demanded elements through to the two arms of a select, and
check the condition with or without demanded elements depending on if
it's a vector or not.

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

Co-Authored-By: OpenAI Codex <[email protected]>

---

<sub>Stack created with <a href="https://github.com/github/gh-stack";>GitHub 
Stacks CLI</a> • <a href="https://gh.io/stacks-feedback";>Give Feedback 
💬</a></sub>

>From 6b98b820000c33350549c73cb6f0de2f6188b1c4 Mon Sep 17 00:00:00 2001
From: Krzysztof Drewniak <[email protected]>
Date: Fri, 29 May 2026 22:35:59 +0000
Subject: [PATCH] [SelectionDAG] Track demanded select elements in noundef
 checks

Propagate demanded elements through to the two arms of a select, and
check the condition with or without demanded elements depending on if
it's a vector or not.

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

Co-Authored-By: OpenAI Codex <[email protected]>
---
 .../lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 15 +++++++
 .../dagcombine-freeze-select-demanded-elts.ll | 45 +++++++++++++++++++
 2 files changed, 60 insertions(+)
 create mode 100644 
llvm/test/CodeGen/X86/dagcombine-freeze-select-demanded-elts.ll

diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp 
b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index 072a918115bbd..47b15522bcf4e 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -5813,6 +5813,21 @@ bool 
SelectionDAG::isGuaranteedNotToBeUndefOrPoison(SDValue Op,
   case ISD::SPLAT_VECTOR:
     return isGuaranteedNotToBeUndefOrPoison(Op.getOperand(0), Kind, Depth + 1);
 
+  case ISD::SELECT: {
+    SDValue Cond = Op.getOperand(0);
+    bool CondIsVector = Cond.getValueType().isVector();
+    return !canCreateUndefOrPoison(Op, DemandedElts, Kind,
+                                   /*ConsiderFlags*/ true, Depth) &&
+           (CondIsVector
+                ? isGuaranteedNotToBeUndefOrPoison(Cond, DemandedElts, Kind,
+                                                   Depth + 1)
+                : isGuaranteedNotToBeUndefOrPoison(Cond, Kind, Depth + 1)) &&
+           isGuaranteedNotToBeUndefOrPoison(Op.getOperand(1), DemandedElts,
+                                            Kind, Depth + 1) &&
+           isGuaranteedNotToBeUndefOrPoison(Op.getOperand(2), DemandedElts,
+                                            Kind, Depth + 1);
+  }
+
   case ISD::VECTOR_SHUFFLE: {
     APInt DemandedLHS, DemandedRHS;
     auto *SVN = cast<ShuffleVectorSDNode>(Op);
diff --git a/llvm/test/CodeGen/X86/dagcombine-freeze-select-demanded-elts.ll 
b/llvm/test/CodeGen/X86/dagcombine-freeze-select-demanded-elts.ll
new file mode 100644
index 0000000000000..da7241e9892fc
--- /dev/null
+++ b/llvm/test/CodeGen/X86/dagcombine-freeze-select-demanded-elts.ll
@@ -0,0 +1,45 @@
+; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py 
UTC_ARGS: --version 6
+; RUN: llc -mtriple=x86_64-unknown-unknown -mattr=+sse2 \
+; RUN:   -stop-after=x86-isel < %s | FileCheck %s --check-prefix=COMBINE
+; RUN: llc -mtriple=x86_64-unknown-unknown -mattr=+sse2 \
+; RUN:   -combiner-disabled -stop-after=x86-isel < %s | FileCheck %s \
+; RUN:   --check-prefix=NOCOMBINE
+
+define i32 @freeze_select_scalar_demanded(i1 %c, <2 x i32> %a, <2 x i32> %b, 
<2 x i32> %d) nounwind {
+  ; COMBINE-LABEL: name: freeze_select_scalar_demanded
+  ; COMBINE: bb.0 (%ir-block.0):
+  ; COMBINE-NEXT:   liveins: $xmm0
+  ; COMBINE-NEXT: {{  $}}
+  ; COMBINE-NEXT:   [[COPY:%[0-9]+]]:vr128 = COPY $xmm0
+  ; COMBINE-NEXT:   [[MOVPDI2DIrr:%[0-9]+]]:gr32 = MOVPDI2DIrr [[COPY]]
+  ; COMBINE-NEXT:   $eax = COPY [[MOVPDI2DIrr]]
+  ; COMBINE-NEXT:   RET 0, $eax
+  ;
+  ; NOCOMBINE-LABEL: name: freeze_select_scalar_demanded
+  ; NOCOMBINE: bb.0 (%ir-block.0):
+  ; NOCOMBINE-NEXT:   liveins: $edi, $xmm0, $xmm1, $xmm2
+  ; NOCOMBINE-NEXT: {{  $}}
+  ; NOCOMBINE-NEXT:   [[COPY:%[0-9]+]]:vr128 = COPY $xmm2
+  ; NOCOMBINE-NEXT:   [[COPY1:%[0-9]+]]:vr128 = COPY $xmm1
+  ; NOCOMBINE-NEXT:   [[COPY2:%[0-9]+]]:vr128 = COPY $xmm0
+  ; NOCOMBINE-NEXT:   [[COPY3:%[0-9]+]]:gr32 = COPY $edi
+  ; NOCOMBINE-NEXT:   [[COPY4:%[0-9]+]]:gr8 = COPY [[COPY3]].sub_8bit
+  ; NOCOMBINE-NEXT:   [[PADDDrm:%[0-9]+]]:vr128 = nsw PADDDrm [[COPY1]], $rip, 
1, $noreg, %const.0, $noreg :: (load (s128) from constant-pool)
+  ; NOCOMBINE-NEXT:   [[PSUBDrm:%[0-9]+]]:vr128 = nsw PSUBDrm [[COPY]], $rip, 
1, $noreg, %const.1, $noreg :: (load (s128) from constant-pool)
+  ; NOCOMBINE-NEXT:   [[PUNPCKLQDQrr:%[0-9]+]]:vr128 = PUNPCKLQDQrr [[COPY2]], 
killed [[PADDDrm]]
+  ; NOCOMBINE-NEXT:   [[PUNPCKLQDQrr1:%[0-9]+]]:vr128 = PUNPCKLQDQrr 
[[COPY2]], killed [[PSUBDrm]]
+  ; NOCOMBINE-NEXT:   TEST8ri killed [[COPY4]], 1, implicit-def $eflags
+  ; NOCOMBINE-NEXT:   [[CMOV_VR128_:%[0-9]+]]:vr128 = CMOV_VR128 killed 
[[PUNPCKLQDQrr1]], killed [[PUNPCKLQDQrr]], 5, implicit $eflags
+  ; NOCOMBINE-NEXT:   [[COPY5:%[0-9]+]]:vr128 = COPY killed [[CMOV_VR128_]]
+  ; NOCOMBINE-NEXT:   [[MOVPDI2DIrr:%[0-9]+]]:gr32 = MOVPDI2DIrr killed 
[[COPY5]]
+  ; NOCOMBINE-NEXT:   $eax = COPY [[MOVPDI2DIrr]]
+  ; NOCOMBINE-NEXT:   RET 0, $eax
+  %poisonable.b = add nsw <2 x i32> %b, <i32 2147483647, i32 2147483647>
+  %poisonable.d = sub nsw <2 x i32> %d, <i32 -2147483648, i32 -2147483648>
+  %lhs = shufflevector <2 x i32> %a, <2 x i32> %poisonable.b, <4 x i32> <i32 
0, i32 1, i32 2, i32 3>
+  %rhs = shufflevector <2 x i32> %a, <2 x i32> %poisonable.d, <4 x i32> <i32 
0, i32 1, i32 2, i32 3>
+  %sel = select i1 %c, <4 x i32> %lhs, <4 x i32> %rhs
+  %fr = freeze <4 x i32> %sel
+  %ext = extractelement <4 x i32> %fr, i64 0
+  ret i32 %ext
+}

_______________________________________________
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits

Reply via email to