[llvm] Fdim constant fold (PR #109235)
Yingwei Zheng via llvm-commits
llvm-commits at lists.llvm.org
Thu Sep 19 00:58:29 PDT 2024
================
@@ -3080,6 +3080,41 @@ Value *LibCallSimplifier::optimizeRemquo(CallInst *CI, IRBuilderBase &B) {
return ConstantFP::get(CI->getType(), Rem);
}
+/// Constant folds fdim
+Value *LibCallSimplifier::optimizeFdim(CallInst *CI, IRBuilderBase &B) {
+ const APFloat *X, *Y;
+ // Check if both values are constants
+ if (!match(CI->getArgOperand(0), m_APFloat(X)) ||
+ !match(CI->getArgOperand(1), m_APFloat(Y)))
+ return nullptr;
+ // If either argument is NaN, NaN is returned
+ if (X->isNaN() || Y->isNaN())
+ return ConstantFP::getQNaN(CI->getType());
+
+ // If the difference if negative, return +0.0
+ if (*X <= *Y)
+ return ConstantFP::get(CI->getType(), 0.0);
+
+ APFloat ReturnVal = *X;
+ APFloat::opStatus Status =
+ ReturnVal.subtract(*Y, RoundingMode::NearestTiesToEven);
+ switch (Status) {
+ case APFloat::opStatus::opOK:
+ break;
+ case APFloat::opStatus::opOverflow:
+ return ConstantFP::get(
+ CI->getType(),
+ APFloat::getLargest(X->getSemantics(), /*Negative=*/false));
----------------
dtcxzyw wrote:
The result should be `inf`. Please add a tests for `fdim(1e308, -1e308)`.
BTW, it would be better to use `fmax(x - y, 0)` instead of handling all corner cases yourself.
https://github.com/llvm/llvm-project/pull/109235
More information about the llvm-commits
mailing list