[turbofan] Fix a typer monotonicity bug

Bug: chromium:1085804
Change-Id: I98f12da97334bd5fd32bd01b1eca56be895dc0a8
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2218286
Commit-Queue: Georg Neis <neis@chromium.org>
Reviewed-by: Tobias Tebbi <tebbi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#68095}
This commit is contained in:
Georg Neis 2020-06-02 11:42:19 +02:00 committed by Commit Bot
parent e4cc52bfeb
commit f3d463923e
2 changed files with 44 additions and 30 deletions

View File

@ -1042,8 +1042,11 @@ Type OperationTyper::NumberMax(Type lhs, Type rhs) {
}
if (lhs.Maybe(Type::MinusZero()) || rhs.Maybe(Type::MinusZero())) {
type = Type::Union(type, Type::MinusZero(), zone());
// In order to ensure monotonicity of the computation below, we additionally
// pretend +0 is present (for simplicity on both sides).
lhs = Type::Union(lhs, cache_->kSingletonZero, zone());
rhs = Type::Union(rhs, cache_->kSingletonZero, zone());
}
if (!lhs.Is(cache_->kIntegerOrMinusZeroOrNaN) ||
!rhs.Is(cache_->kIntegerOrMinusZeroOrNaN)) {
return Type::Union(type, Type::Union(lhs, rhs, zone()), zone());
@ -1051,14 +1054,12 @@ Type OperationTyper::NumberMax(Type lhs, Type rhs) {
lhs = Type::Intersect(lhs, cache_->kInteger, zone());
rhs = Type::Intersect(rhs, cache_->kInteger, zone());
DCHECK(!lhs.IsNone());
DCHECK(!rhs.IsNone());
if (!lhs.IsNone() || !rhs.IsNone()) {
double min = std::max(lhs.IsNone() ? -V8_INFINITY : lhs.Min(),
rhs.IsNone() ? -V8_INFINITY : rhs.Min());
double max = std::max(lhs.IsNone() ? -V8_INFINITY : lhs.Max(),
rhs.IsNone() ? -V8_INFINITY : rhs.Max());
type = Type::Union(type, Type::Range(min, max, zone()), zone());
}
double min = std::max(lhs.Min(), rhs.Min());
double max = std::max(lhs.Max(), rhs.Max());
type = Type::Union(type, Type::Range(min, max, zone()), zone());
return type;
}
@ -1076,8 +1077,11 @@ Type OperationTyper::NumberMin(Type lhs, Type rhs) {
}
if (lhs.Maybe(Type::MinusZero()) || rhs.Maybe(Type::MinusZero())) {
type = Type::Union(type, Type::MinusZero(), zone());
// In order to ensure monotonicity of the computation below, we additionally
// pretend +0 is present (for simplicity on both sides).
lhs = Type::Union(lhs, cache_->kSingletonZero, zone());
rhs = Type::Union(rhs, cache_->kSingletonZero, zone());
}
if (!lhs.Is(cache_->kIntegerOrMinusZeroOrNaN) ||
!rhs.Is(cache_->kIntegerOrMinusZeroOrNaN)) {
return Type::Union(type, Type::Union(lhs, rhs, zone()), zone());
@ -1085,14 +1089,12 @@ Type OperationTyper::NumberMin(Type lhs, Type rhs) {
lhs = Type::Intersect(lhs, cache_->kInteger, zone());
rhs = Type::Intersect(rhs, cache_->kInteger, zone());
DCHECK(!lhs.IsNone());
DCHECK(!rhs.IsNone());
if (!lhs.IsNone() || !rhs.IsNone()) {
double min = std::min(lhs.IsNone() ? +V8_INFINITY : lhs.Min(),
rhs.IsNone() ? +V8_INFINITY : rhs.Min());
double max = std::min(lhs.IsNone() ? +V8_INFINITY : lhs.Max(),
rhs.IsNone() ? +V8_INFINITY : rhs.Max());
type = Type::Union(type, Type::Range(min, max, zone()), zone());
}
double min = std::min(lhs.Min(), rhs.Min());
double max = std::min(lhs.Max(), rhs.Max());
type = Type::Union(type, Type::Range(min, max, zone()), zone());
return type;
}

View File

@ -600,32 +600,38 @@ TEST_F(TyperTest, Manual_Operation_NumberMax) {
Type b = t(Type::MinusZero(), zero_or_minuszero);
CHECK(Type::MinusZero().Is(b));
CHECK(zero.Is(b));
CHECK(a.Is(b));
CHECK(a.Is(b)); // Monotonicity.
Type c = t(zero_or_minuszero, Type::MinusZero());
CHECK(Type::MinusZero().Is(c));
CHECK(zero.Is(c));
CHECK(a.Is(c));
CHECK(a.Is(c)); // Monotonicity.
Type d = t(zero_or_minuszero, zero_or_minuszero);
CHECK(Type::MinusZero().Is(d));
CHECK(zero.Is(d));
CHECK(b.Is(d));
CHECK(c.Is(d));
CHECK(b.Is(d)); // Monotonicity.
CHECK(c.Is(d)); // Monotonicity.
Type e =
t(Type::MinusZero(), Type::Union(Type::MinusZero(), dot_five, zone()));
CHECK(Type::MinusZero().Is(e));
CHECK(dot_five.Is(e));
CHECK(a.Is(e));
CHECK(a.Is(e)); // Monotonicity.
Type f = t(Type::MinusZero(), zero);
CHECK(zero.Is(f));
CHECK(f.Is(b));
CHECK(f.Is(b)); // Monotonicity.
Type g = t(zero, Type::MinusZero());
CHECK(zero.Is(g));
CHECK(g.Is(c));
CHECK(g.Is(c)); // Monotonicity.
Type h = t(Type::Signed32(), Type::MinusZero());
CHECK(Type::MinusZero().Is(h));
Type i = t(Type::Signed32(), zero_or_minuszero);
CHECK(h.Is(i)); // Monotonicity.
}
TEST_F(TyperTest, Manual_Operation_NumberMin) {
@ -644,35 +650,41 @@ TEST_F(TyperTest, Manual_Operation_NumberMin) {
Type b = t(Type::MinusZero(), zero_or_minuszero);
CHECK(Type::MinusZero().Is(b));
CHECK(zero.Is(b));
CHECK(a.Is(b));
CHECK(a.Is(b)); // Monotonicity.
Type c = t(zero_or_minuszero, Type::MinusZero());
CHECK(Type::MinusZero().Is(c));
CHECK(zero.Is(c));
CHECK(a.Is(c));
CHECK(a.Is(c)); // Monotonicity.
Type d = t(zero_or_minuszero, zero_or_minuszero);
CHECK(Type::MinusZero().Is(d));
CHECK(zero.Is(d));
CHECK(b.Is(d));
CHECK(c.Is(d));
CHECK(b.Is(d)); // Monotonicity.
CHECK(c.Is(d)); // Monotonicity.
Type e = t(Type::MinusZero(),
Type::Union(Type::MinusZero(), minus_dot_five, zone()));
CHECK(Type::MinusZero().Is(e));
CHECK(minus_dot_five.Is(e));
CHECK(a.Is(e));
CHECK(a.Is(e)); // Monotonicity.
Type f = t(Type::MinusZero(), zero);
CHECK(Type::MinusZero().Is(f));
CHECK(f.Is(b));
CHECK(f.Is(b)); // Monotonicity.
Type g = t(zero, Type::MinusZero());
CHECK(Type::MinusZero().Is(g));
CHECK(g.Is(c));
CHECK(g.Is(c)); // Monotonicity.
Type h = t(one, Type::MinusZero());
CHECK(Type::MinusZero().Is(h));
Type i = t(Type::Signed32(), Type::MinusZero());
CHECK(Type::MinusZero().Is(i));
Type j = t(Type::Signed32(), zero_or_minuszero);
CHECK(i.Is(j)); // Monotonicity.
}
} // namespace compiler