Commit 0c355790 authored by bmeurer's avatar bmeurer Committed by Commit bot

[crankshaft] Fix invalid ToNumber optimization.

We cannot optimize away ToNumber conversions based on the Type that we
see in Crankshaft, as this might be the (unchecked or even pretruncated)
lower bound. We can only use the HType, which is based on the definition.

R=jkummerow@chromium.org
BUG=chromium:590989
LOG=n

Review URL: https://codereview.chromium.org/1757013002

Cr-Commit-Position: refs/heads/master@{#34445}
parent 017375f3
......@@ -2050,9 +2050,8 @@ HValue* HGraphBuilder::BuildNumberToString(HValue* object, Type* type) {
return Pop();
}
HValue* HGraphBuilder::BuildToNumber(HValue* input, Type* input_type) {
if (input->type().IsTaggedNumber() || input_type->Is(Type::Number())) {
HValue* HGraphBuilder::BuildToNumber(HValue* input) {
if (input->type().IsTaggedNumber()) {
return input;
}
Callable callable = CodeFactory::ToNumber(isolate());
......@@ -11081,10 +11080,10 @@ HValue* HGraphBuilder::BuildBinaryOperation(Token::Value op, HValue* left,
// Special case for +x here.
if (op == Token::MUL) {
if (left->EqualsInteger32Constant(1)) {
return BuildToNumber(right, right_type);
return BuildToNumber(right);
}
if (right->EqualsInteger32Constant(1)) {
return BuildToNumber(left, left_type);
return BuildToNumber(left);
}
}
......@@ -12307,8 +12306,7 @@ void HOptimizedGraphBuilder::GenerateToNumber(CallRuntime* call) {
CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
Callable callable = CodeFactory::ToNumber(isolate());
HValue* input = Pop();
Type* input_type = Type::Any();
HValue* result = BuildToNumber(input, input_type);
HValue* result = BuildToNumber(input);
if (result->HasObservableSideEffects()) {
if (!ast_context()->IsEffect()) Push(result);
Add<HSimulate>(call->id(), REMOVABLE_SIMULATE);
......
......@@ -1318,7 +1318,7 @@ class HGraphBuilder {
bool is_jsarray);
HValue* BuildNumberToString(HValue* object, Type* type);
HValue* BuildToNumber(HValue* input, Type* input_type);
HValue* BuildToNumber(HValue* input);
HValue* BuildToObject(HValue* receiver);
void BuildJSObjectCheck(HValue* receiver,
......
// Copyright 2016 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --allow-natives-syntax
var o = {}
var p = {foo: 1.5}
function g(x) { return x.foo === +x.foo; }
assertEquals(false, g(o));
assertEquals(false, g(o));
%OptimizeFunctionOnNextCall(g);
assertEquals(false, g(o)); // Still fine here.
assertEquals(true, g(p));
%OptimizeFunctionOnNextCall(g);
assertEquals(false, g(o)); // Confused by type feedback.
// Copyright 2016 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --allow-natives-syntax
function f(x) { return x === +x; }
assertEquals(false, f(undefined));
assertEquals(false, f(undefined));
%OptimizeFunctionOnNextCall(f);
assertEquals(false, f(undefined)); // Interestingly this fails right away.
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