[llvm] [SimplifyLibCalls] fdim constant fold (PR #109235)

Andy Kaylor via llvm-commits llvm-commits at lists.llvm.org
Fri Sep 27 11:26:48 PDT 2024


================
@@ -3109,6 +3109,33 @@ 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());
+
+  IRBuilderBase::FastMathFlagGuard Guard(B);
+  FastMathFlags FMF = CI->getFastMathFlags();
+  // set no-NaN fast-math-flag as we already checked for NaN for both operands
+  FMF.setNoNaNs();
+  // set no-signed-zeroes as fdim will never return -0.0
+  FMF.setNoSignedZeros();
+  B.setFastMathFlags(FMF);
+  // fdim is equivalent to fmax(x - y, 0), except for the NaN handling
----------------
andykaylor wrote:

I think you can only do this if you know that math errno isn't being used. fdim sets errno on range errors, but the fmax intrinsic does not. An example that shows this is fdim(1e308, -1e308);

https://github.com/llvm/llvm-project/pull/109235


More information about the llvm-commits mailing list