diff options
author | Sanjay Patel <spatel@rotateright.com> | 2022-08-25 15:43:39 -0400 |
---|---|---|
committer | Sanjay Patel <spatel@rotateright.com> | 2022-08-25 16:52:40 -0400 |
commit | 4e44c22c97be99f7c3864fb9fc68b3295835d837 (patch) | |
tree | 15f81c836778b364b8b64402c7c36155ef9c3a25 /llvm/lib/Analysis/ValueTracking.cpp | |
parent | 681b97e5869d49b1e5163534811f370ba5ac0e40 (diff) | |
download | llvm-4e44c22c97be99f7c3864fb9fc68b3295835d837.zip llvm-4e44c22c97be99f7c3864fb9fc68b3295835d837.tar.gz llvm-4e44c22c97be99f7c3864fb9fc68b3295835d837.tar.bz2 |
[ValueTracking][InstCombine] restrict FP min/max matching to avoid miscompile
This is a long-standing FIXME with a non-FMF test that exposes
the bug as shown in issue #57357.
It's possible that there's still a way to miscompile by
mis-identifying/mis-folding FP min/max patterns, but
this patch only exposes a couple of seemingly minor
regressions while preventing the broken transform.
Diffstat (limited to 'llvm/lib/Analysis/ValueTracking.cpp')
-rw-r--r-- | llvm/lib/Analysis/ValueTracking.cpp | 15 |
1 files changed, 12 insertions, 3 deletions
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index b2393de..5f22714 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -6085,6 +6085,7 @@ static SelectPatternResult matchSelectPattern(CmpInst::Predicate Pred, Value *TrueVal, Value *FalseVal, Value *&LHS, Value *&RHS, unsigned Depth) { + bool HasMismatchedZeros = false; if (CmpInst::isFPPredicate(Pred)) { // IEEE-754 ignores the sign of 0.0 in comparisons. So if the select has one // 0.0 operand, set the compare's 0.0 operands to that same value for the @@ -6099,10 +6100,14 @@ static SelectPatternResult matchSelectPattern(CmpInst::Predicate Pred, OutputZeroVal = FalseVal; if (OutputZeroVal) { - if (match(CmpLHS, m_AnyZeroFP())) + if (match(CmpLHS, m_AnyZeroFP()) && CmpLHS != OutputZeroVal) { + HasMismatchedZeros = true; CmpLHS = OutputZeroVal; - if (match(CmpRHS, m_AnyZeroFP())) + } + if (match(CmpRHS, m_AnyZeroFP()) && CmpRHS != OutputZeroVal) { + HasMismatchedZeros = true; CmpRHS = OutputZeroVal; + } } } @@ -6116,7 +6121,11 @@ static SelectPatternResult matchSelectPattern(CmpInst::Predicate Pred, // operands is known to not be zero or if we don't care about signed zero. switch (Pred) { default: break; - // FIXME: Include OGT/OLT/UGT/ULT. + case CmpInst::FCMP_OGT: case CmpInst::FCMP_OLT: + case CmpInst::FCMP_UGT: case CmpInst::FCMP_ULT: + if (!HasMismatchedZeros) + break; + [[fallthrough]]; case CmpInst::FCMP_OGE: case CmpInst::FCMP_OLE: case CmpInst::FCMP_UGE: case CmpInst::FCMP_ULE: if (!FMF.noSignedZeros() && !isKnownNonZero(CmpLHS) && |