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

minnum(X, LesserC) == C --> false
   minnum(X, LesserC) >= C --> false
   minnum(X, LesserC) >  C --> false
   minnum(X, LesserC) != C --> true
   minnum(X, LesserC) <= C --> true
   minnum(X, LesserC) <  C --> true

maxnum siblings will follow if there are no problems here.

We should be able to perform some other combines when the constants
are equal or greater-than too, but that would go in instcombine.

We might also generalize this by creating an FP ConstantRange
(similar to what we do for integers).

Differential Revision: https://reviews.llvm.org/D61691

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@360899 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Sanjay Patel
2019-05-16 14:03:10 +00:00
parent 1b057e5bee
commit 90a7bd7e82
2 changed files with 82 additions and 35 deletions
+30
View File
@@ -3433,7 +3433,37 @@ static Value *SimplifyFCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
break;
}
}
// 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.
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
return getFalse(RetTy);
case FCmpInst::FCMP_ONE: case FCmpInst::FCMP_UNE:
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);
default:
// TRUE/FALSE/ORD/UNO should be handled before this.
llvm_unreachable("Unexpected fcmp predicate");
}
}
}
if (match(RHS, m_AnyZeroFP())) {
switch (Pred) {
case FCmpInst::FCMP_OGE: