Fixed flooring division by a power of 2, once again...
Avoid right shifts by zero bits: On ARM it actually means shifting by 32 bits (correctness issue) and on other platforms they are useless (performance issue). This is fix for the fix in r20544. BUG=v8:3259 LOG=y R=yangguo@chromium.org Review URL: https://codereview.chromium.org/324403003 git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@21769 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
6c26eb26ab
commit
23fc5b75a8
@ -1469,20 +1469,22 @@ void LCodeGen::DoFlooringDivByPowerOf2I(LFlooringDivByPowerOf2I* instr) {
|
||||
DeoptimizeIf(eq, instr->environment());
|
||||
}
|
||||
|
||||
// If the negation could not overflow, simply shifting is OK.
|
||||
if (!instr->hydrogen()->CheckFlag(HValue::kLeftCanBeMinInt)) {
|
||||
__ mov(result, Operand(dividend, ASR, shift));
|
||||
// Dividing by -1 is basically negation, unless we overflow.
|
||||
if (divisor == -1) {
|
||||
if (instr->hydrogen()->CheckFlag(HValue::kLeftCanBeMinInt)) {
|
||||
DeoptimizeIf(vs, instr->environment());
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Dividing by -1 is basically negation, unless we overflow.
|
||||
if (divisor == -1) {
|
||||
DeoptimizeIf(vs, instr->environment());
|
||||
// If the negation could not overflow, simply shifting is OK.
|
||||
if (!instr->hydrogen()->CheckFlag(HValue::kLeftCanBeMinInt)) {
|
||||
__ mov(result, Operand(result, ASR, shift));
|
||||
return;
|
||||
}
|
||||
|
||||
__ mov(result, Operand(kMinInt / divisor), LeaveCC, vs);
|
||||
__ mov(result, Operand(dividend, ASR, shift), LeaveCC, vc);
|
||||
__ mov(result, Operand(result, ASR, shift), LeaveCC, vc);
|
||||
}
|
||||
|
||||
|
||||
|
@ -3933,19 +3933,21 @@ void LCodeGen::DoFlooringDivByPowerOf2I(LFlooringDivByPowerOf2I* instr) {
|
||||
DeoptimizeIf(eq, instr->environment());
|
||||
}
|
||||
|
||||
// Dividing by -1 is basically negation, unless we overflow.
|
||||
if (divisor == -1) {
|
||||
if (instr->hydrogen()->CheckFlag(HValue::kLeftCanBeMinInt)) {
|
||||
DeoptimizeIf(vs, instr->environment());
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// If the negation could not overflow, simply shifting is OK.
|
||||
if (!instr->hydrogen()->CheckFlag(HValue::kLeftCanBeMinInt)) {
|
||||
__ Mov(result, Operand(dividend, ASR, shift));
|
||||
return;
|
||||
}
|
||||
|
||||
// Dividing by -1 is basically negation, unless we overflow.
|
||||
if (divisor == -1) {
|
||||
DeoptimizeIf(vs, instr->environment());
|
||||
return;
|
||||
}
|
||||
|
||||
__ Asr(result, dividend, shift);
|
||||
__ Asr(result, result, shift);
|
||||
__ Csel(result, result, kMinInt / divisor, vc);
|
||||
}
|
||||
|
||||
|
@ -1353,14 +1353,17 @@ void LCodeGen::DoFlooringDivByPowerOf2I(LFlooringDivByPowerOf2I* instr) {
|
||||
DeoptimizeIf(zero, instr->environment());
|
||||
}
|
||||
|
||||
if (!instr->hydrogen()->CheckFlag(HValue::kLeftCanBeMinInt)) {
|
||||
__ sar(dividend, shift);
|
||||
// Dividing by -1 is basically negation, unless we overflow.
|
||||
if (divisor == -1) {
|
||||
if (instr->hydrogen()->CheckFlag(HValue::kLeftCanBeMinInt)) {
|
||||
DeoptimizeIf(overflow, instr->environment());
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Dividing by -1 is basically negation, unless we overflow.
|
||||
if (divisor == -1) {
|
||||
DeoptimizeIf(overflow, instr->environment());
|
||||
// If the negation could not overflow, simply shifting is OK.
|
||||
if (!instr->hydrogen()->CheckFlag(HValue::kLeftCanBeMinInt)) {
|
||||
__ sar(dividend, shift);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1134,16 +1134,17 @@ void LCodeGen::DoFlooringDivByPowerOf2I(LFlooringDivByPowerOf2I* instr) {
|
||||
DeoptimizeIf(zero, instr->environment());
|
||||
}
|
||||
|
||||
// If the negation could not overflow, simply shifting is OK.
|
||||
if (!instr->hydrogen()->CheckFlag(HValue::kLeftCanBeMinInt)) {
|
||||
__ sarl(dividend, Immediate(shift));
|
||||
// Dividing by -1 is basically negation, unless we overflow.
|
||||
if (divisor == -1) {
|
||||
if (instr->hydrogen()->CheckFlag(HValue::kLeftCanBeMinInt)) {
|
||||
DeoptimizeIf(overflow, instr->environment());
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Note that we could emit branch-free code, but that would need one more
|
||||
// register.
|
||||
if (divisor == -1) {
|
||||
DeoptimizeIf(overflow, instr->environment());
|
||||
// If the negation could not overflow, simply shifting is OK.
|
||||
if (!instr->hydrogen()->CheckFlag(HValue::kLeftCanBeMinInt)) {
|
||||
__ sarl(dividend, Immediate(shift));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -308,10 +308,6 @@
|
||||
# Currently always deopt on minus zero
|
||||
'math-floor-of-div-minus-zero': [SKIP],
|
||||
|
||||
# Issue 3259.
|
||||
'math-floor-of-div-nosudiv': [PASS, FAIL],
|
||||
'math-floor-of-div': [PASS, FAIL],
|
||||
|
||||
############################################################################
|
||||
# Slow tests.
|
||||
'regress/regress-2185-2': [PASS, SLOW],
|
||||
|
Loading…
Reference in New Issue
Block a user