From d3c80611a2da29bb217d5c1eaea284039ea664d4 Mon Sep 17 00:00:00 2001 From: James Molloy Date: Mon, 2 Nov 2015 09:54:00 +0000 Subject: [PATCH] [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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@251785 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/IR/PatternMatch.h | 63 +++++++++++++--------------------- 1 file changed, 24 insertions(+), 39 deletions(-) diff --git a/include/llvm/IR/PatternMatch.h b/include/llvm/IR/PatternMatch.h index f4d7d8c4441..0c5ec692105 100644 --- a/include/llvm/IR/PatternMatch.h +++ b/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 bool match(OpTy *V) { - // Look for "(x pred y) ? x : y" or "(x pred y) ? y : x". - auto *SI = dyn_cast(V); - if (!SI) - return false; - auto *Cmp = dyn_cast(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); } }; -- 2.34.1