aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Analysis/ValueTracking.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Analysis/ValueTracking.cpp')
-rw-r--r--llvm/lib/Analysis/ValueTracking.cpp40
1 files changed, 40 insertions, 0 deletions
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 05eb2fc..904b069 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -5991,6 +5991,46 @@ CmpInst::Predicate llvm::getInverseMinMaxPred(SelectPatternFlavor SPF) {
return getMinMaxPred(getInverseMinMaxFlavor(SPF));
}
+std::pair<Intrinsic::ID, bool>
+llvm::canConvertToMinOrMaxIntrinsic(ArrayRef<Value *> VL) {
+ // Check if VL contains select instructions that can be folded into a min/max
+ // vector intrinsic and return the intrinsic if it is possible.
+ // TODO: Support floating point min/max.
+ bool AllCmpSingleUse = true;
+ SelectPatternResult SelectPattern;
+ SelectPattern.Flavor = SPF_UNKNOWN;
+ if (all_of(VL, [&SelectPattern, &AllCmpSingleUse](Value *I) {
+ Value *LHS, *RHS;
+ auto CurrentPattern = matchSelectPattern(I, LHS, RHS);
+ if (!SelectPatternResult::isMinOrMax(CurrentPattern.Flavor) ||
+ CurrentPattern.Flavor == SPF_FMINNUM ||
+ CurrentPattern.Flavor == SPF_FMAXNUM ||
+ !I->getType()->isIntOrIntVectorTy())
+ return false;
+ if (SelectPattern.Flavor != SPF_UNKNOWN &&
+ SelectPattern.Flavor != CurrentPattern.Flavor)
+ return false;
+ SelectPattern = CurrentPattern;
+ AllCmpSingleUse &=
+ match(I, m_Select(m_OneUse(m_Value()), m_Value(), m_Value()));
+ return true;
+ })) {
+ switch (SelectPattern.Flavor) {
+ case SPF_SMIN:
+ return {Intrinsic::smin, AllCmpSingleUse};
+ case SPF_UMIN:
+ return {Intrinsic::umin, AllCmpSingleUse};
+ case SPF_SMAX:
+ return {Intrinsic::smax, AllCmpSingleUse};
+ case SPF_UMAX:
+ return {Intrinsic::umax, AllCmpSingleUse};
+ default:
+ llvm_unreachable("unexpected select pattern flavor");
+ }
+ }
+ return {Intrinsic::not_intrinsic, false};
+}
+
/// Return true if "icmp Pred LHS RHS" is always true.
static bool isTruePredicate(CmpInst::Predicate Pred, const Value *LHS,
const Value *RHS, const DataLayout &DL,