diff options
author | Philip Reames <listmail@philipreames.com> | 2016-02-12 00:09:18 +0000 |
---|---|---|
committer | Philip Reames <listmail@philipreames.com> | 2016-02-12 00:09:18 +0000 |
commit | 854a84c0b0a3386943bdc6bf67d8f2e36c4496db (patch) | |
tree | 46c06bf1897b87d63b2f63e863407c632f840ab3 /llvm/lib | |
parent | 9ddad935b93906f8b0389b9120ce29ff0206585f (diff) | |
download | bcm5719-llvm-854a84c0b0a3386943bdc6bf67d8f2e36c4496db.tar.gz bcm5719-llvm-854a84c0b0a3386943bdc6bf67d8f2e36c4496db.zip |
[LVI] Improve select handling to use condition
This patches teaches LVI to recognize clamp idioms (e.g. select(a > 5, a, 5) will always produce something greater than 5.
The tests end up being somewhat simplistic because trying to exercise the case I actually care about (a loop with a range check on a clamped secondary induction variable) ends up tripping across a couple of other imprecisions in the analysis. Ah, the joys of LVI...
Differential Revision: http://reviews.llvm.org/D16827
llvm-svn: 260627
Diffstat (limited to 'llvm/lib')
-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 bc90b929cf0..8f121110051 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); |