[llvm] Optimize fptrunc(x)>=C1 --> x>=C2 (PR #99475)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Nov 7 17:14:41 PST 2024
================
@@ -7882,6 +7892,93 @@ static Instruction *foldFCmpReciprocalAndZero(FCmpInst &I, Instruction *LHSI,
return new FCmpInst(Pred, LHSI->getOperand(1), RHSC, "", &I);
}
+// Fold fptrunc(x) < constant --> x < constant if possible.
+static Instruction *foldFCmpFpTrunc(FCmpInst &I, Instruction *LHSI,
+ Constant *RHSC) {
+ FCmpInst::Predicate Pred = I.getPredicate();
+ bool RoundDown = false;
+
+ if (Pred == FCmpInst::FCMP_OGE || Pred == FCmpInst::FCMP_UGE ||
+ Pred == FCmpInst::FCMP_OLT || Pred == FCmpInst::FCMP_ULT)
+ RoundDown = true;
+ else if (Pred == FCmpInst::FCMP_OGT || Pred == FCmpInst::FCMP_UGT ||
+ Pred == FCmpInst::FCMP_OLE || Pred == FCmpInst::FCMP_ULE)
+ RoundDown = false;
+ else
+ return nullptr;
+
+ const APFloat *RValue;
+ if (!match(RHSC, m_APFloat(RValue)))
+ return nullptr;
+
+ // RHSC should not be nan or infinity.
+ if (RValue->isNaN() || RValue->isInfinity())
+ return nullptr;
+
+ Type *LType = LHSI->getOperand(0)->getType();
+ Type *RType = RHSC->getType();
+ Type *LEleType = LType->getScalarType();
+ Type *REleType = RType->getScalarType();
+
+ APFloat NextRValue = *RValue;
+ NextRValue.next(RoundDown);
+
+ // Round RValue to suitable value
+ APFloat ExtRValue = *RValue;
+ APFloat ExtNextRValue = NextRValue;
+ bool lossInfo;
+ ExtRValue.convert(LEleType->getFltSemantics(), APFloat::rmNearestTiesToEven,
+ &lossInfo);
+ ExtNextRValue.convert(LEleType->getFltSemantics(),
+ APFloat::rmNearestTiesToEven, &lossInfo);
+
+ // Binary search to find the maximal (or minimal) value after RValue promotion.
----------------
kissholic wrote:
std::lower_bound/std::upper_bound (or similar algorithm like std::binary_search) seems only accept [ForwardIt type](https://en.cppreference.com/w/cpp/algorithm/lower_bound) and there is likely no suitable substitution algorithm in LLVM too, which may requires constructing a new complex wrapper struct of APFloat, such as implementing name required iteration methods, calculating the mean of two APFloat (without constructing a new APFloat divisor), defining a comparation function and so on.
Considering the internal complexity of APFloat wrapper, it is simpler to keep the original one (i think)?
https://github.com/llvm/llvm-project/pull/99475
More information about the llvm-commits
mailing list