Bug 1329016 - Allow negative zero in CacheIR index check. r=jandem
authorTom Schuster <evilpies@gmail.com>
Fri, 20 Jan 2017 12:43:47 +0100
changeset 375337 59962d7c3d8c00a6d774362deb0934e84b1938c6
parent 375336 9b5cc104aaf600a84643800a17bddfbed0acbc24
child 375338 ab4dc22fcd04354db1dc728754b497a83ca01e34
push id6996
push userjlorenzo@mozilla.com
push dateMon, 06 Mar 2017 20:48:21 +0000
treeherdermozilla-beta@d89512dab048 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjandem
bugs1329016
milestone53.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1329016 - Allow negative zero in CacheIR index check. r=jandem
js/src/jit-test/tests/basic/negative-zero-index.js
js/src/jit/CacheIR.cpp
js/src/jit/CacheIRCompiler.cpp
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/basic/negative-zero-index.js
@@ -0,0 +1,20 @@
+function test() {
+    const array = [1];
+    for (let i = 0; i < 10; i++) {
+        assertEq(array[0], 1);
+        assertEq(array[0.0], 1);
+        assertEq(array[-0.0], 1);
+        // ToPropertyKey(-0.0) is "0", but "-0" is distinct!
+        assertEq(array["-0"], undefined);
+    }
+
+    const string = "a";
+    for (let i = 0; i < 10; i++) {
+        assertEq(string[0], "a");
+        assertEq(string[0.0], "a");
+        assertEq(string[-0.0], "a");
+        assertEq(string["-0"], undefined);
+    }
+}
+
+test();
--- a/js/src/jit/CacheIR.cpp
+++ b/js/src/jit/CacheIR.cpp
@@ -1493,17 +1493,18 @@ bool
 IRGenerator::maybeGuardInt32Index(const Value& index, ValOperandId indexId,
                                   uint32_t* int32Index, Int32OperandId* int32IndexId)
 {
     if (index.isNumber()) {
         int32_t indexSigned;
         if (index.isInt32()) {
             indexSigned = index.toInt32();
         } else {
-            if (!mozilla::NumberIsInt32(index.toDouble(), &indexSigned))
+            // We allow negative zero here.
+            if (!mozilla::NumberEqualsInt32(index.toDouble(), &indexSigned))
                 return false;
             if (!cx_->runtime()->jitSupportsFloatingPoint)
                 return false;
         }
 
         if (indexSigned < 0)
             return false;
 
--- a/js/src/jit/CacheIRCompiler.cpp
+++ b/js/src/jit/CacheIRCompiler.cpp
@@ -1135,18 +1135,20 @@ CacheIRCompiler::emitGuardIsInt32Index()
         masm.branchTestDouble(Assembler::NotEqual, input, failure->label());
 
         // If we're compiling a Baseline IC, FloatReg0 is always available.
         Label failurePopReg;
         if (mode_ != Mode::Baseline)
             masm.push(FloatReg0);
 
         masm.unboxDouble(input, FloatReg0);
+        // ToPropertyKey(-0.0) is "0", so we can truncate -0.0 to 0 here.
         masm.convertDoubleToInt32(FloatReg0, output,
-                                  (mode_ == Mode::Baseline) ? failure->label() : &failurePopReg);
+                                  (mode_ == Mode::Baseline) ? failure->label() : &failurePopReg,
+                                  false);
         if (mode_ != Mode::Baseline) {
             masm.pop(FloatReg0);
             masm.jump(&done);
 
             masm.bind(&failurePopReg);
             masm.pop(FloatReg0);
             masm.jump(failure->label());
         }