diff options
author | Sanjay Patel <spatel@rotateright.com> | 2019-05-16 14:03:10 +0000 |
---|---|---|
committer | Sanjay Patel <spatel@rotateright.com> | 2019-05-16 14:03:10 +0000 |
commit | 152f81fae80eb415cc09073f03125836216c8df9 (patch) | |
tree | 0dd4e13d83b980b13003c3778d08cd8d9ea2f0b1 /llvm/lib/Analysis/InstructionSimplify.cpp | |
parent | 2dee094a08ff4e244e8df046f3b1d6445e707b77 (diff) | |
download | bcm5719-llvm-152f81fae80eb415cc09073f03125836216c8df9.tar.gz bcm5719-llvm-152f81fae80eb415cc09073f03125836216c8df9.zip |
[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
llvm-svn: 360899
Diffstat (limited to 'llvm/lib/Analysis/InstructionSimplify.cpp')
-rw-r--r-- | llvm/lib/Analysis/InstructionSimplify.cpp | 30 |
1 files changed, 30 insertions, 0 deletions
diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp index 770fdf9054c..f1ec7b36a93 100644 --- a/llvm/lib/Analysis/InstructionSimplify.cpp +++ b/llvm/lib/Analysis/InstructionSimplify.cpp @@ -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: |