Bug 1135039: Apply swizzle type policy changes in Ion too; r=sunfish
☠☠ backed out by b79d608ca174 ☠ ☠
authorBenjamin Bouvier <benj@benj.me>
Mon, 02 Mar 2015 19:40:06 +0100
changeset 261953 18c84fcee487097abe547d7a5cccf641ee489270
parent 261952 cc4786da89db2c3470551632e72d388a516d1abd
child 261954 f2a7b760ad5c0fc6bdf8d06f7ed97410f9d977c7
push id4718
push userraliiev@mozilla.com
push dateMon, 11 May 2015 18:39:53 +0000
treeherdermozilla-beta@c20c4ef55f08 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssunfish
bugs1135039
milestone39.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 1135039: Apply swizzle type policy changes in Ion too; r=sunfish
js/src/jit-test/tests/SIMD/swizzle.js
js/src/jit/Lowering.cpp
js/src/jit/MCallOptimize.cpp
js/src/jit/TypePolicy.cpp
js/src/jit/shared/CodeGenerator-x86-shared.cpp
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/SIMD/swizzle.js
@@ -0,0 +1,71 @@
+if (!this.hasOwnProperty("SIMD"))
+  quit();
+
+load(libdir + 'simd.js');
+
+setJitCompilerOption("ion.warmup.trigger", 50);
+
+function f() {
+    var i4 = SIMD.int32x4(1, 2, 3, 4);
+
+    var leet = Math.fround(13.37);
+    var f4 = SIMD.float32x4(-.5, -0, Infinity, leet);
+
+    var compI = [
+        [1,2,3,4],
+        [2,3,4,1],
+        [3,4,1,2],
+        [4,1,2,3]
+    ];
+
+    var compF = [
+        [-.5, -0, Infinity, leet],
+        [-0, Infinity, leet, -.5],
+        [Infinity, leet, -.5, -0],
+        [leet, -.5, -0, Infinity]
+    ];
+
+    for (var i = 0; i < 150; i++) {
+        // Variable lanes
+        var r = SIMD.float32x4.swizzle(f4, i % 4, (i + 1) % 4, (i + 2) % 4, (i + 3) % 4);
+        assertEqX4(r, compF[i % 4]);
+
+        // Constant lanes
+        assertEqX4(SIMD.float32x4.swizzle(f4, 3, 2, 1, 0), [leet, Infinity, -0, -.5]);
+
+        // Variable lanes
+        var r = SIMD.int32x4.swizzle(i4, i % 4, (i + 1) % 4, (i + 2) % 4, (i + 3) % 4);
+        assertEqX4(r, compI[i % 4]);
+
+        // Constant lanes
+        assertEqX4(SIMD.int32x4.swizzle(i4, 3, 2, 1, 0), [4, 3, 2, 1]);
+    }
+}
+
+function testBailouts(uglyDuckling) {
+    var i4 = SIMD.int32x4(1, 2, 3, 4);
+    for (var i = 0; i < 150; i++) {
+        // Test bailouts
+        var value = i == 149 ? uglyDuckling : 0;
+        var caught = false;
+        try {
+            assertEqX4(SIMD.int32x4.swizzle(i4, value, 3, 2, 0), [1, 4, 3, 1]);
+        } catch(e) {
+            print(e);
+            caught = true;
+            assertEq(i, 149);
+            assertEq(e instanceof TypeError, true);
+        }
+        assertEq(i < 149 || caught, true);
+    }
+}
+
+f();
+testBailouts(-1);
+testBailouts(4);
+testBailouts(2.5);
+testBailouts(undefined);
+testBailouts(null);
+testBailouts({});
+testBailouts('one');
+testBailouts(true);
--- a/js/src/jit/Lowering.cpp
+++ b/js/src/jit/Lowering.cpp
@@ -3958,20 +3958,22 @@ LIRGenerator::visitSimdGeneralSwizzle(MS
 
     LAllocation lanesUses[4];
     for (size_t i = 0; i < 4; i++)
         lanesUses[i] = use(ins->lane(i));
 
     if (ins->input()->type() == MIRType_Int32x4) {
         LSimdGeneralSwizzleI *lir = new (alloc()) LSimdGeneralSwizzleI(useRegister(ins->input()),
                                                                        lanesUses, temp());
+        assignSnapshot(lir, Bailout_BoundsCheck);
         define(lir, ins);
     } else if (ins->input()->type() == MIRType_Float32x4) {
         LSimdGeneralSwizzleF *lir = new (alloc()) LSimdGeneralSwizzleF(useRegister(ins->input()),
                                                                        lanesUses, temp());
+        assignSnapshot(lir, Bailout_BoundsCheck);
         define(lir, ins);
     } else {
         MOZ_CRASH("Unknown SIMD kind when getting lane");
     }
 }
 
 void
 LIRGenerator::visitSimdShuffle(MSimdShuffle *ins)
--- a/js/src/jit/MCallOptimize.cpp
+++ b/js/src/jit/MCallOptimize.cpp
@@ -349,23 +349,24 @@ IonBuilder::inlineNativeCall(CallInfo &c
         return inlineSimdSelect(callInfo, native, IsElementWise(false), SimdTypeDescr::TYPE_INT32);
     if (native == js::simd_float32x4_select)
         return inlineSimdSelect(callInfo, native, IsElementWise(true), SimdTypeDescr::TYPE_FLOAT32);
     if (native == js::simd_float32x4_bitselect)
         return inlineSimdSelect(callInfo, native, IsElementWise(false), SimdTypeDescr::TYPE_FLOAT32);
 
     if (native == js::simd_int32x4_swizzle)
         return inlineSimdSwizzle(callInfo, native, SimdTypeDescr::TYPE_INT32);
+    if (native == js::simd_float32x4_swizzle)
+        return inlineSimdSwizzle(callInfo, native, SimdTypeDescr::TYPE_FLOAT32);
 
     if (native == js::simd_int32x4_load)
         return inlineSimdLoad(callInfo, native, SimdTypeDescr::TYPE_INT32);
     if (native == js::simd_float32x4_load)
         return inlineSimdLoad(callInfo, native, SimdTypeDescr::TYPE_FLOAT32);
 
-
     if (native == js::simd_int32x4_store)
         return inlineSimdStore(callInfo, native, SimdTypeDescr::TYPE_INT32);
     if (native == js::simd_float32x4_store)
         return inlineSimdStore(callInfo, native, SimdTypeDescr::TYPE_FLOAT32);
 
     return InliningStatus_NotInlined;
 }
 
--- a/js/src/jit/TypePolicy.cpp
+++ b/js/src/jit/TypePolicy.cpp
@@ -795,17 +795,17 @@ SimdSwizzlePolicy::adjustInputs(TempAllo
         return false;
 
     // Next inputs are the lanes, which need to be int32
     for (unsigned i = 0; i < 4; i++) {
         MDefinition *in = ins->getOperand(i + 1);
         if (in->type() == MIRType_Int32)
             continue;
 
-        MInstruction *replace = MTruncateToInt32::New(alloc, in);
+        MInstruction *replace = MToInt32::New(alloc, in, MacroAssembler::IntConversion_NumbersOnly);
         ins->block()->insertBefore(ins, replace);
         ins->replaceOperand(i + 1, replace);
         if (!replace->typePolicy()->adjustInputs(alloc, replace))
             return false;
     }
 
     return true;
 }
--- a/js/src/jit/shared/CodeGenerator-x86-shared.cpp
+++ b/js/src/jit/shared/CodeGenerator-x86-shared.cpp
@@ -2387,87 +2387,96 @@ CodeGeneratorX86Shared::visitSimdGeneral
 
     // This won't generate fast code, but it's fine because we expect users
     // to have used constant indices (and thus MSimdGeneralSwizzle to be fold
     // into MSimdSwizzle, which are fast).
     masm.reserveStack(Simd128DataSize * 2);
 
     masm.storeAlignedInt32x4(input, Address(StackPointer, Simd128DataSize));
 
+    Label bail;
+
     for (size_t i = 0; i < 4; i++) {
         Operand lane = ToOperand(ins->lane(i));
 
-        Label go, join;
-        masm.cmp32(lane, Imm32(4));
-        masm.j(Assembler::Below, &go);
-
-        {
-            masm.store32(Imm32(0), Address(StackPointer, i * sizeof(int32_t)));
-            masm.jump(&join);
-        }
-
-        masm.bind(&go);
+        masm.cmp32(lane, Imm32(3));
+        masm.j(Assembler::Above, &bail);
+
         if (lane.kind() == Operand::REG) {
             masm.load32(Operand(StackPointer, ToRegister(ins->lane(i)), TimesFour, Simd128DataSize),
                         temp);
         } else {
             masm.load32(lane, temp);
             masm.load32(Operand(StackPointer, temp, TimesFour, Simd128DataSize), temp);
         }
 
         masm.store32(temp, Address(StackPointer, i * sizeof(int32_t)));
-        masm.bind(&join);
     }
 
     FloatRegister output = ToFloatRegister(ins->output());
     masm.loadAlignedInt32x4(Address(StackPointer, 0), output);
 
+    Label join;
+    masm.jump(&join);
+
+    {
+        masm.bind(&bail);
+        masm.setFramePushed(masm.framePushed() + Simd128DataSize * 2);
+        masm.freeStack(Simd128DataSize * 2);
+        bailout(ins->snapshot());
+    }
+
+    masm.bind(&join);
     masm.freeStack(Simd128DataSize * 2);
 }
 
 void
 CodeGeneratorX86Shared::visitSimdGeneralSwizzleF(LSimdGeneralSwizzleF *ins)
 {
     FloatRegister input = ToFloatRegister(ins->base());
     Register temp = ToRegister(ins->temp());
 
     // See comment in the visitSimdGeneralSwizzleI.
     masm.reserveStack(Simd128DataSize * 2);
 
     masm.storeAlignedFloat32x4(input, Address(StackPointer, Simd128DataSize));
 
+    Label bail;
+
     for (size_t i = 0; i < 4; i++) {
         Operand lane = ToOperand(ins->lane(i));
 
-        Label go, join;
-        masm.cmp32(lane, Imm32(4));
-        masm.j(Assembler::Below, &go);
-
-        {
-            masm.loadConstantFloat32(float(GenericNaN()), ScratchFloat32Reg);
-            masm.storeFloat32(ScratchFloat32Reg, Address(StackPointer, i * sizeof(int32_t)));
-            masm.jump(&join);
-        }
-
-        masm.bind(&go);
+        masm.cmp32(lane, Imm32(3));
+        masm.j(Assembler::Above, &bail);
+
         if (lane.kind() == Operand::REG) {
             masm.loadFloat32(Operand(StackPointer, ToRegister(ins->lane(i)), TimesFour, Simd128DataSize),
                              ScratchFloat32Reg);
         } else {
             masm.load32(lane, temp);
             masm.loadFloat32(Operand(StackPointer, temp, TimesFour, Simd128DataSize), ScratchFloat32Reg);
         }
 
         masm.storeFloat32(ScratchFloat32Reg, Address(StackPointer, i * sizeof(int32_t)));
-        masm.bind(&join);
     }
 
     FloatRegister output = ToFloatRegister(ins->output());
     masm.loadAlignedFloat32x4(Address(StackPointer, 0), output);
 
+    Label join;
+    masm.jump(&join);
+
+    {
+        masm.bind(&bail);
+        masm.setFramePushed(masm.framePushed() + Simd128DataSize * 2);
+        masm.freeStack(Simd128DataSize * 2);
+        bailout(ins->snapshot());
+    }
+
+    masm.bind(&join);
     masm.freeStack(Simd128DataSize * 2);
 }
 
 void
 CodeGeneratorX86Shared::visitSimdSwizzleI(LSimdSwizzleI *ins)
 {
     FloatRegister input = ToFloatRegister(ins->input());
     FloatRegister output = ToFloatRegister(ins->output());