aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Analysis/ValueTracking.cpp
diff options
context:
space:
mode:
authorSanjay Patel <spatel@rotateright.com>2022-08-25 15:43:39 -0400
committerSanjay Patel <spatel@rotateright.com>2022-08-25 16:52:40 -0400
commit4e44c22c97be99f7c3864fb9fc68b3295835d837 (patch)
tree15f81c836778b364b8b64402c7c36155ef9c3a25 /llvm/lib/Analysis/ValueTracking.cpp
parent681b97e5869d49b1e5163534811f370ba5ac0e40 (diff)
downloadllvm-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.cpp15
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) &&