From 5d473db176fc42886ef9d3c14cad7729a31bfe48 Mon Sep 17 00:00:00 2001 From: "plind44@gmail.com" Date: Tue, 11 Mar 2014 19:04:14 +0000 Subject: [PATCH] MIPS: Cleanup some of the range uses in ModI/DivI. Port r19796 (2b8ff32) BUG=v8:3204 LOG=y R=plind44@gmail.com Review URL: https://codereview.chromium.org/194863004 Patch from Balazs Kilvady . git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@19822 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/mips/lithium-codegen-mips.cc | 41 +++++++++++++++++++++------------------- src/mips/lithium-mips.cc | 33 ++++++++++++++------------------ 2 files changed, 36 insertions(+), 38 deletions(-) diff --git a/src/mips/lithium-codegen-mips.cc b/src/mips/lithium-codegen-mips.cc index 9bebb7b..435321a 100644 --- a/src/mips/lithium-codegen-mips.cc +++ b/src/mips/lithium-codegen-mips.cc @@ -1095,8 +1095,6 @@ void LCodeGen::DoModByPowerOf2I(LModByPowerOf2I* instr) { void LCodeGen::DoModI(LModI* instr) { HMod* hmod = instr->hydrogen(); - HValue* left = hmod->left(); - HValue* right = hmod->right(); const Register left_reg = ToRegister(instr->left()); const Register right_reg = ToRegister(instr->right()); const Register result_reg = ToRegister(instr->result()); @@ -1107,24 +1105,28 @@ void LCodeGen::DoModI(LModI* instr) { Label done; // Check for x % 0, we have to deopt in this case because we can't return a // NaN. - if (right->CanBeZero()) { + if (hmod->CheckFlag(HValue::kCanBeDivByZero)) { DeoptimizeIf(eq, instr->environment(), right_reg, Operand(zero_reg)); } - // Check for kMinInt % -1, we have to deopt if we care about -0, because we - // can't return that. - if (left->RangeCanInclude(kMinInt) && right->RangeCanInclude(-1)) { - Label left_not_min_int; - __ Branch(&left_not_min_int, ne, left_reg, Operand(kMinInt)); - // TODO(svenpanne) Don't deopt when we don't care about -0. - DeoptimizeIf(eq, instr->environment(), right_reg, Operand(-1)); - __ bind(&left_not_min_int); + // Check for kMinInt % -1, div will return kMinInt, which is not what we + // want. We have to deopt if we care about -0, because we can't return that. + if (hmod->CheckFlag(HValue::kCanOverflow)) { + Label no_overflow_possible; + __ Branch(&no_overflow_possible, ne, left_reg, Operand(kMinInt)); + if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) { + DeoptimizeIf(eq, instr->environment(), right_reg, Operand(-1)); + } else { + __ Branch(&no_overflow_possible, ne, right_reg, Operand(-1)); + __ Branch(USE_DELAY_SLOT, &done); + __ mov(result_reg, zero_reg); + } + __ bind(&no_overflow_possible); } - // TODO(svenpanne) Only emit the test/deopt if we have to. + // If we care about -0, test if the dividend is <0 and the result is 0. __ Branch(USE_DELAY_SLOT, &done, ge, left_reg, Operand(zero_reg)); __ mfhi(result_reg); - if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) { DeoptimizeIf(eq, instr->environment(), result_reg, Operand(zero_reg)); } @@ -1133,6 +1135,7 @@ void LCodeGen::DoModI(LModI* instr) { void LCodeGen::DoDivI(LDivI* instr) { + HBinaryOperation* hdiv = instr->hydrogen(); const Register left = ToRegister(instr->left()); const Register right = ToRegister(instr->right()); const Register result = ToRegister(instr->result()); @@ -1142,12 +1145,12 @@ void LCodeGen::DoDivI(LDivI* instr) { __ div(left, right); // Check for x / 0. - if (instr->hydrogen()->CheckFlag(HValue::kCanBeDivByZero)) { + if (hdiv->CheckFlag(HValue::kCanBeDivByZero)) { DeoptimizeIf(eq, instr->environment(), right, Operand(zero_reg)); } // Check for (0 / -x) that will produce negative zero. - if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { + if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero)) { Label left_not_zero; __ Branch(&left_not_zero, ne, left, Operand(zero_reg)); DeoptimizeIf(lt, instr->environment(), right, Operand(zero_reg)); @@ -1155,14 +1158,15 @@ void LCodeGen::DoDivI(LDivI* instr) { } // Check for (kMinInt / -1). - if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { + if (hdiv->CheckFlag(HValue::kCanOverflow) && + !hdiv->CheckFlag(HValue::kAllUsesTruncatingToInt32)) { Label left_not_min_int; __ Branch(&left_not_min_int, ne, left, Operand(kMinInt)); DeoptimizeIf(eq, instr->environment(), right, Operand(-1)); __ bind(&left_not_min_int); } - if (!instr->hydrogen()->CheckFlag(HInstruction::kAllUsesTruncatingToInt32)) { + if (!hdiv->CheckFlag(HValue::kAllUsesTruncatingToInt32)) { __ mfhi(result); DeoptimizeIf(ne, instr->environment(), result, Operand(zero_reg)); } @@ -1233,8 +1237,7 @@ void LCodeGen::DoFlooringDivByConstI(LFlooringDivByConstI* instr) { // Check for (0 / -x) that will produce negative zero. HMathFloorOfDiv* hdiv = instr->hydrogen(); - if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && - hdiv->left()->RangeCanInclude(0) && divisor < 0) { + if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) { DeoptimizeIf(eq, instr->environment(), dividend, Operand(zero_reg)); } diff --git a/src/mips/lithium-mips.cc b/src/mips/lithium-mips.cc index d2cc39b..fd0a2aa 100644 --- a/src/mips/lithium-mips.cc +++ b/src/mips/lithium-mips.cc @@ -1289,8 +1289,7 @@ LInstruction* LChunkBuilder::DoFlooringDivByConstI(HMathFloorOfDiv* instr) { DefineAsRegister(new(zone()) LFlooringDivByConstI(dividend, divisor)); bool can_deopt = divisor == 0 || - (instr->CheckFlag(HValue::kBailoutOnMinusZero) && - instr->left()->RangeCanInclude(0) && divisor < 0); + (instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0); return can_deopt ? AssignEnvironment(result) : result; } @@ -1317,12 +1316,12 @@ LInstruction* LChunkBuilder::DoModByPowerOf2I(HMod* instr) { ASSERT(instr->right()->representation().Equals(instr->representation())); LOperand* dividend = UseRegisterAtStart(instr->left()); int32_t divisor = instr->right()->GetInteger32Constant(); - LInstruction* result = - DefineSameAsFirst(new(zone()) LModByPowerOf2I(dividend, divisor)); - bool can_deopt = - instr->CheckFlag(HValue::kBailoutOnMinusZero) && - instr->left()->CanBeNegative(); - return can_deopt ? AssignEnvironment(result) : result; + LInstruction* result = DefineSameAsFirst(new(zone()) LModByPowerOf2I( + dividend, divisor)); + if (instr->CheckFlag(HValue::kBailoutOnMinusZero)) { + result = AssignEnvironment(result); + } + return result; } @@ -1332,17 +1331,13 @@ LInstruction* LChunkBuilder::DoModI(HMod* instr) { ASSERT(instr->right()->representation().Equals(instr->representation())); LOperand* dividend = UseRegister(instr->left()); LOperand* divisor = UseRegister(instr->right()); - LModI* mod = new(zone()) LModI(dividend, - divisor); - LInstruction* result = DefineAsRegister(mod); - bool can_deopt = (instr->right()->CanBeZero() || - (instr->left()->RangeCanInclude(kMinInt) && - instr->right()->RangeCanInclude(-1) && - instr->CheckFlag(HValue::kBailoutOnMinusZero)) || - (instr->left()->CanBeNegative() && - instr->CanBeZero() && - instr->CheckFlag(HValue::kBailoutOnMinusZero))); - return can_deopt ? AssignEnvironment(result) : result; + LInstruction* result = DefineAsRegister(new(zone()) LModI( + dividend, divisor)); + if (instr->CheckFlag(HValue::kCanBeDivByZero) || + instr->CheckFlag(HValue::kBailoutOnMinusZero)) { + result = AssignEnvironment(result); + } + return result; } -- 2.7.4