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.cpp22
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;
}