[InstSimplify] fold fcmp (maxnum, X, C1), C2

This is the sibling transform for rL360899 (D61691):

  maxnum(X, GreaterC) == C --> false
  maxnum(X, GreaterC) <= C --> false
  maxnum(X, GreaterC) <  C --> false
  maxnum(X, GreaterC) >= C --> true
  maxnum(X, GreaterC) >  C --> true
  maxnum(X, GreaterC) != C --> true

llvm-svn: 361118
diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp
index 95ba69d..f97daec 100644
--- a/llvm/lib/Analysis/InstructionSimplify.cpp
+++ b/llvm/lib/Analysis/InstructionSimplify.cpp
@@ -3435,28 +3435,38 @@
     }
 
     // Check comparison of constant with minnum with smaller constant.
-    // TODO: Add the related transform for maxnum.
-    const APFloat *MinC;
-    if (match(LHS,
-              m_Intrinsic<Intrinsic::minnum>(m_Value(), m_APFloat(MinC))) &&
-        MinC->compare(*C) == APFloat::cmpLessThan) {
-      // The 'less-than' relationship and minnum guarantee that we do not have
-      // NaN constants, so ordered and unordered preds are handled the same.
+    const APFloat *C2;
+    if ((match(LHS, m_Intrinsic<Intrinsic::minnum>(m_Value(), m_APFloat(C2))) &&
+         C2->compare(*C) == APFloat::cmpLessThan) ||
+        (match(LHS, m_Intrinsic<Intrinsic::maxnum>(m_Value(), m_APFloat(C2))) &&
+         C2->compare(*C) == APFloat::cmpGreaterThan)) {
+      bool IsMaxNum =
+          cast<IntrinsicInst>(LHS)->getIntrinsicID() == Intrinsic::maxnum;
+      // The ordered relationship and minnum/maxnum guarantee that we do not
+      // have NaN constants, so ordered/unordered preds are handled the same.
       switch (Pred) {
       case FCmpInst::FCMP_OEQ: case FCmpInst::FCMP_UEQ:
-      case FCmpInst::FCMP_OGE: case FCmpInst::FCMP_UGE:
-      case FCmpInst::FCMP_OGT: case FCmpInst::FCMP_UGT:
-        // minnum(X, LesserC) == C --> false
-        // minnum(X, LesserC) >= C --> false
-        // minnum(X, LesserC) >  C --> false
+        // minnum(X, LesserC)  == C --> false
+        // maxnum(X, GreaterC) == C --> false
         return getFalse(RetTy);
       case FCmpInst::FCMP_ONE: case FCmpInst::FCMP_UNE:
+        // minnum(X, LesserC)  != C --> true
+        // maxnum(X, GreaterC) != C --> true
+        return getTrue(RetTy);
+      case FCmpInst::FCMP_OGE: case FCmpInst::FCMP_UGE:
+      case FCmpInst::FCMP_OGT: case FCmpInst::FCMP_UGT:
+        // minnum(X, LesserC)  >= C --> false
+        // minnum(X, LesserC)  >  C --> false
+        // maxnum(X, GreaterC) >= C --> true
+        // maxnum(X, GreaterC) >  C --> true
+        return ConstantInt::get(RetTy, IsMaxNum);
       case FCmpInst::FCMP_OLE: case FCmpInst::FCMP_ULE:
       case FCmpInst::FCMP_OLT: case FCmpInst::FCMP_ULT:
-        // minnum(X, LesserC) != C --> true
-        // minnum(X, LesserC) <= C --> true
-        // minnum(X, LesserC) <  C --> true
-        return getTrue(RetTy);
+        // minnum(X, LesserC)  <= C --> true
+        // minnum(X, LesserC)  <  C --> true
+        // maxnum(X, GreaterC) <= C --> false
+        // maxnum(X, GreaterC) <  C --> false
+        return ConstantInt::get(RetTy, !IsMaxNum);
       default:
         // TRUE/FALSE/ORD/UNO should be handled before this.
         llvm_unreachable("Unexpected fcmp predicate");