diff options
author | Sanjay Patel <spatel@rotateright.com> | 2017-12-13 21:58:15 +0000 |
---|---|---|
committer | Sanjay Patel <spatel@rotateright.com> | 2017-12-13 21:58:15 +0000 |
commit | 3c7a35de7fbc0a73505545cd9f68a3bbacb68e57 (patch) | |
tree | 133516ab85455faa61a9d6194d0b707076c08259 /llvm/lib/Transforms/Scalar/EarlyCSE.cpp | |
parent | 75f8360e280c1a23b57b61374451281957a0d497 (diff) | |
download | bcm5719-llvm-3c7a35de7fbc0a73505545cd9f68a3bbacb68e57.tar.gz bcm5719-llvm-3c7a35de7fbc0a73505545cd9f68a3bbacb68e57.zip |
[EarlyCSE] recognize commuted and swapped variants of min/max as equivalent (PR35642)
As shown in:
https://bugs.llvm.org/show_bug.cgi?id=35642
...we can have different forms of min/max, so we should recognize those here in EarlyCSE
similar to how we already handle binops and compares that can commute.
Differential Revision: https://reviews.llvm.org/D41136
llvm-svn: 320640
Diffstat (limited to 'llvm/lib/Transforms/Scalar/EarlyCSE.cpp')
-rw-r--r-- | llvm/lib/Transforms/Scalar/EarlyCSE.cpp | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/Scalar/EarlyCSE.cpp b/llvm/lib/Transforms/Scalar/EarlyCSE.cpp index 1066dc33007..11bf8ee733c 100644 --- a/llvm/lib/Transforms/Scalar/EarlyCSE.cpp +++ b/llvm/lib/Transforms/Scalar/EarlyCSE.cpp @@ -27,6 +27,7 @@ #include "llvm/Analysis/MemorySSAUpdater.h" #include "llvm/Analysis/TargetLibraryInfo.h" #include "llvm/Analysis/TargetTransformInfo.h" +#include "llvm/Analysis/ValueTracking.h" #include "llvm/IR/BasicBlock.h" #include "llvm/IR/Constants.h" #include "llvm/IR/DataLayout.h" @@ -142,6 +143,19 @@ unsigned DenseMapInfo<SimpleValue>::getHashValue(SimpleValue Val) { return hash_combine(Inst->getOpcode(), Pred, LHS, RHS); } + // Hash min/max (cmp + select) to allow for commuted operands, non-canonical + // compare predicate (eg, the compare for smin may use 'sgt' rather than + // 'slt'), and non-canonical operands in the compare. + Value *A, *B; + SelectPatternFlavor SPF = matchSelectPattern(Inst, A, B).Flavor; + // TODO: We should also detect abs and FP min/max. + if (SPF == SPF_SMIN || SPF == SPF_SMAX || + SPF == SPF_UMIN || SPF == SPF_UMAX) { + if (A > B) + std::swap(A, B); + return hash_combine(Inst->getOpcode(), SPF, A, B); + } + if (CastInst *CI = dyn_cast<CastInst>(Inst)) return hash_combine(CI->getOpcode(), CI->getType(), CI->getOperand(0)); @@ -200,6 +214,19 @@ bool DenseMapInfo<SimpleValue>::isEqual(SimpleValue LHS, SimpleValue RHS) { LHSCmp->getSwappedPredicate() == RHSCmp->getPredicate(); } + // Min/max can occur with commuted operands, non-canonical predicates, and/or + // non-canonical operands. + Value *LHSA, *LHSB; + SelectPatternFlavor LSPF = matchSelectPattern(LHSI, LHSA, LHSB).Flavor; + // TODO: We should also detect abs and FP min/max. + if (LSPF == SPF_SMIN || LSPF == SPF_SMAX || + LSPF == SPF_UMIN || LSPF == SPF_UMAX) { + Value *RHSA, *RHSB; + SelectPatternFlavor RSPF = matchSelectPattern(RHSI, RHSA, RHSB).Flavor; + return (LSPF == RSPF && ((LHSA == RHSA && LHSB == RHSB) || + (LHSA == RHSB && LHSB == RHSA))); + } + return false; } |