From a7d67a64f11100434b196143e2ba516f8c13697a Mon Sep 17 00:00:00 2001 From: svenpanne Date: Mon, 26 Jan 2015 00:35:45 -0800 Subject: [PATCH] Fixed Hydrogen environment handling for mul-i on ARM and ARM64. 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 | 8 ++++++-- src/arm64/lithium-arm64.cc | 4 +++- test/mjsunit/regress/regress-451322.js | 17 +++++++++++++++++ 3 files changed, 26 insertions(+), 3 deletions(-) create mode 100644 test/mjsunit/regress/regress-451322.js diff --git a/src/arm/lithium-arm.cc b/src/arm/lithium-arm.cc index e5de950..4ee5159 100644 --- a/src/arm/lithium-arm.cc +++ b/src/arm/lithium-arm.cc @@ -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); diff --git a/src/arm64/lithium-arm64.cc b/src/arm64/lithium-arm64.cc index 2d5f7f2..d667f71 100644 --- a/src/arm64/lithium-arm64.cc +++ b/src/arm64/lithium-arm64.cc @@ -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 index 0000000..b7794f5 --- /dev/null +++ b/test/mjsunit/regress/regress-451322.js @@ -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(); -- 2.7.4