Bug 1435756 - Clarify fallthrough in generated code for wasm truncate. r=bbouvier
authorLars T Hansen <lhansen@mozilla.com>
Mon, 05 Feb 2018 20:29:27 +0100
changeset 402514 95245d5d7560d1a858c0ec80c4da820dfb182063
parent 402513 a69a458dec3d02a932ca5a2144558e8882b0b636
child 402515 256247373b45b3599feb86ee570004633587f864
push id99584
push userlhansen@mozilla.com
push dateTue, 06 Feb 2018 10:59:43 +0000
treeherdermozilla-inbound@95245d5d7560 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbbouvier
bugs1435756
milestone60.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 1435756 - Clarify fallthrough in generated code for wasm truncate. r=bbouvier
js/src/jit/x86-shared/MacroAssembler-x86-shared.cpp
--- a/js/src/jit/x86-shared/MacroAssembler-x86-shared.cpp
+++ b/js/src/jit/x86-shared/MacroAssembler-x86-shared.cpp
@@ -678,26 +678,27 @@ MacroAssembler::wasmTrapInstruction()
 }
 
 // RAII class that generates the jumps to traps when it's destructed, to
 // prevent some code duplication in the outOfLineWasmTruncateXtoY methods.
 struct MOZ_RAII AutoHandleWasmTruncateToIntErrors
 {
     MacroAssembler& masm;
     Label inputIsNaN;
-    Label fail;
+    Label intOverflow;
     wasm::BytecodeOffset off;
 
     explicit AutoHandleWasmTruncateToIntErrors(MacroAssembler& masm, wasm::BytecodeOffset off)
       : masm(masm), off(off)
     { }
 
     ~AutoHandleWasmTruncateToIntErrors() {
-        // Handle errors.
-        masm.bind(&fail);
+        // Handle errors.  These cases are not in arbitrary order: code will
+        // fall through to intOverflow.
+        masm.bind(&intOverflow);
         masm.jump(wasm::OldTrapDesc(off, wasm::Trap::IntegerOverflow, masm.framePushed()));
 
         masm.bind(&inputIsNaN);
         masm.jump(wasm::OldTrapDesc(off, wasm::Trap::InvalidConversionToInteger, masm.framePushed()));
     }
 };
 
 void
@@ -720,100 +721,104 @@ void
 MacroAssembler::oolWasmTruncateCheckF64ToI32(FloatRegister input, bool isUnsigned,
                                              wasm::BytecodeOffset off, Label* rejoin)
 {
     AutoHandleWasmTruncateToIntErrors traps(*this, off);
 
     // Eagerly take care of NaNs.
     branchDouble(Assembler::DoubleUnordered, input, input, &traps.inputIsNaN);
 
-    // Handle special values (not needed for unsigned values).
+    // For unsigned, fall through to intOverflow failure case.
     if (isUnsigned)
         return;
 
+    // Handle special values.
+
     // We've used vcvttsd2si. The only valid double values that can
     // truncate to INT32_MIN are in ]INT32_MIN - 1; INT32_MIN].
     loadConstantDouble(double(INT32_MIN) - 1.0, ScratchDoubleReg);
-    branchDouble(Assembler::DoubleLessThanOrEqual, input, ScratchDoubleReg, &traps.fail);
+    branchDouble(Assembler::DoubleLessThanOrEqual, input, ScratchDoubleReg, &traps.intOverflow);
 
     loadConstantDouble(double(INT32_MIN), ScratchDoubleReg);
-    branchDouble(Assembler::DoubleGreaterThan, input, ScratchDoubleReg, &traps.fail);
+    branchDouble(Assembler::DoubleGreaterThan, input, ScratchDoubleReg, &traps.intOverflow);
     jump(rejoin);
 }
 
 void
 MacroAssembler::oolWasmTruncateCheckF32ToI32(FloatRegister input, bool isUnsigned,
                                              wasm::BytecodeOffset off, Label* rejoin)
 {
     AutoHandleWasmTruncateToIntErrors traps(*this, off);
 
     // Eagerly take care of NaNs.
     branchFloat(Assembler::DoubleUnordered, input, input, &traps.inputIsNaN);
 
-    // Handle special values (not needed for unsigned values).
+    // For unsigned, fall through to intOverflow failure case.
     if (isUnsigned)
         return;
 
+    // Handle special values.
+
     // We've used vcvttss2si. Check that the input wasn't
     // float(INT32_MIN), which is the only legimitate input that
     // would truncate to INT32_MIN.
     loadConstantFloat32(float(INT32_MIN), ScratchFloat32Reg);
-    branchFloat(Assembler::DoubleNotEqual, input, ScratchFloat32Reg, &traps.fail);
+    branchFloat(Assembler::DoubleNotEqual, input, ScratchFloat32Reg, &traps.intOverflow);
     jump(rejoin);
 }
 
 void
 MacroAssembler::oolWasmTruncateCheckF64ToI64(FloatRegister input, bool isUnsigned,
                                              wasm::BytecodeOffset off, Label* rejoin)
 {
     AutoHandleWasmTruncateToIntErrors traps(*this, off);
 
     // Eagerly take care of NaNs.
     branchDouble(Assembler::DoubleUnordered, input, input, &traps.inputIsNaN);
 
     // Handle special values.
     if (isUnsigned) {
         loadConstantDouble(-0.0, ScratchDoubleReg);
-        branchDouble(Assembler::DoubleGreaterThan, input, ScratchDoubleReg, &traps.fail);
+        branchDouble(Assembler::DoubleGreaterThan, input, ScratchDoubleReg, &traps.intOverflow);
         loadConstantDouble(-1.0, ScratchDoubleReg);
-        branchDouble(Assembler::DoubleLessThanOrEqual, input, ScratchDoubleReg, &traps.fail);
+        branchDouble(Assembler::DoubleLessThanOrEqual, input, ScratchDoubleReg, &traps.intOverflow);
         jump(rejoin);
         return;
     }
 
     // We've used vcvtsd2sq. The only legit value whose i64
     // truncation is INT64_MIN is double(INT64_MIN): exponent is so
     // high that the highest resolution around is much more than 1.
     loadConstantDouble(double(int64_t(INT64_MIN)), ScratchDoubleReg);
-    branchDouble(Assembler::DoubleNotEqual, input, ScratchDoubleReg, &traps.fail);
+    branchDouble(Assembler::DoubleNotEqual, input, ScratchDoubleReg, &traps.intOverflow);
     jump(rejoin);
 }
 
 void
 MacroAssembler::oolWasmTruncateCheckF32ToI64(FloatRegister input, bool isUnsigned,
                                              wasm::BytecodeOffset off, Label* rejoin)
 {
     AutoHandleWasmTruncateToIntErrors traps(*this, off);
 
     // Eagerly take care of NaNs.
     branchFloat(Assembler::DoubleUnordered, input, input, &traps.inputIsNaN);
 
     // Handle special values.
     if (isUnsigned) {
         loadConstantFloat32(-0.0f, ScratchFloat32Reg);
-        branchFloat(Assembler::DoubleGreaterThan, input, ScratchFloat32Reg, &traps.fail);
+        branchFloat(Assembler::DoubleGreaterThan, input, ScratchFloat32Reg, &traps.intOverflow);
         loadConstantFloat32(-1.0f, ScratchFloat32Reg);
-        branchFloat(Assembler::DoubleLessThanOrEqual, input, ScratchFloat32Reg, &traps.fail);
+        branchFloat(Assembler::DoubleLessThanOrEqual, input, ScratchFloat32Reg, &traps.intOverflow);
         jump(rejoin);
         return;
     }
 
     // We've used vcvtss2sq. See comment in outOfLineWasmTruncateDoubleToInt64.
     loadConstantFloat32(float(int64_t(INT64_MIN)), ScratchFloat32Reg);
-    branchFloat(Assembler::DoubleNotEqual, input, ScratchFloat32Reg, &traps.fail);
+    branchFloat(Assembler::DoubleNotEqual, input, ScratchFloat32Reg, &traps.intOverflow);
     jump(rejoin);
 }
 
 // ========================================================================
 // Primitive atomic operations.
 
 static void
 ExtendTo32(MacroAssembler& masm, Scalar::Type type, Register r)