[llvm] [InstCombine] Enable more fabs fold when the user ignores sign bit of zero/NaN (PR #139861)

Yingwei Zheng via llvm-commits llvm-commits at lists.llvm.org
Wed May 21 06:47:32 PDT 2025


================
@@ -2802,16 +2817,46 @@ static bool ignoreSignBitOfNaN(Instruction &I) {
   // Check if the sign bit is ignored by the only user.
   if (!I.hasOneUse())
     return false;
-  Instruction *User = I.user_back();
-
-  // fcmp ignores the sign bit of NaN.
-  if (User->getOpcode() == Instruction::FCmp)
+  auto *FPOp = dyn_cast<FPMathOperator>(I.user_back());
+  if (!FPOp)
+    return false;
+  if (FPOp->hasNoNaNs())
     return true;
 
-  if (auto *FPOp = dyn_cast<FPMathOperator>(User))
-    return FPOp->hasNoNaNs();
-
-  return false;
+  switch (FPOp->getOpcode()) {
+  case Instruction::FNeg:
+  case Instruction::Select:
+  case Instruction::PHI:
+    return false;
+  case Instruction::Call: {
+    if (auto *II = dyn_cast<IntrinsicInst>(FPOp)) {
+      switch (II->getIntrinsicID()) {
+      case Intrinsic::fabs:
+        return true;
+      case Intrinsic::copysign:
+        return II->getArgOperand(0) == &I;
+      // fmin/fmax returns one of its operands, so the sign bit cannot be
+      // ignored.
+      case Intrinsic::maxnum:
+      case Intrinsic::minnum:
+      case Intrinsic::maximum:
+      case Intrinsic::minimum:
+      case Intrinsic::maximumnum:
+      case Intrinsic::minimumnum:
+      // llvm.canonicalize preserves the sign bit of NaN.
+      case Intrinsic::canonicalize:
+        return false;
+      default:
+        // Other proper FP intrinsics ignore the sign bit of NaN.
+        return true;
----------------
dtcxzyw wrote:

> I'd leave the generalized handling for a later patch. This should also be conservatively correct by default, and require explicit handling of every intrinsic

Reverted for now.


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


More information about the llvm-commits mailing list