diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index 9d73a42df2a4..cd6f083243d0 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -5042,8 +5042,9 @@ bool SelectionDAG::isGuaranteedNotToBeUndefOrPoison(SDValue Op, // If Op can't create undef/poison and none of its operands are undef/poison // then Op is never undef/poison. - // NOTE: TargetNodes should handle this in themselves in - // isGuaranteedNotToBeUndefOrPoisonForTargetNode. + // NOTE: TargetNodes can handle this in themselves in + // isGuaranteedNotToBeUndefOrPoisonForTargetNode or let + // TargetLowering::isGuaranteedNotToBeUndefOrPoisonForTargetNode handle it. return !canCreateUndefOrPoison(Op, PoisonOnly, /*ConsiderFlags*/ true, Depth) && all_of(Op->ops(), [&](SDValue V) { diff --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp index 57f8fc409de4..da29b1d5b312 100644 --- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp @@ -3786,7 +3786,15 @@ bool TargetLowering::isGuaranteedNotToBeUndefOrPoisonForTargetNode( Op.getOpcode() == ISD::INTRINSIC_VOID) && "Should use isGuaranteedNotToBeUndefOrPoison if you don't know whether Op" " is a target node!"); - return false; + + // If Op can't create undef/poison and none of its operands are undef/poison + // then Op is never undef/poison. + return !canCreateUndefOrPoisonForTargetNode(Op, DemandedElts, DAG, PoisonOnly, + /*ConsiderFlags*/ true, Depth) && + all_of(Op->ops(), [&](SDValue V) { + return DAG.isGuaranteedNotToBeUndefOrPoison(V, PoisonOnly, + Depth + 1); + }); } bool TargetLowering::canCreateUndefOrPoisonForTargetNode(