diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -84,6 +84,17 @@ static cl::opt 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 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 @@ case Instruction::SRem: Operands.insert(I->getOperand(1)); break; - + case Instruction::Switch: + if (BranchOnPoisonAsUB) + Operands.insert(cast(I)->getCondition()); + break; + case Instruction::Br: { + auto *BR = cast(I); + if (BranchOnPoisonAsUB && BR->isConditional()) + Operands.insert(BR->getCondition()); + break; + } default: break; }