diff options
author | Sanjay Patel <spatel@rotateright.com> | 2019-02-20 14:34:00 +0000 |
---|---|---|
committer | Sanjay Patel <spatel@rotateright.com> | 2019-02-20 14:34:00 +0000 |
commit | 68171e3cd6894db5a7e0d2fe4fe9094468588c77 (patch) | |
tree | 84bb9daab42ce291345029ba313f6037e9450e6d /llvm/lib/Analysis/InstructionSimplify.cpp | |
parent | 4f134fb66019d948d1f68d62a92f2a01b22eb7ee (diff) | |
download | bcm5719-llvm-68171e3cd6894db5a7e0d2fe4fe9094468588c77.tar.gz bcm5719-llvm-68171e3cd6894db5a7e0d2fe4fe9094468588c77.zip |
[InstSimplify] use any-zero matcher for fcmp folds
The m_APFloat matcher does not work with anything but strict
splat vector constants, so we could miss these folds and then
trigger an assertion in instcombine:
https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=13201
The previous attempt at this in rL354406 had a logic bug that
actually triggered a regression test failure, but I failed to
notice it the first time.
llvm-svn: 354467
Diffstat (limited to 'llvm/lib/Analysis/InstructionSimplify.cpp')
-rw-r--r-- | llvm/lib/Analysis/InstructionSimplify.cpp | 47 |
1 files changed, 25 insertions, 22 deletions
diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp index 843b3e97c07..ed857ddbc78 100644 --- a/llvm/lib/Analysis/InstructionSimplify.cpp +++ b/llvm/lib/Analysis/InstructionSimplify.cpp @@ -3648,6 +3648,8 @@ static Value *SimplifyFCmpInst(unsigned Predicate, Value *LHS, Value *RHS, } // Handle fcmp with constant RHS. + // TODO: Use match with a specific FP value, so these work with vectors with + // undef lanes. const APFloat *C; if (match(RHS, m_APFloat(C))) { // Check whether the constant is an infinity. @@ -3676,28 +3678,7 @@ static Value *SimplifyFCmpInst(unsigned Predicate, Value *LHS, Value *RHS, } } } - if (C->isZero()) { - switch (Pred) { - case FCmpInst::FCMP_OGE: - if (FMF.noNaNs() && CannotBeOrderedLessThanZero(LHS, Q.TLI)) - return getTrue(RetTy); - break; - case FCmpInst::FCMP_UGE: - if (CannotBeOrderedLessThanZero(LHS, Q.TLI)) - return getTrue(RetTy); - break; - case FCmpInst::FCMP_ULT: - if (FMF.noNaNs() && CannotBeOrderedLessThanZero(LHS, Q.TLI)) - return getFalse(RetTy); - break; - case FCmpInst::FCMP_OLT: - if (CannotBeOrderedLessThanZero(LHS, Q.TLI)) - return getFalse(RetTy); - break; - default: - break; - } - } else if (C->isNegative()) { + if (C->isNegative() && !C->isNegZero()) { assert(!C->isNaN() && "Unexpected NaN constant!"); // TODO: We can catch more cases by using a range check rather than // relying on CannotBeOrderedLessThanZero. @@ -3721,6 +3702,28 @@ static Value *SimplifyFCmpInst(unsigned Predicate, Value *LHS, Value *RHS, } } } + if (match(RHS, m_AnyZeroFP())) { + switch (Pred) { + case FCmpInst::FCMP_OGE: + if (FMF.noNaNs() && CannotBeOrderedLessThanZero(LHS, Q.TLI)) + return getTrue(RetTy); + break; + case FCmpInst::FCMP_UGE: + if (CannotBeOrderedLessThanZero(LHS, Q.TLI)) + return getTrue(RetTy); + break; + case FCmpInst::FCMP_ULT: + if (FMF.noNaNs() && CannotBeOrderedLessThanZero(LHS, Q.TLI)) + return getFalse(RetTy); + break; + case FCmpInst::FCMP_OLT: + if (CannotBeOrderedLessThanZero(LHS, Q.TLI)) + return getFalse(RetTy); + break; + default: + break; + } + } // If the comparison is with the result of a select instruction, check whether // comparing with either branch of the select always yields the same value. |