Commit f3d46392 authored by Georg Neis's avatar Georg Neis Committed by Commit Bot

[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: 's avatarTobias Tebbi <tebbi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#68095}
parent e4cc52bf
...@@ -1042,8 +1042,11 @@ Type OperationTyper::NumberMax(Type lhs, Type rhs) { ...@@ -1042,8 +1042,11 @@ Type OperationTyper::NumberMax(Type lhs, Type rhs) {
} }
if (lhs.Maybe(Type::MinusZero()) || rhs.Maybe(Type::MinusZero())) { if (lhs.Maybe(Type::MinusZero()) || rhs.Maybe(Type::MinusZero())) {
type = Type::Union(type, Type::MinusZero(), zone()); 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) || if (!lhs.Is(cache_->kIntegerOrMinusZeroOrNaN) ||
!rhs.Is(cache_->kIntegerOrMinusZeroOrNaN)) { !rhs.Is(cache_->kIntegerOrMinusZeroOrNaN)) {
return Type::Union(type, Type::Union(lhs, rhs, zone()), zone()); return Type::Union(type, Type::Union(lhs, rhs, zone()), zone());
...@@ -1051,14 +1054,12 @@ Type OperationTyper::NumberMax(Type lhs, Type rhs) { ...@@ -1051,14 +1054,12 @@ Type OperationTyper::NumberMax(Type lhs, Type rhs) {
lhs = Type::Intersect(lhs, cache_->kInteger, zone()); lhs = Type::Intersect(lhs, cache_->kInteger, zone());
rhs = Type::Intersect(rhs, 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.Min(), rhs.Min());
double min = std::max(lhs.IsNone() ? -V8_INFINITY : lhs.Min(), double max = std::max(lhs.Max(), rhs.Max());
rhs.IsNone() ? -V8_INFINITY : rhs.Min()); type = Type::Union(type, Type::Range(min, max, zone()), zone());
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());
}
return type; return type;
} }
...@@ -1076,8 +1077,11 @@ Type OperationTyper::NumberMin(Type lhs, Type rhs) { ...@@ -1076,8 +1077,11 @@ Type OperationTyper::NumberMin(Type lhs, Type rhs) {
} }
if (lhs.Maybe(Type::MinusZero()) || rhs.Maybe(Type::MinusZero())) { if (lhs.Maybe(Type::MinusZero()) || rhs.Maybe(Type::MinusZero())) {
type = Type::Union(type, Type::MinusZero(), zone()); 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) || if (!lhs.Is(cache_->kIntegerOrMinusZeroOrNaN) ||
!rhs.Is(cache_->kIntegerOrMinusZeroOrNaN)) { !rhs.Is(cache_->kIntegerOrMinusZeroOrNaN)) {
return Type::Union(type, Type::Union(lhs, rhs, zone()), zone()); return Type::Union(type, Type::Union(lhs, rhs, zone()), zone());
...@@ -1085,14 +1089,12 @@ Type OperationTyper::NumberMin(Type lhs, Type rhs) { ...@@ -1085,14 +1089,12 @@ Type OperationTyper::NumberMin(Type lhs, Type rhs) {
lhs = Type::Intersect(lhs, cache_->kInteger, zone()); lhs = Type::Intersect(lhs, cache_->kInteger, zone());
rhs = Type::Intersect(rhs, 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.Min(), rhs.Min());
double min = std::min(lhs.IsNone() ? +V8_INFINITY : lhs.Min(), double max = std::min(lhs.Max(), rhs.Max());
rhs.IsNone() ? +V8_INFINITY : rhs.Min()); type = Type::Union(type, Type::Range(min, max, zone()), zone());
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());
}
return type; return type;
} }
......
...@@ -600,32 +600,38 @@ TEST_F(TyperTest, Manual_Operation_NumberMax) { ...@@ -600,32 +600,38 @@ TEST_F(TyperTest, Manual_Operation_NumberMax) {
Type b = t(Type::MinusZero(), zero_or_minuszero); Type b = t(Type::MinusZero(), zero_or_minuszero);
CHECK(Type::MinusZero().Is(b)); CHECK(Type::MinusZero().Is(b));
CHECK(zero.Is(b)); CHECK(zero.Is(b));
CHECK(a.Is(b)); CHECK(a.Is(b)); // Monotonicity.
Type c = t(zero_or_minuszero, Type::MinusZero()); Type c = t(zero_or_minuszero, Type::MinusZero());
CHECK(Type::MinusZero().Is(c)); CHECK(Type::MinusZero().Is(c));
CHECK(zero.Is(c)); CHECK(zero.Is(c));
CHECK(a.Is(c)); CHECK(a.Is(c)); // Monotonicity.
Type d = t(zero_or_minuszero, zero_or_minuszero); Type d = t(zero_or_minuszero, zero_or_minuszero);
CHECK(Type::MinusZero().Is(d)); CHECK(Type::MinusZero().Is(d));
CHECK(zero.Is(d)); CHECK(zero.Is(d));
CHECK(b.Is(d)); CHECK(b.Is(d)); // Monotonicity.
CHECK(c.Is(d)); CHECK(c.Is(d)); // Monotonicity.
Type e = Type e =
t(Type::MinusZero(), Type::Union(Type::MinusZero(), dot_five, zone())); t(Type::MinusZero(), Type::Union(Type::MinusZero(), dot_five, zone()));
CHECK(Type::MinusZero().Is(e)); CHECK(Type::MinusZero().Is(e));
CHECK(dot_five.Is(e)); CHECK(dot_five.Is(e));
CHECK(a.Is(e)); CHECK(a.Is(e)); // Monotonicity.
Type f = t(Type::MinusZero(), zero); Type f = t(Type::MinusZero(), zero);
CHECK(zero.Is(f)); CHECK(zero.Is(f));
CHECK(f.Is(b)); CHECK(f.Is(b)); // Monotonicity.
Type g = t(zero, Type::MinusZero()); Type g = t(zero, Type::MinusZero());
CHECK(zero.Is(g)); 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) { TEST_F(TyperTest, Manual_Operation_NumberMin) {
...@@ -644,35 +650,41 @@ TEST_F(TyperTest, Manual_Operation_NumberMin) { ...@@ -644,35 +650,41 @@ TEST_F(TyperTest, Manual_Operation_NumberMin) {
Type b = t(Type::MinusZero(), zero_or_minuszero); Type b = t(Type::MinusZero(), zero_or_minuszero);
CHECK(Type::MinusZero().Is(b)); CHECK(Type::MinusZero().Is(b));
CHECK(zero.Is(b)); CHECK(zero.Is(b));
CHECK(a.Is(b)); CHECK(a.Is(b)); // Monotonicity.
Type c = t(zero_or_minuszero, Type::MinusZero()); Type c = t(zero_or_minuszero, Type::MinusZero());
CHECK(Type::MinusZero().Is(c)); CHECK(Type::MinusZero().Is(c));
CHECK(zero.Is(c)); CHECK(zero.Is(c));
CHECK(a.Is(c)); CHECK(a.Is(c)); // Monotonicity.
Type d = t(zero_or_minuszero, zero_or_minuszero); Type d = t(zero_or_minuszero, zero_or_minuszero);
CHECK(Type::MinusZero().Is(d)); CHECK(Type::MinusZero().Is(d));
CHECK(zero.Is(d)); CHECK(zero.Is(d));
CHECK(b.Is(d)); CHECK(b.Is(d)); // Monotonicity.
CHECK(c.Is(d)); CHECK(c.Is(d)); // Monotonicity.
Type e = t(Type::MinusZero(), Type e = t(Type::MinusZero(),
Type::Union(Type::MinusZero(), minus_dot_five, zone())); Type::Union(Type::MinusZero(), minus_dot_five, zone()));
CHECK(Type::MinusZero().Is(e)); CHECK(Type::MinusZero().Is(e));
CHECK(minus_dot_five.Is(e)); CHECK(minus_dot_five.Is(e));
CHECK(a.Is(e)); CHECK(a.Is(e)); // Monotonicity.
Type f = t(Type::MinusZero(), zero); Type f = t(Type::MinusZero(), zero);
CHECK(Type::MinusZero().Is(f)); CHECK(Type::MinusZero().Is(f));
CHECK(f.Is(b)); CHECK(f.Is(b)); // Monotonicity.
Type g = t(zero, Type::MinusZero()); Type g = t(zero, Type::MinusZero());
CHECK(Type::MinusZero().Is(g)); CHECK(Type::MinusZero().Is(g));
CHECK(g.Is(c)); CHECK(g.Is(c)); // Monotonicity.
Type h = t(one, Type::MinusZero()); Type h = t(one, Type::MinusZero());
CHECK(Type::MinusZero().Is(h)); 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 } // namespace compiler
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment