From d0fe2952f3589bc15edb232fd47b937d761d2476 Mon Sep 17 00:00:00 2001 From: "ulan@chromium.org" Date: Tue, 25 Mar 2014 16:09:29 +0000 Subject: [PATCH] Revert r20246 "ARM64: Add overflow checking support for multiplications by constant powers of 2." Reason: mjsunit/mul-exhaustive-part4 fails in no snaphot debug. TBR=alexandre.rames@arm.com Review URL: https://codereview.chromium.org/211393002 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@20254 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/arm64/lithium-arm64.cc | 23 +++++++------------ src/arm64/lithium-codegen-arm64.cc | 47 ++++++++++++-------------------------- 2 files changed, 23 insertions(+), 47 deletions(-) diff --git a/src/arm64/lithium-arm64.cc b/src/arm64/lithium-arm64.cc index 3d3ae97..c6f547f 100644 --- a/src/arm64/lithium-arm64.cc +++ b/src/arm64/lithium-arm64.cc @@ -1891,36 +1891,29 @@ LInstruction* LChunkBuilder::DoMul(HMul* instr) { HValue* least_const = instr->BetterLeftOperand(); HValue* most_const = instr->BetterRightOperand(); - LOperand* left; + LOperand* left = UseRegisterAtStart(least_const); // LMulConstI can handle a subset of constants: // With support for overflow detection: // -1, 0, 1, 2 - // 2^n, -(2^n) // Without support for overflow detection: + // 2^n, -(2^n) // 2^n + 1, -(2^n - 1) if (most_const->IsConstant()) { int32_t constant = HConstant::cast(most_const)->Integer32Value(); - bool small_constant = (constant >= -1) && (constant <= 2); - bool end_range_constant = (constant <= -kMaxInt) || (constant == kMaxInt); - int32_t constant_abs = Abs(constant); - - if (!end_range_constant && - (small_constant || - (IsPowerOf2(constant_abs)) || - (!can_overflow && (IsPowerOf2(constant_abs + 1) || - IsPowerOf2(constant_abs - 1))))) { + int32_t constant_abs = (constant >= 0) ? constant : -constant; + + if (((constant >= -1) && (constant <= 2)) || + (!can_overflow && (IsPowerOf2(constant_abs) || + IsPowerOf2(constant_abs + 1) || + IsPowerOf2(constant_abs - 1)))) { LConstantOperand* right = UseConstant(most_const); - bool need_register = IsPowerOf2(constant_abs) && !small_constant; - left = need_register ? UseRegister(least_const) - : UseRegisterAtStart(least_const); LMulConstIS* mul = new(zone()) LMulConstIS(left, right); if (needs_environment) AssignEnvironment(mul); return DefineAsRegister(mul); } } - left = UseRegisterAtStart(least_const); // LMulI/S can handle all cases, but it requires that a register is // allocated for the second operand. LInstruction* result; diff --git a/src/arm64/lithium-codegen-arm64.cc b/src/arm64/lithium-codegen-arm64.cc index 5b0b018..d61151e 100644 --- a/src/arm64/lithium-codegen-arm64.cc +++ b/src/arm64/lithium-codegen-arm64.cc @@ -4253,7 +4253,6 @@ void LCodeGen::DoMulConstIS(LMulConstIS* instr) { Register left = is_smi ? ToRegister(instr->left()) : ToRegister32(instr->left()) ; int32_t right = ToInteger32(instr->right()); - ASSERT((right > -kMaxInt) || (right < kMaxInt)); bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow); bool bailout_on_minus_zero = @@ -4297,40 +4296,20 @@ void LCodeGen::DoMulConstIS(LMulConstIS* instr) { } break; + // All other cases cannot detect overflow, because it would probably be no + // faster than using the smull method in LMulI. + // TODO(jbramley): Investigate this, and add overflow support if it would + // be useful. default: - // Multiplication by constant powers of two (and some related values) - // can be done efficiently with shifted operands. - int32_t right_abs = Abs(right); - - if (IsPowerOf2(right_abs)) { - int right_log2 = WhichPowerOf2(right_abs); - - if (can_overflow) { - Register scratch = result; - ASSERT(!AreAliased(scratch, left)); - __ Cls(scratch, left); - __ Cmp(scratch, right_log2); - DeoptimizeIf(lt, instr->environment()); - } - - if (right >= 0) { - // result = left << log2(right) - __ Lsl(result, left, right_log2); - } else { - // result = -left << log2(-right) - __ Neg(result, Operand(left, LSL, right_log2)); - } - return; - } - - - // For the following cases, we could perform a conservative overflow check - // with CLS as above. However the few cycles saved are likely not worth - // the risk of deoptimizing more often than required. ASSERT(!can_overflow); + // Multiplication by constant powers of two (and some related values) + // can be done efficiently with shifted operands. if (right >= 0) { - if (IsPowerOf2(right - 1)) { + if (IsPowerOf2(right)) { + // result = left << log2(right) + __ Lsl(result, left, WhichPowerOf2(right)); + } else if (IsPowerOf2(right - 1)) { // result = left + left << log2(right - 1) __ Add(result, left, Operand(left, LSL, WhichPowerOf2(right - 1))); } else if (IsPowerOf2(right + 1)) { @@ -4341,7 +4320,10 @@ void LCodeGen::DoMulConstIS(LMulConstIS* instr) { UNREACHABLE(); } } else { - if (IsPowerOf2(-right + 1)) { + if (IsPowerOf2(-right)) { + // result = -left << log2(-right) + __ Neg(result, Operand(left, LSL, WhichPowerOf2(-right))); + } else if (IsPowerOf2(-right + 1)) { // result = left - left << log2(-right + 1) __ Sub(result, left, Operand(left, LSL, WhichPowerOf2(-right + 1))); } else if (IsPowerOf2(-right - 1)) { @@ -4352,6 +4334,7 @@ void LCodeGen::DoMulConstIS(LMulConstIS* instr) { UNREACHABLE(); } } + break; } } -- 2.7.4