[PATCH] [GVN} don't propagate equality comparisons of FP zero (PR22376)
Sanjay Patel
spatel at rotateright.com
Thu Jan 29 09:40:21 PST 2015
Hi pete, ArchDRobison, hfinkel,
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. As shown in http://llvm.org/bugs/show_bug.cgi?id=22376, we can miscompile with the current optimization.
I also checked to make sure that NaN comparisons are handled, and they always appear to be correctly optimized by SimplifyInstruction.
http://reviews.llvm.org/D7257
Files:
lib/Transforms/Scalar/GVN.cpp
test/Transforms/GVN/edge.ll
Index: lib/Transforms/Scalar/GVN.cpp
===================================================================
--- lib/Transforms/Scalar/GVN.cpp
+++ lib/Transforms/Scalar/GVN.cpp
@@ -2182,9 +2182,13 @@
// 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.
+ 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);
Index: test/Transforms/GVN/edge.ll
===================================================================
--- test/Transforms/GVN/edge.ll
+++ test/Transforms/GVN/edge.ll
@@ -69,11 +69,11 @@
br label %return
return:
- %retval.0 = phi double [ %div, %if ], [ %x, %entry ]
- ret double %retval.0
+ %retval = phi double [ %div, %if ], [ %x, %entry ]
+ ret double %retval
; CHECK-LABEL: define double @fcmp_oeq(
-; CHECK: %div = fdiv double %x, 2.000000e+00
+; CHECK: %div = fdiv double %x, 2.0
}
define double @fcmp_une(double %x, double %y) {
@@ -86,10 +86,30 @@
br label %return
return:
- %retval.0 = phi double [ %div, %else ], [ %x, %entry ]
- ret double %retval.0
+ %retval = phi double [ %div, %else ], [ %x, %entry ]
+ ret double %retval
; CHECK-LABEL: define double @fcmp_une(
-; CHECK: %div = fdiv double %x, 2.000000e+00
+; CHECK: %div = fdiv double %x, 2.0
+}
+
+; PR22376 - We can't propagate zero constants because -0.0
+; compares equal to 0.0. If %y is -0.0 in this test case,
+; we would produce the wrong sign on the infinity return value.
+define double @fcmp_oeq_zero(double %x, double %y) {
+entry:
+ %cmp = fcmp oeq double %y, 0.0
+ br i1 %cmp, label %if, label %return
+
+if:
+ %div = fdiv double %x, %y
+ br label %return
+
+return:
+ %retval = phi double [ %div, %if ], [ %x, %entry ]
+ ret double %retval
+
+; CHECK-LABEL: define double @fcmp_oeq_zero(
+; CHECK: %div = fdiv double %x, %y
}
EMAIL PREFERENCES
http://reviews.llvm.org/settings/panel/emailpreferences/
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D7257.18971.patch
Type: text/x-patch
Size: 2475 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20150129/4651d39e/attachment.bin>
More information about the llvm-commits
mailing list