Revision: 19970
Author:   [email protected]
Date:     Mon Mar 17 09:49:32 2014 UTC
Log:      Merged r19798, r19896 into 3.24 branch.

Fix bug in constant folding object comparisons.

Correctly retain argument value when deopting from Math.round on x64.

BUG=351624
LOG=N
[email protected]

Review URL: https://codereview.chromium.org/199093003
http://code.google.com/p/v8/source/detail?r=19970

Added:
 /branches/3.24/test/mjsunit/regress/regress-351624.js
Modified:
 /branches/3.24/src/hydrogen-instructions.cc
 /branches/3.24/src/hydrogen-instructions.h
 /branches/3.24/src/version.cc
 /branches/3.24/src/x64/lithium-codegen-x64.cc
 /branches/3.24/src/x64/lithium-x64.cc
 /branches/3.24/src/x64/lithium-x64.h

=======================================
--- /dev/null
+++ /branches/3.24/test/mjsunit/regress/regress-351624.js Mon Mar 17 09:49:32 2014 UTC
@@ -0,0 +1,23 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --allow-natives-syntax
+
+var big = 1e10;
+var backup = new Float64Array(1);
+
+function mult0(val){
+  var prod = val * big;
+  backup[0] = prod;
+  var rounded = Math.round(prod);
+  assertEquals(prod, backup[0]);
+  return rounded;
+}
+
+var count = 5;
+for (var i = 0; i < count; i++) {
+  if (i == count - 1) %OptimizeFunctionOnNextCall(mult0);
+  var result = mult0(-1);
+  assertEquals(result, -big);
+}
=======================================
--- /branches/3.24/src/hydrogen-instructions.cc Wed Feb 26 08:17:48 2014 UTC
+++ /branches/3.24/src/hydrogen-instructions.cc Mon Mar 17 09:49:32 2014 UTC
@@ -3003,7 +3003,7 @@
 bool HCompareObjectEqAndBranch::KnownSuccessorBlock(HBasicBlock** block) {
   if (left()->IsConstant() && right()->IsConstant()) {
     bool comparison_result =
-        HConstant::cast(left())->Equals(HConstant::cast(right()));
+        HConstant::cast(left())->DataEquals(HConstant::cast(right()));
     *block = comparison_result
         ? FirstSuccessor()
         : SecondSuccessor();
=======================================
--- /branches/3.24/src/hydrogen-instructions.h  Wed Mar  5 12:21:17 2014 UTC
+++ /branches/3.24/src/hydrogen-instructions.h  Mon Mar 17 09:49:32 2014 UTC
@@ -3490,15 +3490,6 @@
   Unique<Object> GetUnique() const {
     return object_;
   }
-
-#ifdef DEBUG
-  virtual void Verify() V8_OVERRIDE { }
-#endif
-
-  DECLARE_CONCRETE_INSTRUCTION(Constant)
-
- protected:
-  virtual Range* InferRange(Zone* zone) V8_OVERRIDE;

   virtual bool DataEquals(HValue* other) V8_OVERRIDE {
     HConstant* other_constant = HConstant::cast(other);
@@ -3524,6 +3515,15 @@
     }
   }

+#ifdef DEBUG
+  virtual void Verify() V8_OVERRIDE { }
+#endif
+
+  DECLARE_CONCRETE_INSTRUCTION(Constant)
+
+ protected:
+  virtual Range* InferRange(Zone* zone) V8_OVERRIDE;
+
  private:
   friend class HGraph;
HConstant(Handle<Object> handle, Representation r = Representation::None());
@@ -4184,24 +4184,6 @@

class HCompareObjectEqAndBranch : public HTemplateControlInstruction<2, 2> {
  public:
-  HCompareObjectEqAndBranch(HValue* left,
-                            HValue* right,
-                            HBasicBlock* true_target = NULL,
-                            HBasicBlock* false_target = NULL) {
- // TODO(danno): make this private when the IfBuilder properly constructs
-    // control flow instructions.
-    ASSERT(!left->IsConstant() ||
-           (!HConstant::cast(left)->HasInteger32Value() ||
-            HConstant::cast(left)->HasSmiValue()));
-    ASSERT(!right->IsConstant() ||
-           (!HConstant::cast(right)->HasInteger32Value() ||
-            HConstant::cast(right)->HasSmiValue()));
-    SetOperandAt(0, left);
-    SetOperandAt(1, right);
-    SetSuccessorAt(0, true_target);
-    SetSuccessorAt(1, false_target);
-  }
-
DECLARE_INSTRUCTION_FACTORY_P2(HCompareObjectEqAndBranch, HValue*, HValue*); DECLARE_INSTRUCTION_FACTORY_P4(HCompareObjectEqAndBranch, HValue*, HValue*,
                                  HBasicBlock*, HBasicBlock*);
@@ -4222,6 +4204,23 @@
   }

   DECLARE_CONCRETE_INSTRUCTION(CompareObjectEqAndBranch)
+
+ private:
+  HCompareObjectEqAndBranch(HValue* left,
+                            HValue* right,
+                            HBasicBlock* true_target = NULL,
+                            HBasicBlock* false_target = NULL) {
+    ASSERT(!left->IsConstant() ||
+           (!HConstant::cast(left)->HasInteger32Value() ||
+            HConstant::cast(left)->HasSmiValue()));
+    ASSERT(!right->IsConstant() ||
+           (!HConstant::cast(right)->HasInteger32Value() ||
+            HConstant::cast(right)->HasSmiValue()));
+    SetOperandAt(0, left);
+    SetOperandAt(1, right);
+    SetSuccessorAt(0, true_target);
+    SetSuccessorAt(1, false_target);
+  }
 };


=======================================
--- /branches/3.24/src/version.cc       Wed Mar 12 19:28:35 2014 UTC
+++ /branches/3.24/src/version.cc       Mon Mar 17 09:49:32 2014 UTC
@@ -35,7 +35,7 @@
 #define MAJOR_VERSION     3
 #define MINOR_VERSION     24
 #define BUILD_NUMBER      35
-#define PATCH_LEVEL       15
+#define PATCH_LEVEL       16
 // Use 1 for candidates and 0 otherwise.
 // (Boolean macro values are not supported by all preprocessors.)
 #define IS_CANDIDATE_VERSION 0
=======================================
--- /branches/3.24/src/x64/lithium-codegen-x64.cc Mon Mar 3 09:38:07 2014 UTC +++ /branches/3.24/src/x64/lithium-codegen-x64.cc Mon Mar 17 09:49:32 2014 UTC
@@ -3551,10 +3551,11 @@
   const XMMRegister xmm_scratch = double_scratch0();
   Register output_reg = ToRegister(instr->result());
   XMMRegister input_reg = ToDoubleRegister(instr->value());
+  XMMRegister input_temp = ToDoubleRegister(instr->temp());
   static int64_t one_half = V8_INT64_C(0x3FE0000000000000);  // 0.5
   static int64_t minus_one_half = V8_INT64_C(0xBFE0000000000000);  // -0.5

-  Label done, round_to_zero, below_one_half, do_not_compensate, restore;
+  Label done, round_to_zero, below_one_half;
   Label::Distance dist = DeoptEveryNTimes() ? Label::kFar : Label::kNear;
   __ movq(kScratchRegister, one_half);
   __ movq(xmm_scratch, kScratchRegister);
@@ -3578,21 +3579,19 @@

   // CVTTSD2SI rounds towards zero, we use ceil(x - (-0.5)) and then
   // compare and compensate.
-  __ movq(kScratchRegister, input_reg);  // Back up input_reg.
-  __ subsd(input_reg, xmm_scratch);
-  __ cvttsd2si(output_reg, input_reg);
+  __ movq(input_temp, input_reg);  // Do not alter input_reg.
+  __ subsd(input_temp, xmm_scratch);
+  __ cvttsd2si(output_reg, input_temp);
// Catch minint due to overflow, and to prevent overflow when compensating.
   __ cmpl(output_reg, Immediate(0x80000000));
   __ RecordComment("D2I conversion overflow");
   DeoptimizeIf(equal, instr->environment());

   __ Cvtlsi2sd(xmm_scratch, output_reg);
-  __ ucomisd(input_reg, xmm_scratch);
-  __ j(equal, &restore, Label::kNear);
+  __ ucomisd(xmm_scratch, input_temp);
+  __ j(equal, &done, dist);
   __ subl(output_reg, Immediate(1));
   // No overflow because we already ruled out minint.
-  __ bind(&restore);
-  __ movq(input_reg, kScratchRegister);  // Restore input_reg.
   __ jmp(&done, dist);

   __ bind(&round_to_zero);
=======================================
--- /branches/3.24/src/x64/lithium-x64.cc       Wed Mar  5 12:21:17 2014 UTC
+++ /branches/3.24/src/x64/lithium-x64.cc       Mon Mar 17 09:49:32 2014 UTC
@@ -1121,8 +1121,9 @@


 LInstruction* LChunkBuilder::DoMathRound(HUnaryMathOperation* instr) {
-  LOperand* input = UseRegisterAtStart(instr->value());
-  LMathRound* result = new(zone()) LMathRound(input);
+  LOperand* input = UseRegister(instr->value());
+  LOperand* temp = FixedTemp(xmm4);
+  LMathRound* result = new(zone()) LMathRound(input, temp);
   return AssignEnvironment(DefineAsRegister(result));
 }

=======================================
--- /branches/3.24/src/x64/lithium-x64.h        Fri Jan 31 14:01:53 2014 UTC
+++ /branches/3.24/src/x64/lithium-x64.h        Mon Mar 17 09:49:32 2014 UTC
@@ -720,13 +720,15 @@
 };


-class LMathRound V8_FINAL : public LTemplateInstruction<1, 1, 0> {
+class LMathRound V8_FINAL : public LTemplateInstruction<1, 1, 1> {
  public:
-  explicit LMathRound(LOperand* value) {
+  explicit LMathRound(LOperand* value, LOperand* temp) {
     inputs_[0] = value;
+    temps_[0] = temp;
   }

   LOperand* value() { return inputs_[0]; }
+  LOperand* temp() { return temps_[0]; }

   DECLARE_CONCRETE_INSTRUCTION(MathRound, "math-round")
   DECLARE_HYDROGEN_ACCESSOR(UnaryMathOperation)

--
--
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/d/optout.

Reply via email to