diff options
author | Florian Hahn <flo@fhahn.com> | 2020-10-31 10:51:19 +0000 |
---|---|---|
committer | Florian Hahn <flo@fhahn.com> | 2020-10-31 16:52:36 +0000 |
commit | 799033d8c569616fbf7c829f2e9b01d5adf4cd6f (patch) | |
tree | db3fbe5d2a9268cc9221815b28d6e06bc160b0d1 /llvm/lib/Analysis/ValueTracking.cpp | |
parent | b231396122f131ffaff5fc4ba36685a7df554aaa (diff) | |
download | llvm-799033d8c569616fbf7c829f2e9b01d5adf4cd6f.zip llvm-799033d8c569616fbf7c829f2e9b01d5adf4cd6f.tar.gz llvm-799033d8c569616fbf7c829f2e9b01d5adf4cd6f.tar.bz2 |
Reland "[SLP] Consider alternatives for cost of select instructions."
This reverts the revert commit a1b53db32418cb6ed6f5b2054d15a22b5aa3aeb9.
This patch includes a fix for a reported issue, caused by
matchSelectPattern returning UMIN for selects of pointers in
some cases by looking to some connected casts.
For now, ensure integer instrinsics are only returned for selects of
ints or int vectors.
Diffstat (limited to 'llvm/lib/Analysis/ValueTracking.cpp')
-rw-r--r-- | llvm/lib/Analysis/ValueTracking.cpp | 40 |
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, |