diff --git a/llvm/include/llvm/CodeGen/SelectionDAGNodes.h b/llvm/include/llvm/CodeGen/SelectionDAGNodes.h index 261f7e49e5c8c..b674d00597640 100644 --- a/llvm/include/llvm/CodeGen/SelectionDAGNodes.h +++ b/llvm/include/llvm/CodeGen/SelectionDAGNodes.h @@ -999,6 +999,13 @@ END_TWO_BYTE_PACK() /// If Flags is not in a defined state then this has no effect. void intersectFlagsWith(const SDNodeFlags Flags); + bool hasPoisonGeneratingFlags() const { + SDNodeFlags Flags = getFlags(); + return Flags.hasNoUnsignedWrap() || Flags.hasNoSignedWrap() || + Flags.hasExact() || Flags.hasDisjoint() || Flags.hasNonNeg() || + Flags.hasNoNaNs() || Flags.hasNoInfs(); + } + void setCFIType(uint32_t Type) { CFIType = Type; } uint32_t getCFIType() const { return CFIType; } diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index b63b8b893fdbf..e322cf6947f44 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -5095,6 +5095,9 @@ bool SelectionDAG::canCreateUndefOrPoison(SDValue Op, const APInt &DemandedElts, if (VT.isScalableVector()) return true; + if (ConsiderFlags && Op->hasPoisonGeneratingFlags()) + return true; + unsigned Opcode = Op.getOpcode(); switch (Opcode) { case ISD::FREEZE: @@ -5134,34 +5137,20 @@ bool SelectionDAG::canCreateUndefOrPoison(SDValue Op, const APInt &DemandedElts, return true; const TargetOptions &Options = getTarget().Options; - return Options.NoNaNsFPMath || Options.NoInfsFPMath || - (ConsiderFlags && - (Op->getFlags().hasNoNaNs() || Op->getFlags().hasNoInfs())); + return Options.NoNaNsFPMath || Options.NoInfsFPMath; } - // Matches hasPoisonGeneratingFlags(). + case ISD::OR: case ISD::ZERO_EXTEND: - return ConsiderFlags && Op->getFlags().hasNonNeg(); - case ISD::ADD: case ISD::SUB: case ISD::MUL: - // Matches hasPoisonGeneratingFlags(). - return ConsiderFlags && (Op->getFlags().hasNoSignedWrap() || - Op->getFlags().hasNoUnsignedWrap()); + // No poison except from flags (which is handled above) + return false; case ISD::SHL: // If the max shift amount isn't in range, then the shift can create poison. - if (!getValidMaximumShiftAmountConstant(Op, DemandedElts)) - return true; - - // Matches hasPoisonGeneratingFlags(). - return ConsiderFlags && (Op->getFlags().hasNoSignedWrap() || - Op->getFlags().hasNoUnsignedWrap()); - - // Matches hasPoisonGeneratingFlags(). - case ISD::OR: - return ConsiderFlags && Op->getFlags().hasDisjoint(); + return !getValidMaximumShiftAmountConstant(Op, DemandedElts); case ISD::SCALAR_TO_VECTOR: // Check if we demand any upper (undef) elements.