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, &not_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, &not_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, &not_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

Reply via email to