[llvm] r230564 - only propagate equality comparisons of FP values that we are certain are non-zero

Sanjay Patel spatel at rotateright.com
Wed Feb 25 14:46:10 PST 2015


Author: spatel
Date: Wed Feb 25 16:46:08 2015
New Revision: 230564

URL: http://llvm.org/viewvc/llvm-project?rev=230564&view=rev
Log:
only propagate equality comparisons of FP values that we are certain are non-zero

This is a follow-on to r227491 which tightens the check for propagating FP
values. If a non-constant value happens to be a zero, we would hit the same
bug as before.

Bug noted and patch suggested by Eli Friedman.

Modified:
    llvm/trunk/lib/Transforms/Scalar/GVN.cpp
    llvm/trunk/test/Transforms/GVN/edge.ll

Modified: llvm/trunk/lib/Transforms/Scalar/GVN.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/GVN.cpp?rev=230564&r1=230563&r2=230564&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/GVN.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/GVN.cpp Wed Feb 25 16:46:08 2015
@@ -2182,12 +2182,16 @@ bool GVN::propagateEquality(Value *LHS,
       // Handle the floating point versions of equality comparisons too.
       if ((isKnownTrue && Cmp->getPredicate() == CmpInst::FCMP_OEQ) ||
           (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.
+
+        // Floating point -0.0 and 0.0 compare equal, so we can only
+        // propagate values if we know that we have a constant and that
+        // its value is non-zero.
+        
         // 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())
+
+        if (isa<ConstantFP>(Op1) && !cast<ConstantFP>(Op1)->isZero())
           Worklist.push_back(std::make_pair(Op0, Op1));
       }
  

Modified: llvm/trunk/test/Transforms/GVN/edge.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/GVN/edge.ll?rev=230564&r1=230563&r2=230564&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/GVN/edge.ll (original)
+++ llvm/trunk/test/Transforms/GVN/edge.ll Wed Feb 25 16:46:08 2015
@@ -59,7 +59,7 @@ bb2:
   ret void
 }
 
-define double @fcmp_oeq(double %x, double %y) {
+define double @fcmp_oeq_not_zero(double %x, double %y) {
 entry:
   %cmp = fcmp oeq double %y, 2.0
   br i1 %cmp, label %if, label %return
@@ -72,11 +72,11 @@ return:
   %retval = phi double [ %div, %if ], [ %x, %entry ]
   ret double %retval
 
-; CHECK-LABEL: define double @fcmp_oeq(
+; CHECK-LABEL: define double @fcmp_oeq_not_zero(
 ; CHECK: %div = fdiv double %x, 2.0
 }
 
-define double @fcmp_une(double %x, double %y) {
+define double @fcmp_une_not_zero(double %x, double %y) {
 entry:
   %cmp = fcmp une double %y, 2.0
   br i1 %cmp, label %return, label %else
@@ -89,7 +89,7 @@ return:
   %retval = phi double [ %div, %else ], [ %x, %entry ]
   ret double %retval
 
-; CHECK-LABEL: define double @fcmp_une(
+; CHECK-LABEL: define double @fcmp_une_not_zero(
 ; CHECK: %div = fdiv double %x, 2.0
 }
 
@@ -129,3 +129,42 @@ return:
 ; CHECK-LABEL: define double @fcmp_une_zero(
 ; CHECK: %div = fdiv double %x, %y
 }
+
+; We also cannot propagate a value if it's not a constant.
+; This is because the value could be 0.0 or -0.0.
+
+define double @fcmp_oeq_maybe_zero(double %x, double %y, double %z1, double %z2) {
+entry:
+ %z = fadd double %z1, %z2
+ %cmp = fcmp oeq double %y, %z
+ br i1 %cmp, label %if, label %return
+
+if:
+ %div = fdiv double %x, %z
+ br label %return
+
+return:
+ %retval = phi double [ %div, %if ], [ %x, %entry ]
+ ret double %retval
+
+; CHECK-LABEL: define double @fcmp_oeq_maybe_zero(
+; CHECK: %div = fdiv double %x, %z
+}
+
+define double @fcmp_une_maybe_zero(double %x, double %y, double %z1, double %z2) {
+entry:
+ %z = fadd double %z1, %z2
+ %cmp = fcmp une double %y, %z
+ br i1 %cmp, label %return, label %else
+
+else:
+ %div = fdiv double %x, %z
+ br label %return
+
+return:
+ %retval = phi double [ %div, %else ], [ %x, %entry ]
+ ret double %retval
+
+; CHECK-LABEL: define double @fcmp_une_maybe_zero(
+; CHECK: %div = fdiv double %x, %z
+}





More information about the llvm-commits mailing list