[llvm] [InstCombine] Canonicalize the fcmp range check idiom into `fabs + fcmp` (PR #76367)
Yingwei Zheng via llvm-commits
llvm-commits at lists.llvm.org
Mon Feb 5 10:10:28 PST 2024
================
@@ -1419,6 +1419,45 @@ Value *InstCombinerImpl::foldLogicOfFCmps(FCmpInst *LHS, FCmpInst *RHS,
}
}
+ // Canonicalize the range check idiom:
+ // and (fcmp olt/ole/ult/ule x, C), (fcmp ogt/oge/ugt/uge x, -C)
+ // --> fabs(x) olt/ole/ult/ule C
+ // or (fcmp ogt/oge/ugt/uge x, C), (fcmp olt/ole/ult/ule x, -C)
+ // --> fabs(x) ogt/oge/ugt/uge C
+ // TODO: Generalize to handle a negated variable operand?
+ const APFloat *LHSC, *RHSC;
+ if (LHS0 == RHS0 && LHS->hasOneUse() && RHS->hasOneUse() &&
+ FCmpInst::getSwappedPredicate(PredL) == PredR &&
+ match(LHS1, m_APFloatAllowUndef(LHSC)) &&
+ match(RHS1, m_APFloatAllowUndef(RHSC)) &&
+ LHSC->bitwiseIsEqual(neg(*RHSC))) {
+ auto IsLessThanOrLessEqual = [](FCmpInst::Predicate Pred) {
+ switch (Pred) {
+ case FCmpInst::FCMP_OLT:
+ case FCmpInst::FCMP_OLE:
+ case FCmpInst::FCMP_ULT:
+ case FCmpInst::FCMP_ULE:
+ return true;
+ default:
+ return false;
+ }
+ };
+ if (IsLessThanOrLessEqual(IsAnd ? PredR : PredL)) {
+ std::swap(LHSC, RHSC);
+ std::swap(PredL, PredR);
+ }
+ if (IsLessThanOrLessEqual(IsAnd ? PredL : PredR)) {
+ BuilderTy::FastMathFlagGuard Guard(Builder);
+ FastMathFlags FMF = LHS->getFastMathFlags();
+ FMF |= RHS->getFastMathFlags();
+ Builder.setFastMathFlags(FMF);
----------------
dtcxzyw wrote:
Done.
https://github.com/llvm/llvm-project/pull/76367
More information about the llvm-commits
mailing list