summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Analysis/InstructionSimplify.cpp
diff options
context:
space:
mode:
authorSanjay Patel <spatel@rotateright.com>2019-05-16 14:03:10 +0000
committerSanjay Patel <spatel@rotateright.com>2019-05-16 14:03:10 +0000
commit152f81fae80eb415cc09073f03125836216c8df9 (patch)
tree0dd4e13d83b980b13003c3778d08cd8d9ea2f0b1 /llvm/lib/Analysis/InstructionSimplify.cpp
parent2dee094a08ff4e244e8df046f3b1d6445e707b77 (diff)
downloadbcm5719-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.cpp30
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:
OpenPOWER on IntegriCloud