[llvm-branch-commits] [llvm] [SelectionDAG] Track demanded select elements in noundef checks (PR #200934)

via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Mon Jun 1 13:48:16 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-x86

Author: Krzysztof Drewniak (krzysz00)

<details>
<summary>Changes</summary>

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 <codex@<!-- -->openai.com>

---

<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>

---
Full diff: https://github.com/llvm/llvm-project/pull/200934.diff


2 Files Affected:

- (modified) llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp (+15) 
- (added) llvm/test/CodeGen/X86/dagcombine-freeze-select-demanded-elts.ll (+45) 


``````````diff
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
+}

``````````

</details>


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


More information about the llvm-branch-commits mailing list