[llvm] DAG: Preserve poison in some cast folds (PR #225403)
Matt Arsenault via llvm-commits
llvm-commits at lists.llvm.org
Tue Sep 22 06:56:22 PDT 2026
https://github.com/arsenm created https://github.com/llvm/llvm-project/pull/225403
None
>From 2d7dff031edc7e2f58e65856e7169eb9fe2dce46 Mon Sep 17 00:00:00 2001
From: Matt Arsenault <Matthew.Arsenault at amd.com>
Date: Wed, 1 Jul 2026 13:30:22 +0200
Subject: [PATCH] DAG: Preserve poison in some cast folds
---
llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 38 ++++++++++++-------
1 file changed, 24 insertions(+), 14 deletions(-)
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index 17e2ab01bc11f..e86514aed9410 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -16736,14 +16736,24 @@ SDValue DAGCombiner::visitZERO_EXTEND(SDNode *N) {
return SDValue();
}
+/// For a unary operation, propagate poison or undef from the operand \p N0 to
+/// the result type \p VT. Returns an empty SDValue if \p N0 is neither.
+static SDValue propagateUnaryUndef(SelectionDAG &DAG, SDValue N0, EVT VT) {
+ if (N0.getOpcode() == ISD::POISON)
+ return DAG.getPOISON(VT);
+ if (N0.getOpcode() == ISD::UNDEF)
+ return DAG.getUNDEF(VT);
+ return SDValue();
+}
+
SDValue DAGCombiner::visitANY_EXTEND(SDNode *N) {
SDValue N0 = N->getOperand(0);
EVT VT = N->getValueType(0);
SDLoc DL(N);
- // aext(undef) = undef
- if (N0.isUndef())
- return DAG.getUNDEF(VT);
+ // aext(undef) = undef, aext(poison) = poison
+ if (SDValue R = propagateUnaryUndef(DAG, N0, VT))
+ return R;
if (SDValue Res = tryToFoldExtendOfConstant(N, DL, TLI, DAG, LegalTypes))
return Res;
@@ -17764,9 +17774,9 @@ SDValue DAGCombiner::visitTRUNCATE(SDNode *N) {
bool isLE = DAG.getDataLayout().isLittleEndian();
SDLoc DL(N);
- // trunc(undef) = undef
- if (N0.isUndef())
- return DAG.getUNDEF(VT);
+ // trunc(undef) = undef, trunc(poison) = poison
+ if (SDValue R = propagateUnaryUndef(DAG, N0, VT))
+ return R;
// fold (truncate (truncate x)) -> (truncate x)
if (N0.getOpcode() == ISD::TRUNCATE)
@@ -18305,8 +18315,8 @@ SDValue DAGCombiner::visitBITCAST(SDNode *N) {
SDValue N0 = N->getOperand(0);
EVT VT = N->getValueType(0);
- if (N0.isUndef())
- return DAG.getUNDEF(VT);
+ if (SDValue R = propagateUnaryUndef(DAG, N0, VT))
+ return R;
// If the input is a BUILD_VECTOR with all constant elements, fold this now.
// Only do this before legalize types, unless both types are integer and the
@@ -20792,8 +20802,8 @@ SDValue DAGCombiner::visitFP_TO_SINT(SDNode *N) {
SDLoc DL(N);
// fold (fp_to_sint undef) -> undef
- if (N0.isUndef())
- return DAG.getUNDEF(VT);
+ if (SDValue R = propagateUnaryUndef(DAG, N0, VT))
+ return R;
// fold (fp_to_sint c1fp) -> c1
if (SDValue C = DAG.FoldConstantArithmetic(ISD::FP_TO_SINT, DL, VT, {N0}))
@@ -20808,8 +20818,8 @@ SDValue DAGCombiner::visitFP_TO_UINT(SDNode *N) {
SDLoc DL(N);
// fold (fp_to_uint undef) -> undef
- if (N0.isUndef())
- return DAG.getUNDEF(VT);
+ if (SDValue R = propagateUnaryUndef(DAG, N0, VT))
+ return R;
// fold (fp_to_uint c1fp) -> c1
if (SDValue C = DAG.FoldConstantArithmetic(ISD::FP_TO_UINT, DL, VT, {N0}))
@@ -20824,8 +20834,8 @@ SDValue DAGCombiner::visitXROUND(SDNode *N) {
// fold (lrint|llrint undef) -> undef
// fold (lround|llround undef) -> undef
- if (N0.isUndef())
- return DAG.getUNDEF(VT);
+ if (SDValue R = propagateUnaryUndef(DAG, N0, VT))
+ return R;
// fold (lrint|llrint c1fp) -> c1
// fold (lround|llround c1fp) -> c1
More information about the llvm-commits
mailing list