Index: include/llvm/IR/PatternMatch.h =================================================================== --- include/llvm/IR/PatternMatch.h +++ 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 @@ 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); } };