Avoid redundant smi check for Math.abs

R=jkummerow@chromium.org

Review URL: https://codereview.chromium.org/21180004

Patch from Weiliang Lin <weiliang.lin2@gmail.com>.

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@16021 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 15c1d23f
...@@ -3765,7 +3765,7 @@ void LCodeGen::DoMathAbs(LMathAbs* instr) { ...@@ -3765,7 +3765,7 @@ void LCodeGen::DoMathAbs(LMathAbs* instr) {
DwVfpRegister input = ToDoubleRegister(instr->value()); DwVfpRegister input = ToDoubleRegister(instr->value());
DwVfpRegister result = ToDoubleRegister(instr->result()); DwVfpRegister result = ToDoubleRegister(instr->result());
__ vabs(result, input); __ vabs(result, input);
} else if (r.IsInteger32()) { } else if (r.IsSmiOrInteger32()) {
EmitIntegerMathAbs(instr); EmitIntegerMathAbs(instr);
} else { } else {
// Representation is tagged. // Representation is tagged.
......
...@@ -3821,7 +3821,7 @@ void LCodeGen::DoMathAbs(LMathAbs* instr) { ...@@ -3821,7 +3821,7 @@ void LCodeGen::DoMathAbs(LMathAbs* instr) {
__ xorps(scratch, scratch); __ xorps(scratch, scratch);
__ subsd(scratch, input_reg); __ subsd(scratch, input_reg);
__ pand(input_reg, scratch); __ pand(input_reg, scratch);
} else if (r.IsInteger32()) { } else if (r.IsSmiOrInteger32()) {
EmitIntegerMathAbs(instr); EmitIntegerMathAbs(instr);
} else { // Tagged case. } else { // Tagged case.
DeferredMathAbsTaggedHeapNumber* deferred = DeferredMathAbsTaggedHeapNumber* deferred =
......
...@@ -3426,6 +3426,17 @@ void LCodeGen::EmitIntegerMathAbs(LMathAbs* instr) { ...@@ -3426,6 +3426,17 @@ void LCodeGen::EmitIntegerMathAbs(LMathAbs* instr) {
} }
void LCodeGen::EmitInteger64MathAbs(LMathAbs* instr) {
Register input_reg = ToRegister(instr->value());
__ testq(input_reg, input_reg);
Label is_positive;
__ j(not_sign, &is_positive, Label::kNear);
__ neg(input_reg); // Sets flags.
DeoptimizeIf(negative, instr->environment());
__ bind(&is_positive);
}
void LCodeGen::DoMathAbs(LMathAbs* instr) { void LCodeGen::DoMathAbs(LMathAbs* instr) {
// Class for deferred case. // Class for deferred case.
class DeferredMathAbsTaggedHeapNumber: public LDeferredCode { class DeferredMathAbsTaggedHeapNumber: public LDeferredCode {
...@@ -3451,6 +3462,8 @@ void LCodeGen::DoMathAbs(LMathAbs* instr) { ...@@ -3451,6 +3462,8 @@ void LCodeGen::DoMathAbs(LMathAbs* instr) {
__ andpd(input_reg, scratch); __ andpd(input_reg, scratch);
} else if (r.IsInteger32()) { } else if (r.IsInteger32()) {
EmitIntegerMathAbs(instr); EmitIntegerMathAbs(instr);
} else if (r.IsSmi()) {
EmitInteger64MathAbs(instr);
} else { // Tagged case. } else { // Tagged case.
DeferredMathAbsTaggedHeapNumber* deferred = DeferredMathAbsTaggedHeapNumber* deferred =
new(zone()) DeferredMathAbsTaggedHeapNumber(this, instr); new(zone()) DeferredMathAbsTaggedHeapNumber(this, instr);
......
...@@ -268,6 +268,7 @@ class LCodeGen BASE_EMBEDDED { ...@@ -268,6 +268,7 @@ class LCodeGen BASE_EMBEDDED {
uint32_t additional_index = 0); uint32_t additional_index = 0);
void EmitIntegerMathAbs(LMathAbs* instr); void EmitIntegerMathAbs(LMathAbs* instr);
void EmitInteger64MathAbs(LMathAbs* instr);
// Support for recording safepoint and position information. // Support for recording safepoint and position information.
void RecordSafepoint(LPointerMap* pointers, void RecordSafepoint(LPointerMap* pointers,
......
...@@ -109,3 +109,14 @@ for(var i = 0; i < 1000; i++) { ...@@ -109,3 +109,14 @@ for(var i = 0; i < 1000; i++) {
assertEquals(42, foo(-42)); assertEquals(42, foo(-42));
%OptimizeFunctionOnNextCall(foo) %OptimizeFunctionOnNextCall(foo)
assertEquals(42, foo(-42)); assertEquals(42, foo(-42));
// Regression test for SMI input of Math.abs on X64, see:
// https://codereview.chromium.org/21180004/
var a = [-1, -2];
function foo2() {
return Math.abs(a[0]);
}
assertEquals(1, foo2());
assertEquals(1, foo2());
%OptimizeFunctionOnNextCall(foo2);
assertEquals(1, foo2());
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment