Revision: 6590
Author: [email protected]
Date: Wed Feb 2 08:14:28 2011
Log: Merge r6573 to 3.0 branch. This is a fix for issue 1088, Math.pow(-0,
0.5).
Review URL: http://codereview.chromium.org/6334056
http://code.google.com/p/v8/source/detail?r=6590
Modified:
/branches/3.0/src/arm/codegen-arm.cc
/branches/3.0/src/assembler.cc
/branches/3.0/src/ia32/code-stubs-ia32.cc
/branches/3.0/src/ia32/codegen-ia32.cc
/branches/3.0/src/ia32/lithium-codegen-ia32.cc
/branches/3.0/src/version.cc
/branches/3.0/src/x64/codegen-x64.cc
/branches/3.0/test/mjsunit/math-pow.js
=======================================
--- /branches/3.0/src/arm/codegen-arm.cc Fri Jan 28 00:04:38 2011
+++ /branches/3.0/src/arm/codegen-arm.cc Wed Feb 2 08:14:28 2011
@@ -4698,12 +4698,15 @@
runtime.entry_label(),
AVOID_NANS_AND_INFINITIES);
+ // Convert -0 into +0 by adding +0.
+ __ vmov(d2, 0.0);
+ __ vadd(d0, d2, d0);
// Load 1.0 into d2.
__ vmov(d2, 1.0);
- // Calculate the reciprocal of the square root. 1/sqrt(x) = sqrt(1/x).
- __ vdiv(d0, d2, d0);
+ // Calculate the reciprocal of the square root.
__ vsqrt(d0, d0);
+ __ vdiv(d0, d2, d0);
__ b(&allocate_return);
@@ -4717,6 +4720,9 @@
scratch1, scratch2, heap_number_map, s0,
runtime.entry_label(),
AVOID_NANS_AND_INFINITIES);
+ // Convert -0 into +0 by adding +0.
+ __ vmov(d2, 0.0);
+ __ vadd(d0, d2, d0);
__ vsqrt(d0, d0);
__ bind(&allocate_return);
=======================================
--- /branches/3.0/src/assembler.cc Wed Jan 19 03:11:08 2011
+++ /branches/3.0/src/assembler.cc Wed Feb 2 08:14:28 2011
@@ -838,8 +838,8 @@
return power_double_int(x, y_int); // Returns 1.0 for exponent 0.
}
if (!isinf(x)) {
- if (y == 0.5) return sqrt(x);
- if (y == -0.5) return 1.0 / sqrt(x);
+ if (y == 0.5) return sqrt(x + 0.0); // -0 must be converted to +0.
+ if (y == -0.5) return 1.0 / sqrt(x + 0.0);
}
if (isnan(y) || ((x == 1 || x == -1) && isinf(y))) {
return OS::nan_value();
=======================================
--- /branches/3.0/src/ia32/code-stubs-ia32.cc Tue Jan 25 06:06:47 2011
+++ /branches/3.0/src/ia32/code-stubs-ia32.cc Wed Feb 2 08:14:28 2011
@@ -3477,10 +3477,12 @@
__ j(not_equal, ¬_minus_half);
// Calculates reciprocal of square root.
- // Note that 1/sqrt(x) = sqrt(1/x))
- __ divsd(xmm3, xmm0);
- __ movsd(xmm1, xmm3);
+ // sqrtsd returns -0 when input is -0. ECMA spec requires +0.
+ __ xorpd(xmm1, xmm1);
+ __ addsd(xmm1, xmm0);
__ sqrtsd(xmm1, xmm1);
+ __ divsd(xmm3, xmm1);
+ __ movsd(xmm1, xmm3);
__ jmp(&allocate_return);
// Test for 0.5.
@@ -3492,7 +3494,9 @@
__ ucomisd(xmm2, xmm1);
__ j(not_equal, &call_runtime);
// Calculates square root.
- __ movsd(xmm1, xmm0);
+ // sqrtsd returns -0 when input is -0. ECMA spec requires +0.
+ __ xorpd(xmm1, xmm1);
+ __ addsd(xmm1, xmm0);
__ sqrtsd(xmm1, xmm1);
__ bind(&allocate_return);
=======================================
--- /branches/3.0/src/ia32/codegen-ia32.cc Tue Jan 25 06:06:47 2011
+++ /branches/3.0/src/ia32/codegen-ia32.cc Wed Feb 2 08:14:28 2011
@@ -7951,10 +7951,12 @@
__ j(not_equal, ¬_minus_half);
// Calculates reciprocal of square root.
- // Note that 1/sqrt(x) = sqrt(1/x))
- __ divsd(xmm3, xmm0);
- __ movsd(xmm1, xmm3);
+ // sqrtsd returns -0 when input is -0. ECMA spec requires +0.
+ __ xorpd(xmm1, xmm1);
+ __ addsd(xmm1, xmm0);
__ sqrtsd(xmm1, xmm1);
+ __ divsd(xmm3, xmm1);
+ __ movsd(xmm1, xmm3);
__ jmp(&allocate_return);
// Test for 0.5.
@@ -7966,7 +7968,9 @@
__ ucomisd(xmm2, xmm1);
call_runtime.Branch(not_equal);
// Calculates square root.
- __ movsd(xmm1, xmm0);
+ // sqrtsd returns -0 when input is -0. ECMA spec requires +0.
+ __ xorpd(xmm1, xmm1);
+ __ addsd(xmm1, xmm0);
__ sqrtsd(xmm1, xmm1);
JumpTarget done;
=======================================
--- /branches/3.0/src/ia32/lithium-codegen-ia32.cc Wed Feb 2 07:49:30 2011
+++ /branches/3.0/src/ia32/lithium-codegen-ia32.cc Wed Feb 2 08:14:28 2011
@@ -2388,6 +2388,8 @@
__ movdbl(xmm_scratch, Operand::StaticVariable(negative_infinity));
__ ucomisd(xmm_scratch, input_reg);
DeoptimizeIf(equal, instr->environment());
+ __ xorpd(xmm_scratch, xmm_scratch);
+ __ addsd(input_reg, xmm_scratch); // Convert -0 to +0.
__ sqrtsd(input_reg, input_reg);
}
=======================================
--- /branches/3.0/src/version.cc Wed Feb 2 07:52:58 2011
+++ /branches/3.0/src/version.cc Wed Feb 2 08:14:28 2011
@@ -1,4 +1,4 @@
-// Copyright 2010 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
@@ -35,7 +35,7 @@
#define MAJOR_VERSION 3
#define MINOR_VERSION 0
#define BUILD_NUMBER 12
-#define PATCH_LEVEL 7
+#define PATCH_LEVEL 8
#define CANDIDATE_VERSION false
// Define SONAME to have the SCons build the put a specific SONAME into the
=======================================
--- /branches/3.0/src/x64/codegen-x64.cc Tue Jan 25 06:06:47 2011
+++ /branches/3.0/src/x64/codegen-x64.cc Wed Feb 2 08:14:28 2011
@@ -6969,10 +6969,12 @@
__ j(not_equal, ¬_minus_half);
// Calculates reciprocal of square root.
- // Note that 1/sqrt(x) = sqrt(1/x))
- __ divsd(xmm3, xmm0);
- __ movsd(xmm1, xmm3);
+ // sqrtsd returns -0 when input is -0. ECMA spec requires +0.
+ __ xorpd(xmm1, xmm1);
+ __ addsd(xmm1, xmm0);
__ sqrtsd(xmm1, xmm1);
+ __ divsd(xmm3, xmm1);
+ __ movsd(xmm1, xmm3);
__ jmp(&allocate_return);
// Test for 0.5.
@@ -6985,7 +6987,9 @@
call_runtime.Branch(not_equal);
// Calculates square root.
- __ movsd(xmm1, xmm0);
+ // sqrtsd returns -0 when input is -0. ECMA spec requires +0.
+ __ xorpd(xmm1, xmm1);
+ __ addsd(xmm1, xmm0);
__ sqrtsd(xmm1, xmm1);
JumpTarget done;
=======================================
--- /branches/3.0/test/mjsunit/math-pow.js Mon Jul 5 04:01:40 2010
+++ /branches/3.0/test/mjsunit/math-pow.js Wed Feb 2 08:14:28 2011
@@ -58,10 +58,11 @@
assertEquals(Infinity, Math.pow(2, Infinity));
assertEquals(Infinity, Math.pow(-2, Infinity));
-assertEquals(+0, Math.pow(1.1, -Infinity));
-assertEquals(+0, Math.pow(-1.1, -Infinity));
-assertEquals(+0, Math.pow(2, -Infinity));
-assertEquals(+0, Math.pow(-2, -Infinity));
+// Because +0 == -0, we need to compare 1/{+,-}0 to {+,-}Infinity
+assertEquals(+Infinity, 1/Math.pow(1.1, -Infinity));
+assertEquals(+Infinity, 1/Math.pow(-1.1, -Infinity));
+assertEquals(+Infinity, 1/Math.pow(2, -Infinity));
+assertEquals(+Infinity, 1/Math.pow(-2, -Infinity));
assertEquals(NaN, Math.pow(1, Infinity));
assertEquals(NaN, Math.pow(1, -Infinity));
@@ -81,8 +82,8 @@
assertEquals(Infinity, Math.pow(Infinity, 0.1));
assertEquals(Infinity, Math.pow(Infinity, 2));
-assertEquals(+0, Math.pow(Infinity, -0.1));
-assertEquals(+0, Math.pow(Infinity, -2));
+assertEquals(+Infinity, 1/Math.pow(Infinity, -0.1));
+assertEquals(+Infinity, 1/Math.pow(Infinity, -2));
assertEquals(-Infinity, Math.pow(-Infinity, 3));
assertEquals(-Infinity, Math.pow(-Infinity, 13));
@@ -90,23 +91,23 @@
assertEquals(Infinity, Math.pow(-Infinity, 3.1));
assertEquals(Infinity, Math.pow(-Infinity, 2));
-assertEquals(-0, Math.pow(-Infinity, -3));
-assertEquals(-0, Math.pow(-Infinity, -13));
-
-assertEquals(+0, Math.pow(-Infinity, -3.1));
-assertEquals(+0, Math.pow(-Infinity, -2));
-
-assertEquals(+0, Math.pow(+0, 1.1));
-assertEquals(+0, Math.pow(+0, 2));
+assertEquals(-Infinity, 1/Math.pow(-Infinity, -3));
+assertEquals(-Infinity, 1/Math.pow(-Infinity, -13));
+
+assertEquals(+Infinity, 1/Math.pow(-Infinity, -3.1));
+assertEquals(+Infinity, 1/Math.pow(-Infinity, -2));
+
+assertEquals(+Infinity, 1/Math.pow(+0, 1.1));
+assertEquals(+Infinity, 1/Math.pow(+0, 2));
assertEquals(Infinity, Math.pow(+0, -1.1));
assertEquals(Infinity, Math.pow(+0, -2));
-assertEquals(-0, Math.pow(-0, 3));
-assertEquals(-0, Math.pow(-0, 13));
-
-assertEquals(+0, Math.pow(-0, 3.1));
-assertEquals(+0, Math.pow(-0, 2));
+assertEquals(-Infinity, 1/Math.pow(-0, 3));
+assertEquals(-Infinity, 1/Math.pow(-0, 13));
+
+assertEquals(+Infinity, 1/Math.pow(-0, 3.1));
+assertEquals(+Infinity, 1/Math.pow(-0, 2));
assertEquals(-Infinity, Math.pow(-0, -3));
assertEquals(-Infinity, Math.pow(-0, -13));
@@ -123,6 +124,18 @@
assertEquals(NaN, Math.pow(-1000, 1.1));
assertEquals(NaN, Math.pow(-1000, -1.1));
+assertEquals(+Infinity, 1/Math.pow(-0, 0.5));
+assertEquals(+Infinity, 1/Math.pow(-0, 0.6));
+assertEquals(-Infinity, 1/Math.pow(-0, 1));
+assertEquals(-Infinity, 1/Math.pow(-0, 10000000001));
+
+assertEquals(+Infinity, Math.pow(-0, -0.5));
+assertEquals(+Infinity, Math.pow(-0, -0.6));
+assertEquals(-Infinity, Math.pow(-0, -1));
+assertEquals(-Infinity, Math.pow(-0, -10000000001));
+
+
+
// Tests from Sputnik S8.5_A13_T1.
assertTrue((1*((Math.pow(2,53))-1)*(Math.pow(2,-1074))) ===
4.4501477170144023e-308);
assertTrue((1*(Math.pow(2,52))*(Math.pow(2,-1074))) ===
2.2250738585072014e-308);
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev