Fixed Hydrogen environment handling for mul-i on ARM and ARM64.
authorsvenpanne <svenpanne@chromium.org>
Mon, 26 Jan 2015 08:35:45 +0000 (00:35 -0800)
committerCommit bot <commit-bot@chromium.org>
Mon, 26 Jan 2015 08:35:58 +0000 (08:35 +0000)
The whole logic in DoMul makes me cry, so I made only the minimal
change to fix the issue...

BUG=v8:451322
LOG=y

Review URL: https://codereview.chromium.org/873703002

Cr-Commit-Position: refs/heads/master@{#26261}

src/arm/lithium-arm.cc
src/arm64/lithium-arm64.cc
test/mjsunit/regress/regress-451322.js [new file with mode: 0644]

index e5de950..4ee5159 100644 (file)
@@ -1508,9 +1508,10 @@ LInstruction* LChunkBuilder::DoMul(HMul* instr) {
     bool can_overflow = instr->CheckFlag(HValue::kCanOverflow);
     bool bailout_on_minus_zero = instr->CheckFlag(HValue::kBailoutOnMinusZero);
 
+    int32_t constant_value = 0;
     if (right->IsConstant()) {
       HConstant* constant = HConstant::cast(right);
-      int32_t constant_value = constant->Integer32Value();
+      constant_value = constant->Integer32Value();
       // Constants -1, 0 and 1 can be optimized if the result can overflow.
       // For other constants, it can be optimized only without overflow.
       if (!can_overflow || ((constant_value >= -1) && (constant_value <= 1))) {
@@ -1533,7 +1534,10 @@ LInstruction* LChunkBuilder::DoMul(HMul* instr) {
       right_op = UseRegister(right);
     }
     LMulI* mul = new(zone()) LMulI(left_op, right_op);
-    if (can_overflow || bailout_on_minus_zero) {
+    if (right_op->IsConstantOperand()
+            ? ((can_overflow && constant_value == -1) ||
+               (bailout_on_minus_zero && constant_value <= 0))
+            : (can_overflow || bailout_on_minus_zero)) {
       AssignEnvironment(mul);
     }
     return DefineAsRegister(mul);
index 2d5f7f2..d667f71 100644 (file)
@@ -1963,7 +1963,9 @@ LInstruction* LChunkBuilder::DoMul(HMul* instr) {
                                        : UseRegisterAtStart(least_const);
         LInstruction* result =
             DefineAsRegister(new(zone()) LMulConstIS(left, right));
-        if ((bailout_on_minus_zero && constant <= 0) || can_overflow) {
+        if ((bailout_on_minus_zero && constant <= 0) ||
+            (can_overflow && constant != 1 &&
+             base::bits::IsPowerOfTwo32(constant_abs))) {
           result = AssignEnvironment(result);
         }
         return result;
diff --git a/test/mjsunit/regress/regress-451322.js b/test/mjsunit/regress/regress-451322.js
new file mode 100644 (file)
index 0000000..b7794f5
--- /dev/null
@@ -0,0 +1,17 @@
+// Copyright 2015 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 foo = 0;
+
+function bar() {
+  var baz = 0 - {};
+  if (foo > 24) return baz * 0;
+}
+
+bar();
+bar();
+%OptimizeFunctionOnNextCall(bar);
+bar();