forked from OSchip/llvm-project
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. llvm-svn: 230564
This commit is contained in:
parent
3588686baf
commit
cc29f4f2cb
|
@ -2182,12 +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)) {
|
||||
// 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));
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue