[turbofan] Properly turn Number.min(-0,+0) into -0.

Previously the simplified operation `Number.min(x,y)` would lower to
`Select(Float64LessThan(x, y), x, y)` which would yield `y` when both
`x` and `y` are zeros, specifically when `x` was -0 and `y` was +0.
For `NumberMin` we need to use `Float64LessThanOrEqual` since we
generally allow -0 on the left hand side (in SimplifiedLowering).

Bug: chromium:906870
Change-Id: I25ae8fb19608b77c90ed130e69d9d9fa93fcea9d
Reviewed-on: https://chromium-review.googlesource.com/c/1342920
Commit-Queue: Benedikt Meurer <bmeurer@chromium.org>
Reviewed-by: Jaroslav Sevcik <jarin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#57633}
This commit is contained in:
Benedikt Meurer 2018-11-20 09:59:35 +01:00 committed by Commit Bot
parent 2603bb051e
commit 154cb3f318
2 changed files with 51 additions and 1 deletions

View File

@ -2359,7 +2359,8 @@ class RepresentationSelector {
rhs_type.Is(truncation.IdentifiesZeroAndMinusZero()
? Type::OrderedNumber()
: Type::PlainNumber())) {
lowering->DoMin(node, lowering->machine()->Float64LessThan(),
lowering->DoMin(node,
lowering->machine()->Float64LessThanOrEqual(),
MachineRepresentation::kFloat64);
} else {
NodeProperties::ChangeOp(node, Float64Op(node));

View File

@ -0,0 +1,49 @@
// Copyright 2018 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() {
function foo() {
return Infinity / Math.max(-0, +0);
}
assertEquals(+Infinity, foo());
assertEquals(+Infinity, foo());
%OptimizeFunctionOnNextCall(foo);
assertEquals(+Infinity, foo());
})();
(function() {
function foo() {
return Infinity / Math.max(+0, -0);
}
assertEquals(+Infinity, foo());
assertEquals(+Infinity, foo());
%OptimizeFunctionOnNextCall(foo);
assertEquals(+Infinity, foo());
})();
(function() {
function foo() {
return Infinity / Math.min(-0, +0);
}
assertEquals(-Infinity, foo());
assertEquals(-Infinity, foo());
%OptimizeFunctionOnNextCall(foo);
assertEquals(-Infinity, foo());
})();
(function() {
function foo() {
return Infinity / Math.min(+0, -0);
}
assertEquals(-Infinity, foo());
assertEquals(-Infinity, foo());
%OptimizeFunctionOnNextCall(foo);
assertEquals(-Infinity, foo());
})();