Skip to content

Commit 4858e9c

Browse files
authored
[InstCombine] Canonicalize the fcmp range check idiom into fabs + fcmp (#76367)
This patch canonicalizes the fcmp range check idiom into `fabs + fcmp` since the canonicalized form is better than the original form for the backends. Godbolt: https://godbolt.org/z/x3eqPb1fz ``` 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 ``` Alive2: https://alive2.llvm.org/ce/z/MRtoYq
1 parent 8bb827c commit 4858e9c

File tree

2 files changed

+399
-0
lines changed

2 files changed

+399
-0
lines changed

llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1419,6 +1419,44 @@ Value *InstCombinerImpl::foldLogicOfFCmps(FCmpInst *LHS, FCmpInst *RHS,
14191419
}
14201420
}
14211421

1422+
// Canonicalize the range check idiom:
1423+
// and (fcmp olt/ole/ult/ule x, C), (fcmp ogt/oge/ugt/uge x, -C)
1424+
// --> fabs(x) olt/ole/ult/ule C
1425+
// or (fcmp ogt/oge/ugt/uge x, C), (fcmp olt/ole/ult/ule x, -C)
1426+
// --> fabs(x) ogt/oge/ugt/uge C
1427+
// TODO: Generalize to handle a negated variable operand?
1428+
const APFloat *LHSC, *RHSC;
1429+
if (LHS0 == RHS0 && LHS->hasOneUse() && RHS->hasOneUse() &&
1430+
FCmpInst::getSwappedPredicate(PredL) == PredR &&
1431+
match(LHS1, m_APFloatAllowUndef(LHSC)) &&
1432+
match(RHS1, m_APFloatAllowUndef(RHSC)) &&
1433+
LHSC->bitwiseIsEqual(neg(*RHSC))) {
1434+
auto IsLessThanOrLessEqual = [](FCmpInst::Predicate Pred) {
1435+
switch (Pred) {
1436+
case FCmpInst::FCMP_OLT:
1437+
case FCmpInst::FCMP_OLE:
1438+
case FCmpInst::FCMP_ULT:
1439+
case FCmpInst::FCMP_ULE:
1440+
return true;
1441+
default:
1442+
return false;
1443+
}
1444+
};
1445+
if (IsLessThanOrLessEqual(IsAnd ? PredR : PredL)) {
1446+
std::swap(LHSC, RHSC);
1447+
std::swap(PredL, PredR);
1448+
}
1449+
if (IsLessThanOrLessEqual(IsAnd ? PredL : PredR)) {
1450+
BuilderTy::FastMathFlagGuard Guard(Builder);
1451+
Builder.setFastMathFlags(LHS->getFastMathFlags() |
1452+
RHS->getFastMathFlags());
1453+
1454+
Value *FAbs = Builder.CreateUnaryIntrinsic(Intrinsic::fabs, LHS0);
1455+
return Builder.CreateFCmp(PredL, FAbs,
1456+
ConstantFP::get(LHS0->getType(), *LHSC));
1457+
}
1458+
}
1459+
14221460
return nullptr;
14231461
}
14241462

0 commit comments

Comments
 (0)