[turbofan] Fix handling of null in -0 == null comparison
TurboFan truncated null to +0 even in contexts such as -0 == null because it was not handling the TypeCheck correctly. This restricts the type conversion case to not apply truncation in this case (see comment in patch). Change-Id: Ia38ace9608800c8d61988de402a31dd863d9160a Bug: chromium:961237 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1609538 Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Commit-Queue: Sigurd Schneider <sigurds@chromium.org> Cr-Commit-Position: refs/heads/master@{#61446}
This commit is contained in:
parent
c5a16a397e
commit
210856603f
@ -863,8 +863,17 @@ Node* RepresentationChanger::GetFloat64RepresentationFor(
|
||||
op = machine()->ChangeInt32ToFloat64();
|
||||
} else if (output_type.Is(Type::Number())) {
|
||||
op = simplified()->ChangeTaggedToFloat64();
|
||||
} else if (output_type.Is(Type::NumberOrOddball())) {
|
||||
// TODO(jarin) Here we should check that truncation is Number.
|
||||
} else if ((output_type.Is(Type::NumberOrOddball()) &&
|
||||
use_info.truncation().IsUsedAsFloat64()) ||
|
||||
output_type.Is(Type::NumberOrHole())) {
|
||||
// JavaScript 'null' is an Oddball that results in +0 when truncated to
|
||||
// Number. In a context like -0 == null, which must evaluate to false,
|
||||
// this truncation must not happen. For this reason we restrict this case
|
||||
// to when either the user explicitly requested a float (and thus wants
|
||||
// +0 if null is the input) or we know from the types that the input can
|
||||
// only be Number | Hole. The latter is necessary to handle the operator
|
||||
// CheckFloat64Hole. We did not put in the type (Number | Oddball \ Null)
|
||||
// to discover more bugs related to this conversion via crashes.
|
||||
op = simplified()->TruncateTaggedToFloat64();
|
||||
} else if (use_info.type_check() == TypeCheckKind::kNumber ||
|
||||
(use_info.type_check() == TypeCheckKind::kNumberOrOddball &&
|
||||
|
@ -544,7 +544,7 @@ TEST(SingleChanges) {
|
||||
Type::Number(), MachineRepresentation::kFloat64);
|
||||
CheckChange(IrOpcode::kTruncateTaggedToFloat64,
|
||||
MachineRepresentation::kTagged, Type::NumberOrUndefined(),
|
||||
MachineRepresentation::kFloat64);
|
||||
UseInfo(MachineRepresentation::kFloat64, Truncation::Float64()));
|
||||
CheckChange(IrOpcode::kChangeTaggedToFloat64, MachineRepresentation::kTagged,
|
||||
Type::Signed31(), MachineRepresentation::kFloat64);
|
||||
|
||||
|
15
test/mjsunit/regress/regress-961237.js
Normal file
15
test/mjsunit/regress/regress-961237.js
Normal file
@ -0,0 +1,15 @@
|
||||
// Copyright 2019 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
|
||||
|
||||
const a = 1.1;
|
||||
const b = null;
|
||||
|
||||
function f(x) { return -0 == (x ? a : b); }
|
||||
%PrepareFunctionForOptimization(f);
|
||||
assertEquals(false, f(true));
|
||||
assertEquals(false, f(true));
|
||||
%OptimizeFunctionOnNextCall(f);
|
||||
assertEquals(false, f(false));
|
Loading…
Reference in New Issue
Block a user