summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Analysis/InstructionSimplify.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Analysis/InstructionSimplify.cpp')
-rw-r--r--llvm/lib/Analysis/InstructionSimplify.cpp42
1 files changed, 26 insertions, 16 deletions
diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp
index 95ba69df6ba..f97daec9556 100644
--- a/llvm/lib/Analysis/InstructionSimplify.cpp
+++ b/llvm/lib/Analysis/InstructionSimplify.cpp
@@ -3435,28 +3435,38 @@ static Value *SimplifyFCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
}
// 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");
OpenPOWER on IntegriCloud