@@ -6560,10 +6560,25 @@ static bool shiftAmountKnownInRange(const Value *ShiftAmount) {
65606560 return Safe;
65616561}
65626562
6563- static bool canCreateUndefOrPoison (const Operator *Op, bool PoisonOnly,
6563+ enum class UndefPoisonKind {
6564+ PoisonOnly = (1 << 0 ),
6565+ UndefOnly = (1 << 1 ),
6566+ UndefOrPoison = PoisonOnly | UndefOnly,
6567+ };
6568+
6569+ static bool includesPoison (UndefPoisonKind Kind) {
6570+ return (unsigned (Kind) & unsigned (UndefPoisonKind::PoisonOnly)) != 0 ;
6571+ }
6572+
6573+ static bool includesUndef (UndefPoisonKind Kind) {
6574+ return (unsigned (Kind) & unsigned (UndefPoisonKind::UndefOnly)) != 0 ;
6575+ }
6576+
6577+ static bool canCreateUndefOrPoison (const Operator *Op, UndefPoisonKind Kind,
65646578 bool ConsiderFlagsAndMetadata) {
65656579
6566- if (ConsiderFlagsAndMetadata && Op->hasPoisonGeneratingFlagsOrMetadata ())
6580+ if (ConsiderFlagsAndMetadata && includesPoison (Kind) &&
6581+ Op->hasPoisonGeneratingFlagsOrMetadata ())
65676582 return true ;
65686583
65696584 unsigned Opcode = Op->getOpcode ();
@@ -6573,7 +6588,7 @@ static bool canCreateUndefOrPoison(const Operator *Op, bool PoisonOnly,
65736588 case Instruction::Shl:
65746589 case Instruction::AShr:
65756590 case Instruction::LShr:
6576- return !shiftAmountKnownInRange (Op->getOperand (1 ));
6591+ return includesPoison (Kind) && !shiftAmountKnownInRange (Op->getOperand (1 ));
65776592 case Instruction::FPToSI:
65786593 case Instruction::FPToUI:
65796594 // fptosi/ui yields poison if the resulting value does not fit in the
@@ -6614,7 +6629,8 @@ static bool canCreateUndefOrPoison(const Operator *Op, bool PoisonOnly,
66146629 return false ;
66156630 case Intrinsic::sshl_sat:
66166631 case Intrinsic::ushl_sat:
6617- return !shiftAmountKnownInRange (II->getArgOperand (1 ));
6632+ return includesPoison (Kind) &&
6633+ !shiftAmountKnownInRange (II->getArgOperand (1 ));
66186634 case Intrinsic::fma:
66196635 case Intrinsic::fmuladd:
66206636 case Intrinsic::sqrt:
@@ -6669,15 +6685,16 @@ static bool canCreateUndefOrPoison(const Operator *Op, bool PoisonOnly,
66696685 auto *VTy = cast<VectorType>(Op->getOperand (0 )->getType ());
66706686 unsigned IdxOp = Op->getOpcode () == Instruction::InsertElement ? 2 : 1 ;
66716687 auto *Idx = dyn_cast<ConstantInt>(Op->getOperand (IdxOp));
6672- if (!Idx || Idx->getValue ().uge (VTy->getElementCount ().getKnownMinValue ()))
6673- return true ;
6688+ if (includesPoison (Kind))
6689+ return !Idx ||
6690+ Idx->getValue ().uge (VTy->getElementCount ().getKnownMinValue ());
66746691 return false ;
66756692 }
66766693 case Instruction::ShuffleVector: {
66776694 ArrayRef<int > Mask = isa<ConstantExpr>(Op)
66786695 ? cast<ConstantExpr>(Op)->getShuffleMask ()
66796696 : cast<ShuffleVectorInst>(Op)->getShuffleMask ();
6680- return is_contained (Mask, PoisonMaskElem);
6697+ return includesPoison (Kind) && is_contained (Mask, PoisonMaskElem);
66816698 }
66826699 case Instruction::FNeg:
66836700 case Instruction::PHI:
@@ -6713,17 +6730,17 @@ static bool canCreateUndefOrPoison(const Operator *Op, bool PoisonOnly,
67136730
67146731bool llvm::canCreateUndefOrPoison (const Operator *Op,
67156732 bool ConsiderFlagsAndMetadata) {
6716- return ::canCreateUndefOrPoison (Op, /* PoisonOnly= */ false ,
6733+ return ::canCreateUndefOrPoison (Op, UndefPoisonKind::UndefOrPoison ,
67176734 ConsiderFlagsAndMetadata);
67186735}
67196736
67206737bool llvm::canCreatePoison (const Operator *Op, bool ConsiderFlagsAndMetadata) {
6721- return ::canCreateUndefOrPoison (Op, /* PoisonOnly= */ true ,
6738+ return ::canCreateUndefOrPoison (Op, UndefPoisonKind:: PoisonOnly,
67226739 ConsiderFlagsAndMetadata);
67236740}
67246741
6725- static bool directlyImpliesPoison (const Value *ValAssumedPoison,
6726- const Value *V, unsigned Depth) {
6742+ static bool directlyImpliesPoison (const Value *ValAssumedPoison, const Value *V,
6743+ unsigned Depth) {
67276744 if (ValAssumedPoison == V)
67286745 return true ;
67296746
@@ -6775,14 +6792,11 @@ bool llvm::impliesPoison(const Value *ValAssumedPoison, const Value *V) {
67756792 return ::impliesPoison (ValAssumedPoison, V, /* Depth */ 0 );
67766793}
67776794
6778- static bool programUndefinedIfUndefOrPoison (const Value *V,
6779- bool PoisonOnly);
6795+ static bool programUndefinedIfUndefOrPoison (const Value *V, bool PoisonOnly);
67806796
6781- static bool isGuaranteedNotToBeUndefOrPoison (const Value *V,
6782- AssumptionCache *AC,
6783- const Instruction *CtxI,
6784- const DominatorTree *DT,
6785- unsigned Depth, bool PoisonOnly) {
6797+ static bool isGuaranteedNotToBeUndefOrPoison (
6798+ const Value *V, AssumptionCache *AC, const Instruction *CtxI,
6799+ const DominatorTree *DT, unsigned Depth, UndefPoisonKind Kind) {
67866800 if (Depth >= MaxAnalysisRecursionDepth)
67876801 return false ;
67886802
@@ -6797,16 +6811,19 @@ static bool isGuaranteedNotToBeUndefOrPoison(const Value *V,
67976811 }
67986812
67996813 if (auto *C = dyn_cast<Constant>(V)) {
6814+ if (isa<PoisonValue>(C))
6815+ return !includesPoison (Kind);
6816+
68006817 if (isa<UndefValue>(C))
6801- return PoisonOnly && !isa<PoisonValue>(C );
6818+ return ! includesUndef (Kind );
68026819
68036820 if (isa<ConstantInt>(C) || isa<GlobalVariable>(C) || isa<ConstantFP>(V) ||
68046821 isa<ConstantPointerNull>(C) || isa<Function>(C))
68056822 return true ;
68066823
68076824 if (C->getType ()->isVectorTy () && !isa<ConstantExpr>(C))
6808- return (PoisonOnly ? !C->containsPoisonElement ()
6809- : !C->containsUndefOrPoisonElement ()) &&
6825+ return (! includesUndef (Kind) ? !C->containsPoisonElement ()
6826+ : !C->containsUndefOrPoisonElement ()) &&
68106827 !C->containsConstantExpression ();
68116828 }
68126829
@@ -6824,8 +6841,7 @@ static bool isGuaranteedNotToBeUndefOrPoison(const Value *V,
68246841 return true ;
68256842
68266843 auto OpCheck = [&](const Value *V) {
6827- return isGuaranteedNotToBeUndefOrPoison (V, AC, CtxI, DT, Depth + 1 ,
6828- PoisonOnly);
6844+ return isGuaranteedNotToBeUndefOrPoison (V, AC, CtxI, DT, Depth + 1 , Kind);
68296845 };
68306846
68316847 if (auto *Opr = dyn_cast<Operator>(V)) {
@@ -6847,14 +6863,16 @@ static bool isGuaranteedNotToBeUndefOrPoison(const Value *V,
68476863 for (unsigned i = 0 ; i < Num; ++i) {
68486864 auto *TI = PN->getIncomingBlock (i)->getTerminator ();
68496865 if (!isGuaranteedNotToBeUndefOrPoison (PN->getIncomingValue (i), AC, TI,
6850- DT, Depth + 1 , PoisonOnly )) {
6866+ DT, Depth + 1 , Kind )) {
68516867 IsWellDefined = false ;
68526868 break ;
68536869 }
68546870 }
68556871 if (IsWellDefined)
68566872 return true ;
6857- } else if (!canCreateUndefOrPoison (Opr) && all_of (Opr->operands (), OpCheck))
6873+ } else if (!::canCreateUndefOrPoison (Opr, Kind,
6874+ /* ConsiderFlagsAndMetadata*/ true ) &&
6875+ all_of (Opr->operands (), OpCheck))
68586876 return true ;
68596877 }
68606878
@@ -6864,7 +6882,7 @@ static bool isGuaranteedNotToBeUndefOrPoison(const Value *V,
68646882 I->hasMetadata (LLVMContext::MD_dereferenceable_or_null))
68656883 return true ;
68666884
6867- if (programUndefinedIfUndefOrPoison (V, PoisonOnly ))
6885+ if (programUndefinedIfUndefOrPoison (V, ! includesUndef (Kind) ))
68686886 return true ;
68696887
68706888 // CxtI may be null or a cloned instruction.
@@ -6896,7 +6914,7 @@ static bool isGuaranteedNotToBeUndefOrPoison(const Value *V,
68966914 if (Cond) {
68976915 if (Cond == V)
68986916 return true ;
6899- else if (PoisonOnly && isa<Operator>(Cond)) {
6917+ else if (! includesUndef (Kind) && isa<Operator>(Cond)) {
69006918 // For poison, we can analyze further
69016919 auto *Opr = cast<Operator>(Cond);
69026920 if (any_of (Opr->operands (),
@@ -6918,20 +6936,22 @@ bool llvm::isGuaranteedNotToBeUndefOrPoison(const Value *V, AssumptionCache *AC,
69186936 const Instruction *CtxI,
69196937 const DominatorTree *DT,
69206938 unsigned Depth) {
6921- return ::isGuaranteedNotToBeUndefOrPoison (V, AC, CtxI, DT, Depth, false );
6939+ return ::isGuaranteedNotToBeUndefOrPoison (V, AC, CtxI, DT, Depth,
6940+ UndefPoisonKind::UndefOrPoison);
69226941}
69236942
69246943bool llvm::isGuaranteedNotToBePoison (const Value *V, AssumptionCache *AC,
69256944 const Instruction *CtxI,
69266945 const DominatorTree *DT, unsigned Depth) {
6927- return ::isGuaranteedNotToBeUndefOrPoison (V, AC, CtxI, DT, Depth, true );
6946+ return ::isGuaranteedNotToBeUndefOrPoison (V, AC, CtxI, DT, Depth,
6947+ UndefPoisonKind::PoisonOnly);
69286948}
69296949
69306950bool llvm::isGuaranteedNotToBeUndef (const Value *V, AssumptionCache *AC,
69316951 const Instruction *CtxI,
69326952 const DominatorTree *DT, unsigned Depth) {
6933- // TODO: This is currently equivalent to isGuaranteedNotToBeUndefOrPoison().
6934- return :: isGuaranteedNotToBeUndefOrPoison (V, AC, CtxI, DT, Depth, false );
6953+ return :: isGuaranteedNotToBeUndefOrPoison (V, AC, CtxI, DT, Depth,
6954+ UndefPoisonKind::UndefOnly );
69356955}
69366956
69376957// / Return true if undefined behavior would provably be executed on the path to
0 commit comments