aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Analysis/ValueTracking.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Analysis/ValueTracking.cpp')
-rw-r--r--llvm/lib/Analysis/ValueTracking.cpp35
1 files changed, 16 insertions, 19 deletions
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index dbd5d3c..36fcec9 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -5330,15 +5330,12 @@ static bool directlyImpliesPoison(const Value *ValAssumedPoison,
return false;
if (const auto *I = dyn_cast<Instruction>(V)) {
- if (propagatesPoison(cast<Operator>(I)))
- return any_of(I->operands(), [=](const Value *Op) {
- return directlyImpliesPoison(ValAssumedPoison, Op, Depth + 1);
- });
+ if (any_of(I->operands(), [=](const Use &Op) {
+ return propagatesPoison(Op) &&
+ directlyImpliesPoison(ValAssumedPoison, Op, Depth + 1);
+ }))
+ return true;
- // 'select ValAssumedPoison, _, _' is poison.
- if (const auto *SI = dyn_cast<SelectInst>(I))
- return directlyImpliesPoison(ValAssumedPoison, SI->getCondition(),
- Depth + 1);
// V = extractvalue V0, idx
// V2 = extractvalue V0, idx2
// V0's elements are all poison or not. (e.g., add_with_overflow)
@@ -5496,7 +5493,8 @@ static bool isGuaranteedNotToBeUndefOrPoison(const Value *V,
else if (PoisonOnly && isa<Operator>(Cond)) {
// For poison, we can analyze further
auto *Opr = cast<Operator>(Cond);
- if (propagatesPoison(Opr) && is_contained(Opr->operand_values(), V))
+ if (any_of(Opr->operands(),
+ [V](const Use &U) { return V == U && propagatesPoison(U); }))
return true;
}
}
@@ -5618,13 +5616,15 @@ bool llvm::isGuaranteedToExecuteForEveryIteration(const Instruction *I,
llvm_unreachable("Instruction not contained in its own parent basic block.");
}
-bool llvm::propagatesPoison(const Operator *I) {
+bool llvm::propagatesPoison(const Use &PoisonOp) {
+ const Operator *I = cast<Operator>(PoisonOp.getUser());
switch (I->getOpcode()) {
case Instruction::Freeze:
- case Instruction::Select:
case Instruction::PHI:
case Instruction::Invoke:
return false;
+ case Instruction::Select:
+ return PoisonOp.getOperandNo() == 0;
case Instruction::Call:
if (auto *II = dyn_cast<IntrinsicInst>(I)) {
switch (II->getIntrinsicID()) {
@@ -5805,14 +5805,11 @@ static bool programUndefinedIfUndefOrPoison(const Value *V,
if (!isGuaranteedToTransferExecutionToSuccessor(&I))
return false;
- // If this instruction propagates poison, mark it as poison if any of
- // its operands are poison
- if (propagatesPoison(cast<Operator>(&I))) {
- for (const Value *Op : I.operands()) {
- if (YieldsPoison.count(Op)) {
- YieldsPoison.insert(&I);
- break;
- }
+ // If an operand is poison and propagates it, mark I as yielding poison.
+ for (const Use &Op : I.operands()) {
+ if (YieldsPoison.count(Op) && propagatesPoison(Op)) {
+ YieldsPoison.insert(&I);
+ break;
}
}
}