Skip to content
This repository was archived by the owner on Feb 5, 2019. It is now read-only.

Commit 76a77fb

Browse files
committed
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 ------------------------------------------------------------------------ git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/release_36@227537 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 65794dd commit 76a77fb

File tree

2 files changed

+52
-9
lines changed

2 files changed

+52
-9
lines changed

lib/Transforms/Scalar/GVN.cpp

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2182,9 +2182,16 @@ bool GVN::propagateEquality(Value *LHS, Value *RHS,
21822182

21832183
// Handle the floating point versions of equality comparisons too.
21842184
if ((isKnownTrue && Cmp->getPredicate() == CmpInst::FCMP_OEQ) ||
2185-
(isKnownFalse && Cmp->getPredicate() == CmpInst::FCMP_UNE))
2186-
Worklist.push_back(std::make_pair(Op0, Op1));
2187-
2185+
(isKnownFalse && Cmp->getPredicate() == CmpInst::FCMP_UNE)) {
2186+
// Floating point -0.0 and 0.0 compare equal, so we can't
2187+
// propagate a constant based on that comparison.
2188+
// FIXME: We should do this optimization if 'no signed zeros' is
2189+
// applicable via an instruction-level fast-math-flag or some other
2190+
// indicator that relaxed FP semantics are being used.
2191+
if (!isa<ConstantFP>(Op1) || !cast<ConstantFP>(Op1)->isZero())
2192+
Worklist.push_back(std::make_pair(Op0, Op1));
2193+
}
2194+
21882195
// If "A >= B" is known true, replace "A < B" with false everywhere.
21892196
CmpInst::Predicate NotPred = Cmp->getInversePredicate();
21902197
Constant *NotVal = ConstantInt::get(Cmp->getType(), isKnownFalse);

test/Transforms/GVN/edge.ll

Lines changed: 42 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -69,11 +69,11 @@ if:
6969
br label %return
7070

7171
return:
72-
%retval.0 = phi double [ %div, %if ], [ %x, %entry ]
73-
ret double %retval.0
72+
%retval = phi double [ %div, %if ], [ %x, %entry ]
73+
ret double %retval
7474

7575
; CHECK-LABEL: define double @fcmp_oeq(
76-
; CHECK: %div = fdiv double %x, 2.000000e+00
76+
; CHECK: %div = fdiv double %x, 2.0
7777
}
7878

7979
define double @fcmp_une(double %x, double %y) {
@@ -86,10 +86,46 @@ else:
8686
br label %return
8787

8888
return:
89-
%retval.0 = phi double [ %div, %else ], [ %x, %entry ]
90-
ret double %retval.0
89+
%retval = phi double [ %div, %else ], [ %x, %entry ]
90+
ret double %retval
9191

9292
; CHECK-LABEL: define double @fcmp_une(
93-
; CHECK: %div = fdiv double %x, 2.000000e+00
93+
; CHECK: %div = fdiv double %x, 2.0
9494
}
9595

96+
; PR22376 - We can't propagate zero constants because -0.0
97+
; compares equal to 0.0. If %y is -0.0 in this test case,
98+
; we would produce the wrong sign on the infinity return value.
99+
define double @fcmp_oeq_zero(double %x, double %y) {
100+
entry:
101+
%cmp = fcmp oeq double %y, 0.0
102+
br i1 %cmp, label %if, label %return
103+
104+
if:
105+
%div = fdiv double %x, %y
106+
br label %return
107+
108+
return:
109+
%retval = phi double [ %div, %if ], [ %x, %entry ]
110+
ret double %retval
111+
112+
; CHECK-LABEL: define double @fcmp_oeq_zero(
113+
; CHECK: %div = fdiv double %x, %y
114+
}
115+
116+
define double @fcmp_une_zero(double %x, double %y) {
117+
entry:
118+
%cmp = fcmp une double %y, -0.0
119+
br i1 %cmp, label %return, label %else
120+
121+
else:
122+
%div = fdiv double %x, %y
123+
br label %return
124+
125+
return:
126+
%retval = phi double [ %div, %else ], [ %x, %entry ]
127+
ret double %retval
128+
129+
; CHECK-LABEL: define double @fcmp_une_zero(
130+
; CHECK: %div = fdiv double %x, %y
131+
}

0 commit comments

Comments
 (0)