mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-23 21:01:08 +00:00
Bug 1669428 - Properly control experimental SIMD instructions. r=jseward
This gets rid of an ad-hoc boolean constant and introduces a configuration flag for experimental SIMD instructions. The flag is on by default in Nightly if SIMD is also enabled; otherwise off. This patch therefore disables support for experimental SIMD instructions in beta and release, where they have been available with the other SIMD instructions behind a pref. This seems OK: code using unstable bits of an in-progress proposal should stick to Nightly. Differential Revision: https://phabricator.services.mozilla.com/D92554
This commit is contained in:
parent
17bba3d008
commit
907323e1fd
@ -681,6 +681,29 @@ def wasm_simd(value, jit_enabled, simulator, target):
|
||||
set_config('ENABLE_WASM_SIMD', wasm_simd)
|
||||
set_define('ENABLE_WASM_SIMD', wasm_simd)
|
||||
|
||||
# Experimental SIMD opcodes are Nightly-only by default
|
||||
|
||||
@depends(milestone.is_nightly, '--enable-wasm-simd')
|
||||
def default_wasm_simd_experimental(is_nightly, wasm_simd):
|
||||
if is_nightly and wasm_simd:
|
||||
return True
|
||||
|
||||
js_option('--enable-wasm-simd-experimental',
|
||||
default=default_wasm_simd_experimental,
|
||||
help='{Enable|Disable} WebAssembly SIMD experimental opcodes')
|
||||
|
||||
@depends('--enable-wasm-simd-experimental', '--enable-wasm-simd')
|
||||
def wasm_simd_experimental(value, wasm_simd):
|
||||
if not value:
|
||||
return
|
||||
|
||||
if wasm_simd:
|
||||
return True
|
||||
|
||||
die('--enable-wasm-simd-experimental only possible with --enable-wasm-simd')
|
||||
|
||||
set_config('ENABLE_WASM_SIMD_EXPERIMENTAL', wasm_simd_experimental)
|
||||
set_define('ENABLE_WASM_SIMD_EXPERIMENTAL', wasm_simd_experimental)
|
||||
|
||||
# Options for generating the shell as a script
|
||||
# ============================================
|
||||
|
@ -874,6 +874,17 @@ static bool WasmSimdEnabled(JSContext* cx, unsigned argc, Value* vp) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool WasmSimdExperimentalEnabled(JSContext* cx, unsigned argc,
|
||||
Value* vp) {
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
#ifdef ENABLE_WASM_SIMD_EXPERIMENTAL
|
||||
args.rval().setBoolean(wasm::SimdAvailable(cx));
|
||||
#else
|
||||
args.rval().setBoolean(false);
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool WasmCompilersPresent(JSContext* cx, unsigned argc, Value* vp) {
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
|
||||
@ -4988,7 +4999,6 @@ static bool EvalStencilXDR(JSContext* cx, uint32_t argc, Value* vp) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/* Instantiate the stencil. */
|
||||
frontend::CompilationGCOutput output(cx);
|
||||
if (!compilationInfos.get().instantiateStencils(cx, output)) {
|
||||
@ -6792,6 +6802,11 @@ gc::ZealModeHelpText),
|
||||
" Returns a boolean indicating whether WebAssembly SIMD is supported by the\n"
|
||||
" compilers and runtime."),
|
||||
|
||||
JS_FN_HELP("wasmSimdExperimentalEnabled", WasmSimdExperimentalEnabled, 0, 0,
|
||||
"wasmSimdExperimentalEnabled()",
|
||||
" Returns a boolean indicating whether WebAssembly SIMD experimental instructions\n"
|
||||
" are supported by the compilers and runtime."),
|
||||
|
||||
JS_FN_HELP("wasmReftypesEnabled", WasmReftypesEnabled, 1, 0,
|
||||
"wasmReftypesEnabled()",
|
||||
" Returns a boolean indicating whether the WebAssembly reftypes proposal is enabled."),
|
||||
|
@ -1,15 +1,9 @@
|
||||
// |jit-test| skip-if: !wasmSimdEnabled()
|
||||
// |jit-test| skip-if: !wasmSimdExperimentalEnabled()
|
||||
|
||||
// Experimental opcodes. We have no text parsing support for these yet. The
|
||||
// tests will be cleaned up and moved into ad-hack.js if the opcodes are
|
||||
// adopted.
|
||||
|
||||
// When simd is enabled by default in release builds we will flip the value of
|
||||
// SimdExperimentalEnabled to false in RELEASE_OR_BETA builds. At that point,
|
||||
// these tests will start failing in release or beta builds, and a guard
|
||||
// asserting !RELEASE_OR_BETA will have to be added above. That is how it
|
||||
// should be.
|
||||
|
||||
load(libdir + "wasm-binary.js");
|
||||
|
||||
function wasmEval(bytes, imports) {
|
||||
|
@ -13996,10 +13996,11 @@ bool BaseCompiler::emitBody() {
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
#define CHECK_EXPERIMENTAL_SIMD() \
|
||||
if (!SimdExperimentalEnabled) { \
|
||||
break; \
|
||||
}
|
||||
#ifdef ENABLE_WASM_SIMD_EXPERIMENTAL
|
||||
# define CHECK_SIMD_EXPERIMENTAL() (void)(0)
|
||||
#else
|
||||
# define CHECK_SIMD_EXPERIMENTAL() break
|
||||
#endif
|
||||
|
||||
#define CHECK(E) \
|
||||
if (!(E)) return false
|
||||
@ -14962,19 +14963,19 @@ bool BaseCompiler::emitBody() {
|
||||
case uint32_t(SimdOp::V8x16Swizzle):
|
||||
CHECK_NEXT(dispatchVectorBinary(Swizzle));
|
||||
case uint32_t(SimdOp::F32x4PMaxExperimental):
|
||||
CHECK_EXPERIMENTAL_SIMD();
|
||||
CHECK_SIMD_EXPERIMENTAL();
|
||||
CHECK_NEXT(dispatchVectorBinary(PMaxF32x4));
|
||||
case uint32_t(SimdOp::F32x4PMinExperimental):
|
||||
CHECK_EXPERIMENTAL_SIMD();
|
||||
CHECK_SIMD_EXPERIMENTAL();
|
||||
CHECK_NEXT(dispatchVectorBinary(PMinF32x4));
|
||||
case uint32_t(SimdOp::F64x2PMaxExperimental):
|
||||
CHECK_EXPERIMENTAL_SIMD();
|
||||
CHECK_SIMD_EXPERIMENTAL();
|
||||
CHECK_NEXT(dispatchVectorBinary(PMaxF64x2));
|
||||
case uint32_t(SimdOp::F64x2PMinExperimental):
|
||||
CHECK_EXPERIMENTAL_SIMD();
|
||||
CHECK_SIMD_EXPERIMENTAL();
|
||||
CHECK_NEXT(dispatchVectorBinary(PMinF64x2));
|
||||
case uint32_t(SimdOp::I32x4DotSI16x8Experimental):
|
||||
CHECK_EXPERIMENTAL_SIMD();
|
||||
CHECK_SIMD_EXPERIMENTAL();
|
||||
CHECK_NEXT(dispatchVectorBinary(DotI16x8));
|
||||
case uint32_t(SimdOp::I8x16Neg):
|
||||
CHECK_NEXT(dispatchVectorUnary(NegI8x16));
|
||||
@ -15029,28 +15030,28 @@ bool BaseCompiler::emitBody() {
|
||||
case uint32_t(SimdOp::I32x4Abs):
|
||||
CHECK_NEXT(dispatchVectorUnary(AbsI32x4));
|
||||
case uint32_t(SimdOp::F32x4CeilExperimental):
|
||||
CHECK_EXPERIMENTAL_SIMD();
|
||||
CHECK_SIMD_EXPERIMENTAL();
|
||||
CHECK_NEXT(dispatchVectorUnary(CeilF32x4));
|
||||
case uint32_t(SimdOp::F32x4FloorExperimental):
|
||||
CHECK_EXPERIMENTAL_SIMD();
|
||||
CHECK_SIMD_EXPERIMENTAL();
|
||||
CHECK_NEXT(dispatchVectorUnary(FloorF32x4));
|
||||
case uint32_t(SimdOp::F32x4TruncExperimental):
|
||||
CHECK_EXPERIMENTAL_SIMD();
|
||||
CHECK_SIMD_EXPERIMENTAL();
|
||||
CHECK_NEXT(dispatchVectorUnary(TruncF32x4));
|
||||
case uint32_t(SimdOp::F32x4NearestExperimental):
|
||||
CHECK_EXPERIMENTAL_SIMD();
|
||||
CHECK_SIMD_EXPERIMENTAL();
|
||||
CHECK_NEXT(dispatchVectorUnary(NearestF32x4));
|
||||
case uint32_t(SimdOp::F64x2CeilExperimental):
|
||||
CHECK_EXPERIMENTAL_SIMD();
|
||||
CHECK_SIMD_EXPERIMENTAL();
|
||||
CHECK_NEXT(dispatchVectorUnary(CeilF64x2));
|
||||
case uint32_t(SimdOp::F64x2FloorExperimental):
|
||||
CHECK_EXPERIMENTAL_SIMD();
|
||||
CHECK_SIMD_EXPERIMENTAL();
|
||||
CHECK_NEXT(dispatchVectorUnary(FloorF64x2));
|
||||
case uint32_t(SimdOp::F64x2TruncExperimental):
|
||||
CHECK_EXPERIMENTAL_SIMD();
|
||||
CHECK_SIMD_EXPERIMENTAL();
|
||||
CHECK_NEXT(dispatchVectorUnary(TruncF64x2));
|
||||
case uint32_t(SimdOp::F64x2NearestExperimental):
|
||||
CHECK_EXPERIMENTAL_SIMD();
|
||||
CHECK_SIMD_EXPERIMENTAL();
|
||||
CHECK_NEXT(dispatchVectorUnary(NearestF64x2));
|
||||
case uint32_t(SimdOp::I8x16Shl):
|
||||
CHECK_NEXT(dispatchVectorVariableShift(ShiftLeftI8x16));
|
||||
@ -15111,10 +15112,10 @@ bool BaseCompiler::emitBody() {
|
||||
case uint32_t(SimdOp::I64x2LoadU32x2):
|
||||
CHECK_NEXT(emitLoadExtend(Scalar::Uint32));
|
||||
case uint32_t(SimdOp::V128Load32ZeroExperimental):
|
||||
CHECK_EXPERIMENTAL_SIMD();
|
||||
CHECK_SIMD_EXPERIMENTAL();
|
||||
CHECK_NEXT(emitLoadZero(Scalar::Float32));
|
||||
case uint32_t(SimdOp::V128Load64ZeroExperimental):
|
||||
CHECK_EXPERIMENTAL_SIMD();
|
||||
CHECK_SIMD_EXPERIMENTAL();
|
||||
CHECK_NEXT(emitLoadZero(Scalar::Float64));
|
||||
case uint32_t(SimdOp::V128Store):
|
||||
CHECK_NEXT(emitStore(ValType::V128, Scalar::Simd128));
|
||||
@ -15420,7 +15421,7 @@ bool BaseCompiler::emitBody() {
|
||||
#undef NEXT
|
||||
#undef CHECK_NEXT
|
||||
#undef CHECK_POINTER_COUNT
|
||||
#undef CHECK_EXPERIMENTAL_SIMD
|
||||
#undef CHECK_SIMD_EXPERIMENTAL
|
||||
#undef dispatchBinary
|
||||
#undef dispatchUnary
|
||||
#undef dispatchComparison
|
||||
|
@ -424,11 +424,6 @@ enum class GcOp {
|
||||
// Opcodes with suffix 'Experimental' are proposed but not standardized, and are
|
||||
// compatible with those same opcodes in V8. No opcode labeled 'Experimental'
|
||||
// will ship in a Release build where SIMD is enabled by default.
|
||||
//
|
||||
// Once SIMD ships default-on in release builds, the following flag must be set
|
||||
// to false for RELEASE_OR_BETA.
|
||||
|
||||
static constexpr bool SimdExperimentalEnabled = true;
|
||||
|
||||
enum class SimdOp {
|
||||
V128Load = 0x00,
|
||||
|
@ -4307,10 +4307,11 @@ static bool EmitBodyExprs(FunctionCompiler& f) {
|
||||
if (!(c)) return false; \
|
||||
break
|
||||
|
||||
#define CHECK_EXPERIMENTAL_SIMD() \
|
||||
if (!SimdExperimentalEnabled) { \
|
||||
return f.iter().unrecognizedOpcode(&op); \
|
||||
}
|
||||
#ifdef ENABLE_WASM_SIMD_EXPERIMENTAL
|
||||
# define CHECK_SIMD_EXPERIMENTAL() (void)(0)
|
||||
#else
|
||||
# define CHECK_SIMD_EXPERIMENTAL() return f.iter().unrecognizedOpcode(&op)
|
||||
#endif
|
||||
|
||||
while (true) {
|
||||
if (!f.mirGen().ensureBallast()) {
|
||||
@ -4844,7 +4845,7 @@ static bool EmitBodyExprs(FunctionCompiler& f) {
|
||||
case uint32_t(SimdOp::F64x2Ne):
|
||||
CHECK(EmitBinarySimd128(f, /* commutative= */ true, SimdOp(op.b1)));
|
||||
case uint32_t(SimdOp::I32x4DotSI16x8Experimental):
|
||||
CHECK_EXPERIMENTAL_SIMD();
|
||||
CHECK_SIMD_EXPERIMENTAL();
|
||||
CHECK(EmitBinarySimd128(f, /* commutative= */ true, SimdOp(op.b1)));
|
||||
case uint32_t(SimdOp::V128AndNot):
|
||||
case uint32_t(SimdOp::I8x16Sub):
|
||||
@ -4902,7 +4903,7 @@ static bool EmitBodyExprs(FunctionCompiler& f) {
|
||||
case uint32_t(SimdOp::F32x4PMinExperimental):
|
||||
case uint32_t(SimdOp::F64x2PMaxExperimental):
|
||||
case uint32_t(SimdOp::F64x2PMinExperimental):
|
||||
CHECK_EXPERIMENTAL_SIMD();
|
||||
CHECK_SIMD_EXPERIMENTAL();
|
||||
CHECK(
|
||||
EmitBinarySimd128(f, /* commutative= */ false, SimdOp(op.b1)));
|
||||
case uint32_t(SimdOp::I8x16Splat):
|
||||
@ -4950,7 +4951,7 @@ static bool EmitBodyExprs(FunctionCompiler& f) {
|
||||
case uint32_t(SimdOp::F64x2FloorExperimental):
|
||||
case uint32_t(SimdOp::F64x2TruncExperimental):
|
||||
case uint32_t(SimdOp::F64x2NearestExperimental):
|
||||
CHECK_EXPERIMENTAL_SIMD();
|
||||
CHECK_SIMD_EXPERIMENTAL();
|
||||
CHECK(EmitUnarySimd128(f, SimdOp(op.b1)));
|
||||
case uint32_t(SimdOp::I8x16AnyTrue):
|
||||
case uint32_t(SimdOp::I16x8AnyTrue):
|
||||
@ -5021,10 +5022,10 @@ static bool EmitBodyExprs(FunctionCompiler& f) {
|
||||
case uint32_t(SimdOp::I64x2LoadU32x2):
|
||||
CHECK(EmitLoadExtendSimd128(f, SimdOp(op.b1)));
|
||||
case uint32_t(SimdOp::V128Load32ZeroExperimental):
|
||||
CHECK_EXPERIMENTAL_SIMD();
|
||||
CHECK_SIMD_EXPERIMENTAL();
|
||||
CHECK(EmitLoadZeroSimd128(f, Scalar::Float32, 4));
|
||||
case uint32_t(SimdOp::V128Load64ZeroExperimental):
|
||||
CHECK_EXPERIMENTAL_SIMD();
|
||||
CHECK_SIMD_EXPERIMENTAL();
|
||||
CHECK(EmitLoadZeroSimd128(f, Scalar::Float64, 8));
|
||||
default:
|
||||
return f.iter().unrecognizedOpcode(&op);
|
||||
@ -5354,7 +5355,7 @@ static bool EmitBodyExprs(FunctionCompiler& f) {
|
||||
MOZ_CRASH("unreachable");
|
||||
|
||||
#undef CHECK
|
||||
#undef CHECK_EXPERIMENTAL_SIMD
|
||||
#undef CHECK_SIMD_EXPERIMENTAL
|
||||
}
|
||||
|
||||
bool wasm::IonCompileFunctions(const ModuleEnvironment& env, LifoAlloc& lifo,
|
||||
|
@ -483,10 +483,11 @@ static bool DecodeFunctionBodyExprs(const ModuleEnvironment& env,
|
||||
if (!(c)) return false; \
|
||||
break
|
||||
|
||||
#define CHECK_EXPERIMENTAL_SIMD() \
|
||||
if (!SimdExperimentalEnabled) { \
|
||||
return iter.unrecognizedOpcode(&op); \
|
||||
}
|
||||
#ifdef ENABLE_WASM_SIMD_EXPERIMENTAL
|
||||
# define CHECK_SIMD_EXPERIMENTAL() (void)(0)
|
||||
#else
|
||||
# define CHECK_SIMD_EXPERIMENTAL() return iter.unrecognizedOpcode(&op)
|
||||
#endif
|
||||
|
||||
while (true) {
|
||||
OpBytes op;
|
||||
@ -1058,7 +1059,7 @@ static bool DecodeFunctionBodyExprs(const ModuleEnvironment& env,
|
||||
case uint32_t(SimdOp::F64x2PMaxExperimental):
|
||||
case uint32_t(SimdOp::F64x2PMinExperimental):
|
||||
case uint32_t(SimdOp::I32x4DotSI16x8Experimental):
|
||||
CHECK_EXPERIMENTAL_SIMD();
|
||||
CHECK_SIMD_EXPERIMENTAL();
|
||||
CHECK(iter.readBinary(ValType::V128, ¬hing, ¬hing));
|
||||
|
||||
case uint32_t(SimdOp::I8x16Neg):
|
||||
@ -1097,7 +1098,7 @@ static bool DecodeFunctionBodyExprs(const ModuleEnvironment& env,
|
||||
case uint32_t(SimdOp::F64x2FloorExperimental):
|
||||
case uint32_t(SimdOp::F64x2TruncExperimental):
|
||||
case uint32_t(SimdOp::F64x2NearestExperimental):
|
||||
CHECK_EXPERIMENTAL_SIMD();
|
||||
CHECK_SIMD_EXPERIMENTAL();
|
||||
CHECK(iter.readUnary(ValType::V128, ¬hing));
|
||||
|
||||
case uint32_t(SimdOp::I8x16Shl):
|
||||
@ -1177,13 +1178,13 @@ static bool DecodeFunctionBodyExprs(const ModuleEnvironment& env,
|
||||
|
||||
case uint32_t(SimdOp::V128Load32ZeroExperimental): {
|
||||
LinearMemoryAddress<Nothing> addr;
|
||||
CHECK_EXPERIMENTAL_SIMD();
|
||||
CHECK_SIMD_EXPERIMENTAL();
|
||||
CHECK(iter.readLoadSplat(4, &addr));
|
||||
}
|
||||
|
||||
case uint32_t(SimdOp::V128Load64ZeroExperimental): {
|
||||
LinearMemoryAddress<Nothing> addr;
|
||||
CHECK_EXPERIMENTAL_SIMD();
|
||||
CHECK_SIMD_EXPERIMENTAL();
|
||||
CHECK(iter.readLoadSplat(8, &addr));
|
||||
}
|
||||
|
||||
@ -1507,7 +1508,7 @@ static bool DecodeFunctionBodyExprs(const ModuleEnvironment& env,
|
||||
MOZ_CRASH("unreachable");
|
||||
|
||||
#undef CHECK
|
||||
#undef CHECK_EXPERIMENTAL_SIMD
|
||||
#undef CHECK_SIMD_EXPERIMENTAL
|
||||
}
|
||||
|
||||
bool wasm::ValidateFunctionBody(const ModuleEnvironment& env,
|
||||
|
Loading…
Reference in New Issue
Block a user