[InstCombine] refactor fabs+fcmp fold; NFC

Also, remove/replace/minimize/enhance the tests for this fold.
The code drops FMF, so it needs more tests and at least 1 fix.

llvm-svn: 345734
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
index 1ad648f..9155ad1 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -5288,6 +5288,46 @@
   return NewFCI;
 }
 
+/// Optimize fabs(X) compared with zero.
+static Instruction *foldFabsWithFcmpZero(FCmpInst &I) {
+  Value *X;
+  if (!match(I.getOperand(0), m_Intrinsic<Intrinsic::fabs>(m_Value(X))) ||
+      !match(I.getOperand(1), m_PosZeroFP()))
+    return nullptr;
+
+  switch (I.getPredicate()) {
+  case FCmpInst::FCMP_UGE:
+  case FCmpInst::FCMP_OLT:
+    // fabs(X) >= 0.0 --> true
+    // fabs(X) <  0.0 --> false
+    llvm_unreachable("fcmp should have simplified");
+
+  case FCmpInst::FCMP_OGT:
+    // fabs(X) > 0.0 --> X != 0.0
+    return new FCmpInst(FCmpInst::FCMP_ONE, X, I.getOperand(1));
+
+  case FCmpInst::FCMP_OLE:
+    // fabs(X) <= 0.0 --> X == 0.0
+    return new FCmpInst(FCmpInst::FCMP_OEQ, X, I.getOperand(1));
+
+  case FCmpInst::FCMP_OGE:
+    // fabs(X) >= 0.0 --> !isnan(X)
+    assert(!I.hasNoNaNs() && "fcmp should have simplified");
+    return new FCmpInst(FCmpInst::FCMP_ORD, X, I.getOperand(1));
+
+  case FCmpInst::FCMP_OEQ:
+  case FCmpInst::FCMP_UEQ:
+  case FCmpInst::FCMP_ONE:
+  case FCmpInst::FCMP_UNE:
+    // fabs(X) == 0.0 --> X == 0.0
+    // fabs(X) != 0.0 --> X != 0.0
+    return new FCmpInst(I.getPredicate(), X, I.getOperand(1));
+
+  default:
+    return nullptr;
+  }
+}
+
 Instruction *InstCombiner::visitFCmpInst(FCmpInst &I) {
   bool Changed = false;
 
@@ -5418,45 +5458,11 @@
             if (Instruction *Res = foldCmpLoadFromIndexedGlobal(GEP, GV, I))
               return Res;
       break;
-    case Instruction::Call: {
-      if (!RHSC->isNullValue())
-        break;
-
-      CallInst *CI = cast<CallInst>(LHSI);
-      Intrinsic::ID IID = getIntrinsicForCallSite(CI, &TLI);
-      if (IID != Intrinsic::fabs)
-        break;
-
-      // Various optimization for fabs compared with zero.
-      switch (Pred) {
-      default:
-        break;
-      case FCmpInst::FCMP_UGE:
-      case FCmpInst::FCMP_OLT:
-        // fabs(x) >= 0.0 --> true
-        // fabs(x) <  0.0 --> false
-        llvm_unreachable("fcmp should have simplified");
-
-      // fabs(x) > 0 --> x != 0
-      case FCmpInst::FCMP_OGT:
-        return new FCmpInst(FCmpInst::FCMP_ONE, CI->getArgOperand(0), RHSC);
-      // fabs(x) <= 0 --> x == 0
-      case FCmpInst::FCMP_OLE:
-        return new FCmpInst(FCmpInst::FCMP_OEQ, CI->getArgOperand(0), RHSC);
-      // fabs(x) >= 0 --> !isnan(x)
-      case FCmpInst::FCMP_OGE:
-        assert(!I.hasNoNaNs() && "fcmp should have simplified");
-        return new FCmpInst(FCmpInst::FCMP_ORD, CI->getArgOperand(0), RHSC);
-      // fabs(x) == 0 --> x == 0
-      // fabs(x) != 0 --> x != 0
-      case FCmpInst::FCMP_OEQ:
-      case FCmpInst::FCMP_UEQ:
-      case FCmpInst::FCMP_ONE:
-      case FCmpInst::FCMP_UNE:
-        return new FCmpInst(Pred, CI->getArgOperand(0), RHSC);
-      }
-    }
-    }
+    case Instruction::Call:
+      if (Instruction *X = foldFabsWithFcmpZero(I))
+        return X;
+      break;
+  }
   }
 
   // fcmp pred (fneg x), (fneg y) -> fcmp swap(pred) x, y