diff options
Diffstat (limited to 'llvm/lib/Analysis/LazyValueInfo.cpp')
-rw-r--r-- | llvm/lib/Analysis/LazyValueInfo.cpp | 19 |
1 files changed, 19 insertions, 0 deletions
diff --git a/llvm/lib/Analysis/LazyValueInfo.cpp b/llvm/lib/Analysis/LazyValueInfo.cpp index bc90b92..8f12111 100644 --- a/llvm/lib/Analysis/LazyValueInfo.cpp +++ b/llvm/lib/Analysis/LazyValueInfo.cpp @@ -911,6 +911,25 @@ bool LazyValueInfoCache::solveBlockValueSelect(LVILatticeVal &BBLV, return true; } + // Can we constrain the facts about the true and false values by using the + // condition itself? This shows up with idioms like e.g. select(a > 5, a, 5). + // TODO: We could potentially refine an overdefined true value above. + if (auto *ICI = dyn_cast<ICmpInst>(SI->getCondition())) { + LVILatticeVal TrueValTaken, FalseValTaken; + if (!getValueFromFromCondition(SI->getTrueValue(), ICI, + TrueValTaken, true)) + TrueValTaken.markOverdefined(); + if (!getValueFromFromCondition(SI->getFalseValue(), ICI, + FalseValTaken, false)) + FalseValTaken.markOverdefined(); + + TrueVal = intersect(TrueVal, TrueValTaken); + FalseVal = intersect(FalseVal, FalseValTaken); + } + + // TODO: handle idioms like min & max where we can use a more precise merge + // when our inputs are constant ranges. + LVILatticeVal Result; // Start Undefined. Result.mergeIn(TrueVal, DL); Result.mergeIn(FalseVal, DL); |