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) { ...@@ -1745,9 +1745,10 @@ Range* HValue::InferRange(Zone* zone) {
result = new(zone) Range(Smi::kMinValue, Smi::kMaxValue); result = new(zone) Range(Smi::kMinValue, Smi::kMaxValue);
result->set_can_be_minus_zero(false); result->set_can_be_minus_zero(false);
} else { } else {
// Untagged integer32 cannot be -0, all other representations can.
result = new(zone) Range(); 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; return result;
} }
...@@ -1765,7 +1766,8 @@ Range* HChange::InferRange(Zone* zone) { ...@@ -1765,7 +1766,8 @@ Range* HChange::InferRange(Zone* zone) {
Range* result = (input_range != NULL) Range* result = (input_range != NULL)
? input_range->Copy(zone) ? input_range->Copy(zone)
: HValue::InferRange(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; return result;
} }
...@@ -1810,9 +1812,8 @@ Range* HAdd::InferRange(Zone* zone) { ...@@ -1810,9 +1812,8 @@ Range* HAdd::InferRange(Zone* zone) {
CheckFlag(kAllUsesTruncatingToInt32)) { CheckFlag(kAllUsesTruncatingToInt32)) {
ClearFlag(kCanOverflow); ClearFlag(kCanOverflow);
} }
if (!CheckFlag(kAllUsesTruncatingToInt32)) { res->set_can_be_minus_zero(!CheckFlag(kAllUsesTruncatingToInt32) &&
res->set_can_be_minus_zero(a->CanBeMinusZero() && b->CanBeMinusZero()); a->CanBeMinusZero() && b->CanBeMinusZero());
}
return res; return res;
} else { } else {
return HValue::InferRange(zone); return HValue::InferRange(zone);
...@@ -1829,9 +1830,8 @@ Range* HSub::InferRange(Zone* zone) { ...@@ -1829,9 +1830,8 @@ Range* HSub::InferRange(Zone* zone) {
CheckFlag(kAllUsesTruncatingToInt32)) { CheckFlag(kAllUsesTruncatingToInt32)) {
ClearFlag(kCanOverflow); ClearFlag(kCanOverflow);
} }
if (!CheckFlag(kAllUsesTruncatingToInt32)) { res->set_can_be_minus_zero(!CheckFlag(kAllUsesTruncatingToInt32) &&
res->set_can_be_minus_zero(a->CanBeMinusZero() && b->CanBeZero()); a->CanBeMinusZero() && b->CanBeZero());
}
return res; return res;
} else { } else {
return HValue::InferRange(zone); return HValue::InferRange(zone);
...@@ -1850,11 +1850,9 @@ Range* HMul::InferRange(Zone* zone) { ...@@ -1850,11 +1850,9 @@ Range* HMul::InferRange(Zone* zone) {
// precise and therefore not the same as converting to Double and back. // precise and therefore not the same as converting to Double and back.
ClearFlag(kCanOverflow); ClearFlag(kCanOverflow);
} }
if (!CheckFlag(kAllUsesTruncatingToInt32)) { res->set_can_be_minus_zero(!CheckFlag(kAllUsesTruncatingToInt32) &&
bool m0 = (a->CanBeZero() && b->CanBeNegative()) || ((a->CanBeZero() && b->CanBeNegative()) ||
(a->CanBeNegative() && b->CanBeZero()); (a->CanBeNegative() && b->CanBeZero())));
res->set_can_be_minus_zero(m0);
}
return res; return res;
} else { } else {
return HValue::InferRange(zone); return HValue::InferRange(zone);
...@@ -1867,16 +1865,9 @@ Range* HDiv::InferRange(Zone* zone) { ...@@ -1867,16 +1865,9 @@ Range* HDiv::InferRange(Zone* zone) {
Range* a = left()->range(); Range* a = left()->range();
Range* b = right()->range(); Range* b = right()->range();
Range* result = new(zone) Range(); Range* result = new(zone) Range();
if (!CheckFlag(kAllUsesTruncatingToInt32)) { result->set_can_be_minus_zero(!CheckFlag(kAllUsesTruncatingToInt32) &&
if (a->CanBeMinusZero()) { (a->CanBeMinusZero() ||
result->set_can_be_minus_zero(true); (a->CanBeZero() && b->CanBeNegative())));
}
if (a->CanBeZero() && b->CanBeNegative()) {
result->set_can_be_minus_zero(true);
}
}
if (!a->Includes(kMinInt) || !b->Includes(-1)) { if (!a->Includes(kMinInt) || !b->Includes(-1)) {
ClearFlag(HValue::kCanOverflow); ClearFlag(HValue::kCanOverflow);
} }
...@@ -1906,9 +1897,8 @@ Range* HMod::InferRange(Zone* zone) { ...@@ -1906,9 +1897,8 @@ Range* HMod::InferRange(Zone* zone) {
Range* result = new(zone) Range(left_can_be_negative ? -positive_bound : 0, Range* result = new(zone) Range(left_can_be_negative ? -positive_bound : 0,
a->CanBePositive() ? positive_bound : 0); a->CanBePositive() ? positive_bound : 0);
if (left_can_be_negative && !CheckFlag(kAllUsesTruncatingToInt32)) { result->set_can_be_minus_zero(!CheckFlag(kAllUsesTruncatingToInt32) &&
result->set_can_be_minus_zero(true); left_can_be_negative);
}
if (!a->Includes(kMinInt) || !b->Includes(-1)) { if (!a->Includes(kMinInt) || !b->Includes(-1)) {
ClearFlag(HValue::kCanOverflow); ClearFlag(HValue::kCanOverflow);
...@@ -2458,7 +2448,9 @@ Range* HBitwise::InferRange(Zone* zone) { ...@@ -2458,7 +2448,9 @@ Range* HBitwise::InferRange(Zone* zone) {
? static_cast<int32_t>(-limit) : 0; ? static_cast<int32_t>(-limit) : 0;
return new(zone) Range(min, static_cast<int32_t>(limit - 1)); 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); const int32_t kDefaultMask = static_cast<int32_t>(0xffffffff);
int32_t left_mask = (left()->range() != NULL) int32_t left_mask = (left()->range() != NULL)
...@@ -2470,9 +2462,11 @@ Range* HBitwise::InferRange(Zone* zone) { ...@@ -2470,9 +2462,11 @@ Range* HBitwise::InferRange(Zone* zone) {
int32_t result_mask = (op() == Token::BIT_AND) int32_t result_mask = (op() == Token::BIT_AND)
? left_mask & right_mask ? left_mask & right_mask
: left_mask | right_mask; : left_mask | right_mask;
return (result_mask >= 0) if (result_mask >= 0) return new(zone) Range(0, result_mask);
? new(zone) Range(0, result_mask)
: HValue::InferRange(zone); Range* result = HValue::InferRange(zone);
result->set_can_be_minus_zero(false);
return result;
} }
...@@ -2484,7 +2478,6 @@ Range* HSar::InferRange(Zone* zone) { ...@@ -2484,7 +2478,6 @@ Range* HSar::InferRange(Zone* zone) {
? left()->range()->Copy(zone) ? left()->range()->Copy(zone)
: new(zone) Range(); : new(zone) Range();
result->Sar(c->Integer32Value()); result->Sar(c->Integer32Value());
result->set_can_be_minus_zero(false);
return result; return result;
} }
} }
...@@ -2509,7 +2502,6 @@ Range* HShr::InferRange(Zone* zone) { ...@@ -2509,7 +2502,6 @@ Range* HShr::InferRange(Zone* zone) {
? left()->range()->Copy(zone) ? left()->range()->Copy(zone)
: new(zone) Range(); : new(zone) Range();
result->Sar(c->Integer32Value()); result->Sar(c->Integer32Value());
result->set_can_be_minus_zero(false);
return result; return result;
} }
} }
...@@ -2526,7 +2518,6 @@ Range* HShl::InferRange(Zone* zone) { ...@@ -2526,7 +2518,6 @@ Range* HShl::InferRange(Zone* zone) {
? left()->range()->Copy(zone) ? left()->range()->Copy(zone)
: new(zone) Range(); : new(zone) Range();
result->Shl(c->Integer32Value()); result->Shl(c->Integer32Value());
result->set_can_be_minus_zero(false);
return result; 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