summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms
diff options
context:
space:
mode:
authorSanjay Patel <spatel@rotateright.com>2015-01-29 20:51:49 +0000
committerSanjay Patel <spatel@rotateright.com>2015-01-29 20:51:49 +0000
commit4f07a56958fa1a26024d1f43bd8cc1dee8816d5e (patch)
treeefde8ddb6fe3fcb584af2ba4d25d3ed4ff17b549 /llvm/lib/Transforms
parent03b968e89874e4fe8f76f6b7f2345086d353f962 (diff)
downloadbcm5719-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.cpp13
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);
OpenPOWER on IntegriCloud