diff --git a/llvm/include/llvm/CodeGen/SelectionDAG.h b/llvm/include/llvm/CodeGen/SelectionDAG.h --- a/llvm/include/llvm/CodeGen/SelectionDAG.h +++ b/llvm/include/llvm/CodeGen/SelectionDAG.h @@ -2027,9 +2027,9 @@ /// X|Cst == X+Cst iff X&Cst = 0. bool isBaseWithConstantOffset(SDValue Op) const; - /// Test whether the given SDValue is known to never be NaN. If \p SNaN is - /// true, returns if \p Op is known to never be a signaling NaN (it may still - /// be a qNaN). + /// Test whether the given SDValue (or all elements of it, if it is a + /// vector) is known to never be NaN. If \p SNaN is true, returns if \p Op is + /// known to never be a signaling NaN (it may still be a qNaN). bool isKnownNeverNaN(SDValue Op, bool SNaN = false, unsigned Depth = 0) const; /// \returns true if \p Op is known to never be a signaling NaN. diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -4683,7 +4683,6 @@ if (Depth >= MaxRecursionDepth) return false; // Limit search depth. - // TODO: Handle vectors. // If the value is a constant, we can obviously see if it is a NaN or not. if (const ConstantFPSDNode *C = dyn_cast(Op)) { return !C->getValueAPF().isNaN() || @@ -4781,6 +4780,12 @@ case ISD::EXTRACT_VECTOR_ELT: { return isKnownNeverNaN(Op.getOperand(0), SNaN, Depth + 1); } + case ISD::BUILD_VECTOR: { + for (const SDValue &Opnd : Op->ops()) + if (!isKnownNeverNaN(Opnd, SNaN, Depth + 1)) + return false; + return true; + } default: if (Opcode >= ISD::BUILTIN_OP_END || Opcode == ISD::INTRINSIC_WO_CHAIN ||