Fix and cleanup can_be_minus_zero computation

R=rossberg@chromium.org

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@15546 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 67d9051b
......@@ -1745,9 +1745,10 @@ Range* HValue::InferRange(Zone* zone) {
result = new(zone) Range(Smi::kMinValue, Smi::kMaxValue);
result->set_can_be_minus_zero(false);
} else {
// Untagged integer32 cannot be -0, all other representations can.
result = new(zone) Range();
result->set_can_be_minus_zero(!representation().IsInteger32());
result->set_can_be_minus_zero(!CheckFlag(kAllUsesTruncatingToInt32));
// TODO(jkummerow): The range cannot be minus zero when the upper type
// bound is Integer32.
}
return result;
}
......@@ -1765,7 +1766,8 @@ Range* HChange::InferRange(Zone* zone) {
Range* result = (input_range != NULL)
? input_range->Copy(zone)
: HValue::InferRange(zone);
if (to().IsInteger32()) result->set_can_be_minus_zero(false);
result->set_can_be_minus_zero(!to().IsSmiOrInteger32() ||
!CheckFlag(kAllUsesTruncatingToInt32));
return result;
}
......@@ -1810,9 +1812,8 @@ Range* HAdd::InferRange(Zone* zone) {
CheckFlag(kAllUsesTruncatingToInt32)) {
ClearFlag(kCanOverflow);
}
if (!CheckFlag(kAllUsesTruncatingToInt32)) {
res->set_can_be_minus_zero(a->CanBeMinusZero() && b->CanBeMinusZero());
}
res->set_can_be_minus_zero(!CheckFlag(kAllUsesTruncatingToInt32) &&
a->CanBeMinusZero() && b->CanBeMinusZero());
return res;
} else {
return HValue::InferRange(zone);
......@@ -1829,9 +1830,8 @@ Range* HSub::InferRange(Zone* zone) {
CheckFlag(kAllUsesTruncatingToInt32)) {
ClearFlag(kCanOverflow);
}
if (!CheckFlag(kAllUsesTruncatingToInt32)) {
res->set_can_be_minus_zero(a->CanBeMinusZero() && b->CanBeZero());
}
res->set_can_be_minus_zero(!CheckFlag(kAllUsesTruncatingToInt32) &&
a->CanBeMinusZero() && b->CanBeZero());
return res;
} else {
return HValue::InferRange(zone);
......@@ -1850,11 +1850,9 @@ Range* HMul::InferRange(Zone* zone) {
// precise and therefore not the same as converting to Double and back.
ClearFlag(kCanOverflow);
}
if (!CheckFlag(kAllUsesTruncatingToInt32)) {
bool m0 = (a->CanBeZero() && b->CanBeNegative()) ||
(a->CanBeNegative() && b->CanBeZero());
res->set_can_be_minus_zero(m0);
}
res->set_can_be_minus_zero(!CheckFlag(kAllUsesTruncatingToInt32) &&
((a->CanBeZero() && b->CanBeNegative()) ||
(a->CanBeNegative() && b->CanBeZero())));
return res;
} else {
return HValue::InferRange(zone);
......@@ -1867,16 +1865,9 @@ Range* HDiv::InferRange(Zone* zone) {
Range* a = left()->range();
Range* b = right()->range();
Range* result = new(zone) Range();
if (!CheckFlag(kAllUsesTruncatingToInt32)) {
if (a->CanBeMinusZero()) {
result->set_can_be_minus_zero(true);
}
if (a->CanBeZero() && b->CanBeNegative()) {
result->set_can_be_minus_zero(true);
}
}
result->set_can_be_minus_zero(!CheckFlag(kAllUsesTruncatingToInt32) &&
(a->CanBeMinusZero() ||
(a->CanBeZero() && b->CanBeNegative())));
if (!a->Includes(kMinInt) || !b->Includes(-1)) {
ClearFlag(HValue::kCanOverflow);
}
......@@ -1906,9 +1897,8 @@ Range* HMod::InferRange(Zone* zone) {
Range* result = new(zone) Range(left_can_be_negative ? -positive_bound : 0,
a->CanBePositive() ? positive_bound : 0);
if (left_can_be_negative && !CheckFlag(kAllUsesTruncatingToInt32)) {
result->set_can_be_minus_zero(true);
}
result->set_can_be_minus_zero(!CheckFlag(kAllUsesTruncatingToInt32) &&
left_can_be_negative);
if (!a->Includes(kMinInt) || !b->Includes(-1)) {
ClearFlag(HValue::kCanOverflow);
......@@ -2458,7 +2448,9 @@ Range* HBitwise::InferRange(Zone* zone) {
? static_cast<int32_t>(-limit) : 0;
return new(zone) Range(min, static_cast<int32_t>(limit - 1));
}
return HValue::InferRange(zone);
Range* result = HValue::InferRange(zone);
result->set_can_be_minus_zero(false);
return result;
}
const int32_t kDefaultMask = static_cast<int32_t>(0xffffffff);
int32_t left_mask = (left()->range() != NULL)
......@@ -2470,9 +2462,11 @@ Range* HBitwise::InferRange(Zone* zone) {
int32_t result_mask = (op() == Token::BIT_AND)
? left_mask & right_mask
: left_mask | right_mask;
return (result_mask >= 0)
? new(zone) Range(0, result_mask)
: HValue::InferRange(zone);
if (result_mask >= 0) return new(zone) Range(0, result_mask);
Range* result = HValue::InferRange(zone);
result->set_can_be_minus_zero(false);
return result;
}
......@@ -2484,7 +2478,6 @@ Range* HSar::InferRange(Zone* zone) {
? left()->range()->Copy(zone)
: new(zone) Range();
result->Sar(c->Integer32Value());
result->set_can_be_minus_zero(false);
return result;
}
}
......@@ -2509,7 +2502,6 @@ Range* HShr::InferRange(Zone* zone) {
? left()->range()->Copy(zone)
: new(zone) Range();
result->Sar(c->Integer32Value());
result->set_can_be_minus_zero(false);
return result;
}
}
......@@ -2526,7 +2518,6 @@ Range* HShl::InferRange(Zone* zone) {
? left()->range()->Copy(zone)
: new(zone) Range();
result->Shl(c->Integer32Value());
result->set_can_be_minus_zero(false);
return result;
}
}
......
// Copyright 2013 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Flags: --allow-natives-syntax
function add(x, y) {
return x + y;
}
assertEquals(0, add(0, 0));
assertEquals(0, add(0, 0));
%OptimizeFunctionOnNextCall(add);
assertEquals(-0, add(-0, -0));
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