diff options
author | Sanjay Patel <spatel@rotateright.com> | 2015-01-29 20:51:49 +0000 |
---|---|---|
committer | Sanjay Patel <spatel@rotateright.com> | 2015-01-29 20:51:49 +0000 |
commit | 4f07a56958fa1a26024d1f43bd8cc1dee8816d5e (patch) | |
tree | efde8ddb6fe3fcb584af2ba4d25d3ed4ff17b549 /llvm/lib/Transforms | |
parent | 03b968e89874e4fe8f76f6b7f2345086d353f962 (diff) | |
download | bcm5719-llvm-4f07a56958fa1a26024d1f43bd8cc1dee8816d5e.tar.gz bcm5719-llvm-4f07a56958fa1a26024d1f43bd8cc1dee8816d5e.zip |
[GVN] don't propagate equality comparisons of FP zero (PR22376)
In http://reviews.llvm.org/D6911, we allowed GVN to propagate FP equalities
to allow some simple value range optimizations. But that introduced a bug
when comparing to -0.0 or 0.0: these compare equal even though they are not
bitwise identical.
This patch disallows propagating zero constants in equality comparisons.
Fixes: http://llvm.org/bugs/show_bug.cgi?id=22376
Differential Revision: http://reviews.llvm.org/D7257
llvm-svn: 227491
Diffstat (limited to 'llvm/lib/Transforms')
-rw-r--r-- | llvm/lib/Transforms/Scalar/GVN.cpp | 13 |
1 files changed, 10 insertions, 3 deletions
diff --git a/llvm/lib/Transforms/Scalar/GVN.cpp b/llvm/lib/Transforms/Scalar/GVN.cpp index 29ea432e4a4..7519b598659 100644 --- a/llvm/lib/Transforms/Scalar/GVN.cpp +++ b/llvm/lib/Transforms/Scalar/GVN.cpp @@ -2182,9 +2182,16 @@ bool GVN::propagateEquality(Value *LHS, Value *RHS, // Handle the floating point versions of equality comparisons too. if ((isKnownTrue && Cmp->getPredicate() == CmpInst::FCMP_OEQ) || - (isKnownFalse && Cmp->getPredicate() == CmpInst::FCMP_UNE)) - Worklist.push_back(std::make_pair(Op0, Op1)); - + (isKnownFalse && Cmp->getPredicate() == CmpInst::FCMP_UNE)) { + // Floating point -0.0 and 0.0 compare equal, so we can't + // propagate a constant based on that comparison. + // FIXME: We should do this optimization if 'no signed zeros' is + // applicable via an instruction-level fast-math-flag or some other + // indicator that relaxed FP semantics are being used. + if (!isa<ConstantFP>(Op1) || !cast<ConstantFP>(Op1)->isZero()) + Worklist.push_back(std::make_pair(Op0, Op1)); + } + // If "A >= B" is known true, replace "A < B" with false everywhere. CmpInst::Predicate NotPred = Cmp->getInversePredicate(); Constant *NotVal = ConstantInt::get(Cmp->getType(), isKnownFalse); |