Index: src/ia32/lithium-codegen-ia32.cc |
diff --git a/src/ia32/lithium-codegen-ia32.cc b/src/ia32/lithium-codegen-ia32.cc |
index 5d1f46d065634bc7381850bddca5bf9c0362a740..bea7bc4a84cf876abc4afb680e625b70db6c3821 100644 |
--- a/src/ia32/lithium-codegen-ia32.cc |
+++ b/src/ia32/lithium-codegen-ia32.cc |
@@ -1344,8 +1344,7 @@ void LCodeGen::DoModI(LModI* instr) { |
void LCodeGen::DoDivI(LDivI* instr) { |
if (!instr->is_flooring() && instr->hydrogen()->HasPowerOf2Divisor()) { |
Register dividend = ToRegister(instr->left()); |
- int32_t divisor = |
- HConstant::cast(instr->hydrogen()->right())->Integer32Value(); |
+ int32_t divisor = instr->hydrogen()->right()->GetInteger32Constant(); |
int32_t test_value = 0; |
int32_t power = 0; |
@@ -1368,10 +1367,26 @@ void LCodeGen::DoDivI(LDivI* instr) { |
} |
if (test_value != 0) { |
- // Deoptimize if remainder is not 0. |
- __ test(dividend, Immediate(test_value)); |
- DeoptimizeIf(not_zero, instr->environment()); |
- __ sar(dividend, power); |
+ if (instr->hydrogen()->CheckFlag( |
+ HInstruction::kAllUsesTruncatingToInt32)) { |
+ Label done, negative; |
+ __ cmp(dividend, 0); |
+ __ j(less, &negative, Label::kNear); |
+ __ sar(dividend, power); |
+ __ jmp(&done, Label::kNear); |
+ |
+ __ bind(&negative); |
+ __ neg(dividend); |
+ __ sar(dividend, power); |
+ if (divisor > 0) __ neg(dividend); |
+ __ bind(&done); |
+ return; // Don't fall through to "__ neg" below. |
+ } else { |
+ // Deoptimize if remainder is not 0. |
+ __ test(dividend, Immediate(test_value)); |
+ DeoptimizeIf(not_zero, instr->environment()); |
+ __ sar(dividend, power); |
+ } |
} |
if (divisor < 0) __ neg(dividend); |
@@ -1418,11 +1433,7 @@ void LCodeGen::DoDivI(LDivI* instr) { |
__ cdq(); |
__ idiv(right_reg); |
- if (!instr->is_flooring()) { |
- // Deoptimize if remainder is not 0. |
- __ test(edx, Operand(edx)); |
- DeoptimizeIf(not_zero, instr->environment()); |
- } else { |
+ if (instr->is_flooring()) { |
Label done; |
__ test(edx, edx); |
__ j(zero, &done, Label::kNear); |
@@ -1430,6 +1441,11 @@ void LCodeGen::DoDivI(LDivI* instr) { |
__ sar(edx, 31); |
__ add(eax, edx); |
__ bind(&done); |
+ } else if (!instr->hydrogen()->CheckFlag( |
+ HInstruction::kAllUsesTruncatingToInt32)) { |
+ // Deoptimize if remainder is not 0. |
+ __ test(edx, Operand(edx)); |
+ DeoptimizeIf(not_zero, instr->environment()); |
} |
} |