Commit 0ac34190 authored by Hans Wennborg's avatar Hans Wennborg
Browse files

Merging r227491:

------------------------------------------------------------------------
r227491 | spatel | 2015-01-29 12:51:49 -0800 (Thu, 29 Jan 2015) | 13 lines

[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: 227537
parent 7fba80dd
Loading
Loading
Loading
Loading
+10 −3
Original line number Diff line number Diff line
@@ -2182,8 +2182,15 @@ 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))
          (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();
+42 −6
Original line number Diff line number Diff line
@@ -69,11 +69,11 @@ if:
  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,46 @@ else:
  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
}

define double @fcmp_une_zero(double %x, double %y) {
entry:
  %cmp = fcmp une double %y, -0.0
  br i1 %cmp, label %return, label %else

else:
  %div = fdiv double %x, %y
  br label %return

return:
  %retval = phi double [ %div, %else ], [ %x, %entry ]
  ret double %retval

; CHECK-LABEL: define double @fcmp_une_zero(
; CHECK: %div = fdiv double %x, %y
}