mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-11-01 15:11:24 +00:00
[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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@227491 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
1b7b2597d5
commit
26c81cc870
@ -2182,9 +2182,16 @@ bool GVN::propagateEquality(Value *LHS, Value *RHS,
|
|||||||
|
|
||||||
// Handle the floating point versions of equality comparisons too.
|
// Handle the floating point versions of equality comparisons too.
|
||||||
if ((isKnownTrue && Cmp->getPredicate() == CmpInst::FCMP_OEQ) ||
|
if ((isKnownTrue && Cmp->getPredicate() == CmpInst::FCMP_OEQ) ||
|
||||||
(isKnownFalse && Cmp->getPredicate() == CmpInst::FCMP_UNE))
|
(isKnownFalse && Cmp->getPredicate() == CmpInst::FCMP_UNE)) {
|
||||||
Worklist.push_back(std::make_pair(Op0, Op1));
|
// 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.
|
// If "A >= B" is known true, replace "A < B" with false everywhere.
|
||||||
CmpInst::Predicate NotPred = Cmp->getInversePredicate();
|
CmpInst::Predicate NotPred = Cmp->getInversePredicate();
|
||||||
Constant *NotVal = ConstantInt::get(Cmp->getType(), isKnownFalse);
|
Constant *NotVal = ConstantInt::get(Cmp->getType(), isKnownFalse);
|
||||||
|
@ -69,11 +69,11 @@ if:
|
|||||||
br label %return
|
br label %return
|
||||||
|
|
||||||
return:
|
return:
|
||||||
%retval.0 = phi double [ %div, %if ], [ %x, %entry ]
|
%retval = phi double [ %div, %if ], [ %x, %entry ]
|
||||||
ret double %retval.0
|
ret double %retval
|
||||||
|
|
||||||
; CHECK-LABEL: define double @fcmp_oeq(
|
; 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) {
|
define double @fcmp_une(double %x, double %y) {
|
||||||
@ -86,10 +86,46 @@ else:
|
|||||||
br label %return
|
br label %return
|
||||||
|
|
||||||
return:
|
return:
|
||||||
%retval.0 = phi double [ %div, %else ], [ %x, %entry ]
|
%retval = phi double [ %div, %else ], [ %x, %entry ]
|
||||||
ret double %retval.0
|
ret double %retval
|
||||||
|
|
||||||
; CHECK-LABEL: define double @fcmp_une(
|
; 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
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user