Better range information for logical shift right >>>.
authorfschneider@chromium.org <fschneider@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Mon, 25 Jul 2011 13:28:35 +0000 (13:28 +0000)
committerfschneider@chromium.org <fschneider@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Mon, 25 Jul 2011 13:28:35 +0000 (13:28 +0000)
If the input range is positive and the shift count is constant
we can replace >>> with >> to compute the output range.

For negative inputs, we can only compute a range if the
result always fits into a signed int32.

BUG=v8:1510
Review URL: http://codereview.chromium.org/7489043

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@8735 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/hydrogen-instructions.cc
src/hydrogen-instructions.h

index 6c316cd..2be2a03 100644 (file)
@@ -1230,6 +1230,30 @@ Range* HSar::InferRange() {
 }
 
 
+Range* HShr::InferRange() {
+  if (right()->IsConstant()) {
+    HConstant* c = HConstant::cast(right());
+    if (c->HasInteger32Value()) {
+      int shift_count = c->Integer32Value() & 0x1f;
+      if (left()->range()->CanBeNegative()) {
+        // Only compute bounds if the result always fits into an int32.
+        return (shift_count >= 1)
+            ? new Range(0, static_cast<uint32_t>(0xffffffff) >> shift_count)
+            : new Range();
+      } else {
+        // For positive inputs we can use the >> operator.
+        Range* result = (left()->range() != NULL)
+            ? left()->range()->Copy()
+            : new Range();
+        result->Sar(c->Integer32Value());
+        return result;
+      }
+    }
+  }
+  return HValue::InferRange();
+}
+
+
 Range* HShl::InferRange() {
   if (right()->IsConstant()) {
     HConstant* c = HConstant::cast(right());
index 9b7a95b..bd6763f 100644 (file)
@@ -3060,6 +3060,7 @@ class HShr: public HBitwiseBinaryOperation {
   HShr(HValue* context, HValue* left, HValue* right)
       : HBitwiseBinaryOperation(context, left, right) { }
 
+  virtual Range* InferRange();
   virtual HType CalculateInferredType();
 
   DECLARE_CONCRETE_INSTRUCTION(Shr)