MIPS64: Fix random failures of fannkuch.js.
TEST=mjsunit/asm/embenchen/fannkuch, mjsunit/math-abs BUG= Review URL: https://codereview.chromium.org/1192413002 Cr-Commit-Position: refs/heads/master@{#29157}
This commit is contained in:
parent
74f97b0d2a
commit
e8173e4ea2
@ -3774,13 +3774,27 @@ void LCodeGen::EmitIntegerMathAbs(LMathAbs* instr) {
|
||||
Label done;
|
||||
__ Branch(USE_DELAY_SLOT, &done, ge, input, Operand(zero_reg));
|
||||
__ mov(result, input);
|
||||
__ dsubu(result, zero_reg, input);
|
||||
__ subu(result, zero_reg, input);
|
||||
// Overflow if result is still negative, i.e. 0x80000000.
|
||||
DeoptimizeIf(lt, instr, Deoptimizer::kOverflow, result, Operand(zero_reg));
|
||||
__ bind(&done);
|
||||
}
|
||||
|
||||
|
||||
void LCodeGen::EmitSmiMathAbs(LMathAbs* instr) {
|
||||
Register input = ToRegister(instr->value());
|
||||
Register result = ToRegister(instr->result());
|
||||
Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm_);
|
||||
Label done;
|
||||
__ Branch(USE_DELAY_SLOT, &done, ge, input, Operand(zero_reg));
|
||||
__ mov(result, input);
|
||||
__ dsubu(result, zero_reg, input);
|
||||
// Overflow if result is still negative, i.e. 0x80000000 00000000.
|
||||
DeoptimizeIf(lt, instr, Deoptimizer::kOverflow, result, Operand(zero_reg));
|
||||
__ bind(&done);
|
||||
}
|
||||
|
||||
|
||||
void LCodeGen::DoMathAbs(LMathAbs* instr) {
|
||||
// Class for deferred case.
|
||||
class DeferredMathAbsTaggedHeapNumber final : public LDeferredCode {
|
||||
@ -3801,8 +3815,10 @@ void LCodeGen::DoMathAbs(LMathAbs* instr) {
|
||||
FPURegister input = ToDoubleRegister(instr->value());
|
||||
FPURegister result = ToDoubleRegister(instr->result());
|
||||
__ abs_d(result, input);
|
||||
} else if (r.IsSmiOrInteger32()) {
|
||||
} else if (r.IsInteger32()) {
|
||||
EmitIntegerMathAbs(instr);
|
||||
} else if (r.IsSmi()) {
|
||||
EmitSmiMathAbs(instr);
|
||||
} else {
|
||||
// Representation is tagged.
|
||||
DeferredMathAbsTaggedHeapNumber* deferred =
|
||||
@ -3811,7 +3827,7 @@ void LCodeGen::DoMathAbs(LMathAbs* instr) {
|
||||
// Smi check.
|
||||
__ JumpIfNotSmi(input, deferred->entry());
|
||||
// If smi, handle it directly.
|
||||
EmitIntegerMathAbs(instr);
|
||||
EmitSmiMathAbs(instr);
|
||||
__ bind(deferred->exit());
|
||||
}
|
||||
}
|
||||
|
@ -251,6 +251,7 @@ class LCodeGen: public LCodeGenBase {
|
||||
String::Encoding encoding);
|
||||
|
||||
void EmitIntegerMathAbs(LMathAbs* instr);
|
||||
void EmitSmiMathAbs(LMathAbs* instr);
|
||||
|
||||
// Support for recording safepoint and position information.
|
||||
void RecordSafepoint(LPointerMap* pointers,
|
||||
|
@ -120,3 +120,19 @@ assertEquals(1, foo2());
|
||||
assertEquals(1, foo2());
|
||||
%OptimizeFunctionOnNextCall(foo2);
|
||||
assertEquals(1, foo2());
|
||||
|
||||
// Regression test for Integer input of Math.abs on mips64.
|
||||
function absHalf(bits) {
|
||||
var x = 1 << (bits - 1);
|
||||
var half = Math.abs(x);
|
||||
return half;
|
||||
|
||||
}
|
||||
|
||||
// Create minimum integer input for abs() using bitwise operations
|
||||
// that should overflow.
|
||||
bits = 32;
|
||||
assertEquals(2147483648, absHalf(bits));
|
||||
assertEquals(2147483648, absHalf(bits));
|
||||
%OptimizeFunctionOnNextCall(absHalf);
|
||||
assertEquals(2147483648, absHalf(bits));
|
||||
|
Loading…
Reference in New Issue
Block a user