Reviewers: rossberg,

Message:
PTAL.

Description:
Fix and cleanup can_be_minus_zero computation

Please review this at https://codereview.chromium.org/18434004/

SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge

Affected files:
  M src/hydrogen-instructions.cc
  A + test/mjsunit/compiler/minus-zero.js


Index: src/hydrogen-instructions.cc
diff --git a/src/hydrogen-instructions.cc b/src/hydrogen-instructions.cc
index 932fd47af13fc12bf081f3bb232063edd59ee7d2..b3266cfd768aba039c109726ca5018ee7b33cb46 100644
--- a/src/hydrogen-instructions.cc
+++ b/src/hydrogen-instructions.cc
@@ -1736,9 +1736,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;
 }
@@ -1756,7 +1757,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;
 }

@@ -1801,9 +1803,9 @@ 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);
@@ -1820,9 +1822,9 @@ 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);
@@ -1841,11 +1843,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);
@@ -1858,16 +1858,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);
     }
@@ -1897,9 +1890,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);
@@ -2432,7 +2424,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)
@@ -2444,9 +2438,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;
 }


@@ -2458,7 +2454,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;
     }
   }
@@ -2483,7 +2478,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;
       }
     }
@@ -2500,7 +2494,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;
     }
   }
Index: test/mjsunit/compiler/minus-zero.js
diff --git a/test/mjsunit/regress/regress-crbug-173974.js b/test/mjsunit/compiler/minus-zero.js
similarity index 91%
copy from test/mjsunit/regress/regress-crbug-173974.js
copy to test/mjsunit/compiler/minus-zero.js
index 905bd6058a0ad0fe2ebe10e4c7dafbe9945cbe3b..6efceb54e36834c217732a7974f0c5d2a2cca132 100644
--- a/test/mjsunit/regress/regress-crbug-173974.js
+++ b/test/mjsunit/compiler/minus-zero.js
@@ -27,10 +27,11 @@

 // Flags: --allow-natives-syntax

-function f() {
-  var count = "";
-  count[0] --;
+function add(x, y) {
+  return x + y;
 }
-f();
-%OptimizeFunctionOnNextCall(f);
-f();
+
+assertEquals(0, add(0, 0));
+assertEquals(0, add(0, 0));
+%OptimizeFunctionOnNextCall(add);
+assertEquals(-0, add(-0, -0));


--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to