diff options
| author | James Molloy <james.molloy@arm.com> | 2015-11-02 09:54:00 +0000 |
|---|---|---|
| committer | James Molloy <james.molloy@arm.com> | 2015-11-02 09:54:00 +0000 |
| commit | 9d8bbada54a67788b1a3417cdf4718613b344601 (patch) | |
| tree | 3589bcb39deb6c027344200d9dde7c4d0505495c | |
| parent | 0e97e5cb1907ef55966fd27055698515e522c0f0 (diff) | |
| download | bcm5719-llvm-9d8bbada54a67788b1a3417cdf4718613b344601.tar.gz bcm5719-llvm-9d8bbada54a67788b1a3417cdf4718613b344601.zip | |
[PatternMatch] Switch to use ValueTracking::matchSelectPattern
Instead of rolling our own min/max matching code (which is notoriously
hard to get completely right), use ValueTracking's instead.
llvm-svn: 251785
| -rw-r--r-- | llvm/include/llvm/IR/PatternMatch.h | 63 |
1 files changed, 24 insertions, 39 deletions
diff --git a/llvm/include/llvm/IR/PatternMatch.h b/llvm/include/llvm/IR/PatternMatch.h index f4d7d8c4441..0c5ec692105 100644 --- a/llvm/include/llvm/IR/PatternMatch.h +++ b/llvm/include/llvm/IR/PatternMatch.h @@ -29,6 +29,7 @@ #ifndef LLVM_IR_PATTERNMATCH_H #define LLVM_IR_PATTERNMATCH_H +#include "llvm/Analysis/ValueTracking.h" #include "llvm/IR/CallSite.h" #include "llvm/IR/Constants.h" #include "llvm/IR/Instructions.h" @@ -955,85 +956,69 @@ struct MaxMin_match { MaxMin_match(const LHS_t &LHS, const RHS_t &RHS) : L(LHS), R(RHS) {} template <typename OpTy> bool match(OpTy *V) { - // Look for "(x pred y) ? x : y" or "(x pred y) ? y : x". - auto *SI = dyn_cast<SelectInst>(V); - if (!SI) - return false; - auto *Cmp = dyn_cast<CmpInst_t>(SI->getCondition()); - if (!Cmp) - return false; - // At this point we have a select conditioned on a comparison. Check that - // it is the values returned by the select that are being compared. - Value *TrueVal = SI->getTrueValue(); - Value *FalseVal = SI->getFalseValue(); - Value *LHS = Cmp->getOperand(0); - Value *RHS = Cmp->getOperand(1); - if ((TrueVal != LHS || FalseVal != RHS) && - (TrueVal != RHS || FalseVal != LHS)) - return false; - typename CmpInst_t::Predicate Pred = - LHS == TrueVal ? Cmp->getPredicate() : Cmp->getSwappedPredicate(); - // Does "(x pred y) ? x : y" represent the desired max/min operation? - if (!Pred_t::match(Pred)) - return false; - // It does! Bind the operands. - return L.match(LHS) && R.match(RHS); + Value *LHS, *RHS; + auto SPR = matchSelectPattern(V, LHS, RHS); + return Pred_t::match(SPR) && L.match(LHS) && R.match(RHS); } }; /// \brief Helper class for identifying signed max predicates. struct smax_pred_ty { - static bool match(ICmpInst::Predicate Pred) { - return Pred == CmpInst::ICMP_SGT || Pred == CmpInst::ICMP_SGE; + static bool match(SelectPatternResult SPR) { + return SPR.Flavor == SPF_SMAX; } }; /// \brief Helper class for identifying signed min predicates. struct smin_pred_ty { - static bool match(ICmpInst::Predicate Pred) { - return Pred == CmpInst::ICMP_SLT || Pred == CmpInst::ICMP_SLE; + static bool match(SelectPatternResult SPR) { + return SPR.Flavor == SPF_SMIN; } }; /// \brief Helper class for identifying unsigned max predicates. struct umax_pred_ty { - static bool match(ICmpInst::Predicate Pred) { - return Pred == CmpInst::ICMP_UGT || Pred == CmpInst::ICMP_UGE; + static bool match(SelectPatternResult SPR) { + return SPR.Flavor == SPF_UMAX; } }; /// \brief Helper class for identifying unsigned min predicates. struct umin_pred_ty { - static bool match(ICmpInst::Predicate Pred) { - return Pred == CmpInst::ICMP_ULT || Pred == CmpInst::ICMP_ULE; + static bool match(SelectPatternResult SPR) { + return SPR.Flavor == SPF_UMIN; } }; /// \brief Helper class for identifying ordered max predicates. struct ofmax_pred_ty { - static bool match(FCmpInst::Predicate Pred) { - return Pred == CmpInst::FCMP_OGT || Pred == CmpInst::FCMP_OGE; + static bool match(SelectPatternResult SPR) { + return SPR.Flavor == SPF_FMAXNUM && + (SPR.Ordered || SPR.NaNBehavior == SPNB_RETURNS_ANY); } }; /// \brief Helper class for identifying ordered min predicates. struct ofmin_pred_ty { - static bool match(FCmpInst::Predicate Pred) { - return Pred == CmpInst::FCMP_OLT || Pred == CmpInst::FCMP_OLE; + static bool match(SelectPatternResult SPR) { + return SPR.Flavor == SPF_FMINNUM && + (SPR.Ordered || SPR.NaNBehavior == SPNB_RETURNS_ANY); } }; /// \brief Helper class for identifying unordered max predicates. struct ufmax_pred_ty { - static bool match(FCmpInst::Predicate Pred) { - return Pred == CmpInst::FCMP_UGT || Pred == CmpInst::FCMP_UGE; + static bool match(SelectPatternResult SPR) { + return SPR.Flavor == SPF_FMAXNUM && + (!SPR.Ordered || SPR.NaNBehavior == SPNB_RETURNS_ANY); } }; /// \brief Helper class for identifying unordered min predicates. struct ufmin_pred_ty { - static bool match(FCmpInst::Predicate Pred) { - return Pred == CmpInst::FCMP_ULT || Pred == CmpInst::FCMP_ULE; + static bool match(SelectPatternResult SPR) { + return SPR.Flavor == SPF_FMINNUM && + (!SPR.Ordered || SPR.NaNBehavior == SPNB_RETURNS_ANY); } }; |

