Index: src/compiler/typer.cc |
diff --git a/src/compiler/typer.cc b/src/compiler/typer.cc |
index 4d57144809da3eb16e2c5d2bca379c8777319c6d..055feea02c81e691ee43dcdf2f51ec810e0b55fc 100644 |
--- a/src/compiler/typer.cc |
+++ b/src/compiler/typer.cc |
@@ -255,6 +255,8 @@ class Typer::Visitor : public Reducer { |
static Type* ToString(Type*, Typer*); |
static Type* NumberCeil(Type*, Typer*); |
static Type* NumberFloor(Type*, Typer*); |
+ static Type* NumberMax(Type*, Type*, Typer*); |
+ static Type* NumberMin(Type*, Type*, Typer*); |
static Type* NumberRound(Type*, Typer*); |
static Type* NumberSign(Type*, Typer*); |
static Type* NumberTrunc(Type*, Typer*); |
@@ -506,6 +508,54 @@ Type* Typer::Visitor::NumberFloor(Type* type, Typer* t) { |
} |
// static |
+Type* Typer::Visitor::NumberMax(Type* lhs, Type* rhs, Typer* t) { |
+ DCHECK(lhs->Is(Type::Number())); |
+ DCHECK(rhs->Is(Type::Number())); |
+ if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) { |
+ return Type::NaN(); |
+ } |
+ Type* type = Type::None(); |
+ // TODO(turbofan): Improve minus zero handling here. |
+ if (lhs->Maybe(Type::NaN()) || rhs->Maybe(Type::NaN())) { |
+ type = Type::Union(type, Type::NaN(), t->zone()); |
+ } |
+ lhs = Type::Intersect(lhs, Type::OrderedNumber(), t->zone()); |
+ rhs = Type::Intersect(rhs, Type::OrderedNumber(), t->zone()); |
+ if (lhs->Is(t->cache_.kInteger) && rhs->Is(t->cache_.kInteger)) { |
+ double max = std::max(lhs->Max(), rhs->Max()); |
+ double min = std::max(lhs->Min(), rhs->Min()); |
+ type = Type::Union(type, Type::Range(min, max, t->zone()), t->zone()); |
+ } else { |
+ type = Type::Union(type, Type::Union(lhs, rhs, t->zone()), t->zone()); |
+ } |
+ return type; |
+} |
+ |
+// static |
+Type* Typer::Visitor::NumberMin(Type* lhs, Type* rhs, Typer* t) { |
+ DCHECK(lhs->Is(Type::Number())); |
+ DCHECK(rhs->Is(Type::Number())); |
+ if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) { |
+ return Type::NaN(); |
+ } |
+ Type* type = Type::None(); |
+ // TODO(turbofan): Improve minus zero handling here. |
+ if (lhs->Maybe(Type::NaN()) || rhs->Maybe(Type::NaN())) { |
+ type = Type::Union(type, Type::NaN(), t->zone()); |
+ } |
+ lhs = Type::Intersect(lhs, Type::OrderedNumber(), t->zone()); |
+ rhs = Type::Intersect(rhs, Type::OrderedNumber(), t->zone()); |
+ if (lhs->Is(t->cache_.kInteger) && rhs->Is(t->cache_.kInteger)) { |
+ double max = std::min(lhs->Max(), rhs->Max()); |
+ double min = std::min(lhs->Min(), rhs->Min()); |
+ type = Type::Union(type, Type::Range(min, max, t->zone()), t->zone()); |
+ } else { |
+ type = Type::Union(type, Type::Union(lhs, rhs, t->zone()), t->zone()); |
+ } |
+ return type; |
+} |
+ |
+// static |
Type* Typer::Visitor::NumberRound(Type* type, Typer* t) { |
DCHECK(type->Is(Type::Number())); |
if (type->Is(t->cache_.kIntegerOrMinusZeroOrNaN)) return type; |
@@ -1672,6 +1722,14 @@ Type* Typer::Visitor::TypeNumberLog10(Node* node) { return Type::Number(); } |
Type* Typer::Visitor::TypeNumberCbrt(Node* node) { return Type::Number(); } |
+Type* Typer::Visitor::TypeNumberMax(Node* node) { |
+ return TypeBinaryOp(node, NumberMax); |
+} |
+ |
+Type* Typer::Visitor::TypeNumberMin(Node* node) { |
+ return TypeBinaryOp(node, NumberMin); |
+} |
+ |
Type* Typer::Visitor::TypeNumberPow(Node* node) { return Type::Number(); } |
Type* Typer::Visitor::TypeNumberRound(Node* node) { |
@@ -2268,12 +2326,6 @@ Type* Typer::Visitor::TypeFloat32Mul(Node* node) { return Type::Number(); } |
Type* Typer::Visitor::TypeFloat32Div(Node* node) { return Type::Number(); } |
-Type* Typer::Visitor::TypeFloat32Max(Node* node) { return Type::Number(); } |
- |
- |
-Type* Typer::Visitor::TypeFloat32Min(Node* node) { return Type::Number(); } |
- |
- |
Type* Typer::Visitor::TypeFloat32Abs(Node* node) { |
// TODO(turbofan): We should be able to infer a better type here. |
return Type::Number(); |