diff options
Diffstat (limited to 'llvm/lib/Analysis/ValueTracking.cpp')
-rw-r--r-- | llvm/lib/Analysis/ValueTracking.cpp | 22 |
1 files changed, 21 insertions, 1 deletions
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index 8991582..c641652 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -84,6 +84,17 @@ using namespace llvm::PatternMatch; static cl::opt<unsigned> DomConditionsMaxUses("dom-conditions-max-uses", cl::Hidden, cl::init(20)); +// According to the LangRef, branching on a poison condition is absolutely +// immediate full UB. However, historically we haven't implemented that +// consistently as we have an important transformation (non-trivial unswitch) +// which introduces instances of branch on poison/undef to otherwise well +// defined programs. This flag exists to let us test optimization benefit +// of exploiting the specified behavior (in combination with enabling the +// unswitch fix.) +static cl::opt<bool> BranchOnPoisonAsUB("branch-on-poison-as-ub", + cl::Hidden, cl::init(false)); + + /// Returns the bitwidth of the given scalar or pointer type. For vector types, /// returns the element type's bitwidth. static unsigned getBitWidth(Type *Ty, const DataLayout &DL) { @@ -5468,7 +5479,16 @@ void llvm::getGuaranteedNonPoisonOps(const Instruction *I, case Instruction::SRem: Operands.insert(I->getOperand(1)); break; - + case Instruction::Switch: + if (BranchOnPoisonAsUB) + Operands.insert(cast<SwitchInst>(I)->getCondition()); + break; + case Instruction::Br: { + auto *BR = cast<BranchInst>(I); + if (BranchOnPoisonAsUB && BR->isConditional()) + Operands.insert(BR->getCondition()); + break; + } default: break; } |