DwVfpRegister input = ToDoubleRegister(instr->value());
DwVfpRegister result = ToDoubleRegister(instr->result());
__ vabs(result, input);
- } else if (r.IsInteger32()) {
+ } else if (r.IsSmiOrInteger32()) {
EmitIntegerMathAbs(instr);
} else {
// Representation is tagged.
__ xorps(scratch, scratch);
__ subsd(scratch, input_reg);
__ pand(input_reg, scratch);
- } else if (r.IsInteger32()) {
+ } else if (r.IsSmiOrInteger32()) {
EmitIntegerMathAbs(instr);
} else { // Tagged case.
DeferredMathAbsTaggedHeapNumber* deferred =
}
+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) {
// Class for deferred case.
class DeferredMathAbsTaggedHeapNumber: public LDeferredCode {
__ andpd(input_reg, scratch);
} else if (r.IsInteger32()) {
EmitIntegerMathAbs(instr);
+ } else if (r.IsSmi()) {
+ EmitInteger64MathAbs(instr);
} else { // Tagged case.
DeferredMathAbsTaggedHeapNumber* deferred =
new(zone()) DeferredMathAbsTaggedHeapNumber(this, instr);
uint32_t additional_index = 0);
void EmitIntegerMathAbs(LMathAbs* instr);
+ void EmitInteger64MathAbs(LMathAbs* instr);
// Support for recording safepoint and position information.
void RecordSafepoint(LPointerMap* pointers,
assertEquals(42, foo(-42));
%OptimizeFunctionOnNextCall(foo)
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());