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

Matt Arsenault via llvm-commits llvm-commits at lists.llvm.org
Tue Oct 8 14:02:10 PDT 2024


================
@@ -3109,6 +3109,52 @@ Value *LibCallSimplifier::optimizeRemquo(CallInst *CI, IRBuilderBase &B) {
   return ConstantFP::get(CI->getType(), Rem);
 }
 
+/// Constant folds fdim
+Value *LibCallSimplifier::optimizeFdim(CallInst *CI, IRBuilderBase &B) {
+  // Cannot perform the fold unless the call has attribute memory(none)
+  if (!CI->doesNotAccessMemory())
+    return nullptr;
+
+  // propogate poison/undef if any
+  if (match(CI->getArgOperand(0), m_Undef()))
+    return CI->getArgOperand(0);
+  if (match(CI->getArgOperand(1), m_Undef()))
+    return CI->getArgOperand(1);
+
+  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())
+    return ConstantFP::get(CI->getType(), X->makeQuiet());
+  if (Y->isNaN())
+    return ConstantFP::get(CI->getType(), Y->makeQuiet());
+
+  // if X - Y overflows, it will set the errno, so we avoid the fold
+  APFloat Difference = *X;
+  APFloat::opStatus Status =
+      Difference.subtract(*Y, RoundingMode::NearestTiesToEven);
+  switch (Status) {
+  case APFloat::opStatus::opOK:
+  case APFloat::opStatus::opInexact:
+  case APFloat::opStatus::opUnderflow:
+    break;
+  case APFloat::opStatus::opOverflow:
+  case APFloat::opStatus::opInvalidOp:
+  case APFloat::opStatus::opDivByZero:
+    return nullptr;
+  }
+  auto *FSubCall =
+      copyFlags(*CI, B.CreateFSub(CI->getOperand(0), CI->getOperand(1)));
----------------
arsenm wrote:

You did the subtract above, but then throw it away to create fsub which will constant fold.

If you want to only handle this as constant folding, you should use the APFloat Difference, and then use APFloat version of maximum. 

Something like minimum(Difference, APFloat::getZero())

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


More information about the llvm-commits mailing list