Revision: 10891
Author:   [email protected]
Date:     Thu Mar  1 04:45:46 2012
Log: Fix a register assignment bug in typed array stores without SSE3 available.

The old code used a separate HToInt32 instruction which had a wrong register
constraint for the input register which caused wrong result when the stored value is used after a typed array store. (UseRegister instead of UseTempRegister) when no
SSE3 is available.

This change fixes it by replacing HToInt32 with the corresponding HChange
instruction which has correct register contraints.

TEST=mjsunit/compiler/regress-toint32.js
Review URL: https://chromiumcodereview.appspot.com/9565007
http://code.google.com/p/v8/source/detail?r=10891

Added:
 /branches/bleeding_edge/test/mjsunit/compiler/regress-toint32.js
Modified:
 /branches/bleeding_edge/src/arm/lithium-arm.cc
 /branches/bleeding_edge/src/hydrogen-instructions.h
 /branches/bleeding_edge/src/hydrogen.cc
 /branches/bleeding_edge/src/ia32/lithium-ia32.cc
 /branches/bleeding_edge/src/mips/lithium-mips.cc
 /branches/bleeding_edge/src/x64/lithium-x64.cc

=======================================
--- /dev/null
+++ /branches/bleeding_edge/test/mjsunit/compiler/regress-toint32.js Thu Mar 1 04:45:46 2012
@@ -0,0 +1,45 @@
+// Copyright 2012 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 --noenable-sse3
+
+var a = new Int32Array(1);
+var G = 0x80000000;
+
+function f(x) {
+  var v = x;
+  v = v + 1;
+  a[0] = v;
+  v = v - 1;
+  return v;
+}
+
+assertEquals(G, f(G));
+assertEquals(G, f(G));
+%OptimizeFunctionOnNextCall(f);
+assertEquals(G, f(G));
+
=======================================
--- /branches/bleeding_edge/src/arm/lithium-arm.cc      Thu Mar  1 03:33:37 2012
+++ /branches/bleeding_edge/src/arm/lithium-arm.cc      Thu Mar  1 04:45:46 2012
@@ -1761,31 +1761,6 @@
     return AssignEnvironment(DefineAsRegister(result));
   }
 }
-
-
-LInstruction* LChunkBuilder::DoToInt32(HToInt32* instr) {
-  HValue* value = instr->value();
-  Representation input_rep = value->representation();
-  LOperand* reg = UseRegister(value);
-  if (input_rep.IsDouble()) {
-    LOperand* temp1 = TempRegister();
-    LOperand* temp2 = TempRegister();
-    LDoubleToI* res = new(zone()) LDoubleToI(reg, temp1, temp2);
-    return AssignEnvironment(DefineAsRegister(res));
-  } else if (input_rep.IsInteger32()) {
- // Canonicalization should already have removed the hydrogen instruction in
-    // this case, since it is a noop.
-    UNREACHABLE();
-    return NULL;
-  } else {
-    ASSERT(input_rep.IsTagged());
-    LOperand* temp1 = TempRegister();
-    LOperand* temp2 = TempRegister();
-    LOperand* temp3 = FixedTemp(d11);
-    LTaggedToI* res = new(zone()) LTaggedToI(reg, temp1, temp2, temp3);
-    return AssignEnvironment(DefineSameAsFirst(res));
-  }
-}


 LInstruction* LChunkBuilder::DoReturn(HReturn* instr) {
=======================================
--- /branches/bleeding_edge/src/hydrogen-instructions.h Wed Feb 29 05:41:18 2012 +++ /branches/bleeding_edge/src/hydrogen-instructions.h Thu Mar 1 04:45:46 2012
@@ -174,7 +174,6 @@
   V(ThisFunction)                              \
   V(Throw)                                     \
   V(ToFastProperties)                          \
-  V(ToInt32)                                   \
   V(TransitionElementsKind)                    \
   V(Typeof)                                    \
   V(TypeofIsAndBranch)                         \
@@ -1243,34 +1242,6 @@
 };


-class HToInt32: public HUnaryOperation {
- public:
-  explicit HToInt32(HValue* value)
-      : HUnaryOperation(value) {
-    set_representation(Representation::Integer32());
-    SetFlag(kUseGVN);
-    SetFlag(kTruncatingToInt32);
-  }
-
-  virtual Representation RequiredInputRepresentation(int index) {
-    return Representation::None();
-  }
-
-  virtual HValue* Canonicalize() {
-    if (value()->representation().IsInteger32()) {
-      return value();
-    } else {
-      return this;
-    }
-  }
-
-  DECLARE_CONCRETE_INSTRUCTION(ToInt32)
-
- protected:
-  virtual bool DataEquals(HValue* other) { return true; }
-};
-
-
 class HSimulate: public HInstruction {
  public:
   HSimulate(int ast_id, int pop_count)
=======================================
--- /branches/bleeding_edge/src/hydrogen.cc     Thu Mar  1 03:50:11 2012
+++ /branches/bleeding_edge/src/hydrogen.cc     Thu Mar  1 04:45:46 2012
@@ -4514,9 +4514,7 @@
     ASSERT(val != NULL);
     switch (elements_kind) {
       case EXTERNAL_PIXEL_ELEMENTS: {
-        HClampToUint8* clamp = new(zone()) HClampToUint8(val);
-        AddInstruction(clamp);
-        val = clamp;
+        val = AddInstruction(new(zone()) HClampToUint8(val));
         break;
       }
       case EXTERNAL_BYTE_ELEMENTS:
@@ -4525,9 +4523,13 @@
       case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
       case EXTERNAL_INT_ELEMENTS:
       case EXTERNAL_UNSIGNED_INT_ELEMENTS: {
-        HToInt32* floor_val = new(zone()) HToInt32(val);
-        AddInstruction(floor_val);
-        val = floor_val;
+        if (!val->representation().IsInteger32()) {
+          val = AddInstruction(new(zone()) HChange(
+              val,
+              Representation::Integer32(),
+              true,  // Truncate to int32.
+              false));  // Don't deoptimize undefined (irrelevant here).
+        }
         break;
       }
       case EXTERNAL_FLOAT_ELEMENTS:
@@ -4544,6 +4546,7 @@
     return new(zone()) HStoreKeyedSpecializedArrayElement(
         external_elements, checked_key, val, elements_kind);
   } else {
+    ASSERT(val == NULL);
     return new(zone()) HLoadKeyedSpecializedArrayElement(
         external_elements, checked_key, elements_kind);
   }
=======================================
--- /branches/bleeding_edge/src/ia32/lithium-ia32.cc Thu Mar 1 03:33:37 2012 +++ /branches/bleeding_edge/src/ia32/lithium-ia32.cc Thu Mar 1 04:45:46 2012
@@ -1814,34 +1814,6 @@
     return AssignEnvironment(DefineFixed(result, eax));
   }
 }
-
-
-LInstruction* LChunkBuilder::DoToInt32(HToInt32* instr) {
-  HValue* value = instr->value();
-  Representation input_rep = value->representation();
-
-  LInstruction* result;
-  if (input_rep.IsDouble()) {
-    LOperand* reg = UseRegister(value);
-    LOperand* temp_reg =
-        CpuFeatures::IsSupported(SSE3) ? NULL : TempRegister();
-    result = DefineAsRegister(new(zone()) LDoubleToI(reg, temp_reg));
-  } else if (input_rep.IsInteger32()) {
- // Canonicalization should already have removed the hydrogen instruction in
-    // this case, since it is a noop.
-    UNREACHABLE();
-    return NULL;
-  } else {
-    ASSERT(input_rep.IsTagged());
-    LOperand* reg = UseRegister(value);
-    // Register allocator doesn't (yet) support allocation of double
-    // temps. Reserve xmm1 explicitly.
-    LOperand* xmm_temp =
-        CpuFeatures::IsSupported(SSE3) ? NULL : FixedTemp(xmm1);
-    result = DefineSameAsFirst(new(zone()) LTaggedToI(reg, xmm_temp));
-  }
-  return AssignEnvironment(result);
-}


 LInstruction* LChunkBuilder::DoReturn(HReturn* instr) {
=======================================
--- /branches/bleeding_edge/src/mips/lithium-mips.cc Thu Mar 1 04:38:58 2012 +++ /branches/bleeding_edge/src/mips/lithium-mips.cc Thu Mar 1 04:45:46 2012
@@ -1764,31 +1764,6 @@
     return AssignEnvironment(DefineAsRegister(result));
   }
 }
-
-
-LInstruction* LChunkBuilder::DoToInt32(HToInt32* instr) {
-  HValue* value = instr->value();
-  Representation input_rep = value->representation();
-  LOperand* reg = UseRegister(value);
-  if (input_rep.IsDouble()) {
-    LOperand* temp1 = TempRegister();
-    LOperand* temp2 = TempRegister();
-    LDoubleToI* res = new(zone()) LDoubleToI(reg, temp1, temp2);
-    return AssignEnvironment(DefineAsRegister(res));
-  } else if (input_rep.IsInteger32()) {
- // Canonicalization should already have removed the hydrogen instruction in
-    // this case, since it is a noop.
-    UNREACHABLE();
-    return NULL;
-  } else {
-    ASSERT(input_rep.IsTagged());
-    LOperand* temp1 = TempRegister();
-    LOperand* temp2 = TempRegister();
-    LOperand* temp3 = FixedTemp(f22);
-    LTaggedToI* res = new(zone()) LTaggedToI(reg, temp1, temp2, temp3);
-    return AssignEnvironment(DefineSameAsFirst(res));
-  }
-}


 LInstruction* LChunkBuilder::DoReturn(HReturn* instr) {
=======================================
--- /branches/bleeding_edge/src/x64/lithium-x64.cc      Thu Mar  1 03:33:37 2012
+++ /branches/bleeding_edge/src/x64/lithium-x64.cc      Thu Mar  1 04:45:46 2012
@@ -1748,32 +1748,6 @@
     return AssignEnvironment(DefineSameAsFirst(result));
   }
 }
-
-
-LInstruction* LChunkBuilder::DoToInt32(HToInt32* instr) {
-  HValue* value = instr->value();
-  Representation input_rep = value->representation();
-  LOperand* reg = UseRegister(value);
-  if (input_rep.IsDouble()) {
- return AssignEnvironment(DefineAsRegister(new(zone()) LDoubleToI(reg)));
-  } else if (input_rep.IsInteger32()) {
- // Canonicalization should already have removed the hydrogen instruction in
-    // this case, since it is a noop.
-    UNREACHABLE();
-    return NULL;
-  } else {
-    ASSERT(input_rep.IsTagged());
-    LOperand* reg = UseRegister(value);
-    // Register allocator doesn't (yet) support allocation of double
-    // temps. Reserve xmm1 explicitly.
-    LOperand* xmm_temp =
-        CpuFeatures::IsSupported(SSE3)
-        ? NULL
-        : FixedTemp(xmm1);
-    return AssignEnvironment(
-        DefineSameAsFirst(new(zone()) LTaggedToI(reg, xmm_temp)));
-  }
-}


 LInstruction* LChunkBuilder::DoReturn(HReturn* instr) {

--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev

Reply via email to