@@ -43,6 +43,7 @@ const DEFAULT_WASM_MULTI_VALUE: bool = true;
4343const DEFAULT_WASM_MULTI_MEMORY : bool = true ;
4444const DEFAULT_WASM_BULK_MEMORY : bool = true ;
4545const DEFAULT_WASM_SIMD : bool = true ;
46+ const DEFAULT_WASM_RELAXED_SIMD : bool = false ;
4647const DEFAULT_WASM_REFERENCE_TYPES : bool = true ;
4748
4849/// The type of data that is stored in the `wasmtime::Store` during
@@ -140,6 +141,18 @@ pub struct Wizer {
140141 #[ cfg_attr( feature = "structopt" , structopt( long = "allow-wasi" ) ) ]
141142 allow_wasi : bool ,
142143
144+ /// Use deterministic behavior for relaxed SIMD instructions.
145+ ///
146+ /// The relaxed SIMD instructions in Wasm are instructions which are
147+ /// permitted to have different results when run on different host
148+ /// CPU architectures. This flag tells wizer to instead execute relaxed
149+ /// SIMD instructions according to the [deterministic profile], which
150+ /// ensures that they're deterministic and platform-independent.
151+ ///
152+ /// [deterministic profile]: https://webassembly.github.io/spec/core/appendix/profiles.html#deterministic-profile-small-mathrm-det
153+ #[ cfg_attr( feature = "structopt" , structopt( long = "relaxed-simd-deterministic" ) ) ]
154+ relaxed_simd_deterministic : bool ,
155+
143156 /// Provide an additional preloaded module that is available to the
144157 /// main module.
145158 ///
@@ -252,6 +265,13 @@ pub struct Wizer {
252265 #[ cfg_attr( feature = "structopt" , structopt( long, value_name = "true|false" ) ) ]
253266 wasm_simd : Option < bool > ,
254267
268+ /// Enable or disable the Wasm relaxed SIMD proposal.
269+ ///
270+ /// Disabled by default. When enabled, by default relaxed SIMD instructions
271+ /// will produce different results on different platforms. For deterministic
272+ /// results, additionally enable the `--relaxed-simd-deterministic` flag.
273+ wasm_relaxed_simd : Option < bool > ,
274+
255275 /// Enable or disable the Wasm reference-types proposal.
256276 ///
257277 /// Currently does not implement snapshotting or the use of references,
@@ -269,6 +289,7 @@ impl std::fmt::Debug for Wizer {
269289 init_func,
270290 func_renames,
271291 allow_wasi,
292+ relaxed_simd_deterministic,
272293 preload,
273294 preload_bytes,
274295 make_linker : _,
@@ -281,12 +302,14 @@ impl std::fmt::Debug for Wizer {
281302 wasm_multi_value,
282303 wasm_bulk_memory,
283304 wasm_simd,
305+ wasm_relaxed_simd,
284306 wasm_reference_types,
285307 } = self ;
286308 f. debug_struct ( "Wizer" )
287309 . field ( "init_func" , & init_func)
288310 . field ( "func_renames" , & func_renames)
289311 . field ( "allow_wasi" , & allow_wasi)
312+ . field ( "relaxed_simd_deterministic" , & relaxed_simd_deterministic)
290313 . field ( "preload" , & preload)
291314 . field ( "preload_bytes" , & preload_bytes)
292315 . field ( "make_linker" , & ".." )
@@ -299,6 +322,7 @@ impl std::fmt::Debug for Wizer {
299322 . field ( "wasm_multi_value" , & wasm_multi_value)
300323 . field ( "wasm_bulk_memory" , & wasm_bulk_memory)
301324 . field ( "wasm_simd" , & wasm_simd)
325+ . field ( "wasm_relaxed_simd" , & wasm_relaxed_simd)
302326 . field ( "wasm_reference_types" , & wasm_reference_types)
303327 . finish ( )
304328 }
@@ -352,6 +376,7 @@ impl Wizer {
352376 init_func : "wizer.initialize" . into ( ) ,
353377 func_renames : vec ! [ ] ,
354378 allow_wasi : false ,
379+ relaxed_simd_deterministic : false ,
355380 preload : vec ! [ ] ,
356381 preload_bytes : vec ! [ ] ,
357382 make_linker : None ,
@@ -364,6 +389,7 @@ impl Wizer {
364389 wasm_multi_value : None ,
365390 wasm_bulk_memory : None ,
366391 wasm_simd : None ,
392+ wasm_relaxed_simd : None ,
367393 wasm_reference_types : None ,
368394 }
369395 }
@@ -405,6 +431,19 @@ impl Wizer {
405431 Ok ( self )
406432 }
407433
434+ /// Use deterministic behavior for relaxed SIMD instructions.
435+ ///
436+ /// The relaxed SIMD instructions in Wasm are instructions which are
437+ /// permitted to have different results when run on different host
438+ /// CPU architectures. This flag tells wizer to instead execute relaxed
439+ /// SIMD instructions according to the [deterministic profile], which
440+ /// ensures that they're deterministic and platform-independent.
441+ ///
442+ /// [deterministic profile]: https://webassembly.github.io/spec/core/appendix/profiles.html#deterministic-profile-small-mathrm-det
443+ pub fn relaxed_simd_deterministic ( & mut self , deterministic : bool ) {
444+ self . relaxed_simd_deterministic = deterministic;
445+ }
446+
408447 /// Provide an additional preloaded module that is available to the
409448 /// main module.
410449 ///
@@ -583,6 +622,15 @@ impl Wizer {
583622 self
584623 }
585624
625+ /// Enable or disable the Wasm relaxed SIMD proposal.
626+ ///
627+ /// Defaults to `false`. When enabling, consdider whether to additionally
628+ /// use `relaxed_simd_deterministic`.
629+ pub fn wasm_relaxed_simd ( & mut self , enable : bool ) -> & mut Self {
630+ self . wasm_relaxed_simd = Some ( enable) ;
631+ self
632+ }
633+
586634 /// Initialize the given Wasm, snapshot it, and return the serialized
587635 /// snapshot as a new, pre-initialized Wasm module.
588636 pub fn run ( & self , wasm : & [ u8 ] ) -> anyhow:: Result < Vec < u8 > > {
@@ -658,6 +706,7 @@ impl Wizer {
658706 config. wasm_bulk_memory ( self . wasm_bulk_memory . unwrap_or ( DEFAULT_WASM_BULK_MEMORY ) ) ;
659707
660708 config. wasm_simd ( self . wasm_simd . unwrap_or ( DEFAULT_WASM_SIMD ) ) ;
709+ config. wasm_relaxed_simd ( self . wasm_relaxed_simd . unwrap_or ( DEFAULT_WASM_RELAXED_SIMD ) ) ;
661710
662711 // Note that reference_types are not actually supported,
663712 // but many compilers now enable them by default
@@ -669,12 +718,8 @@ impl Wizer {
669718 config. wasm_tail_call ( true ) ;
670719 config. wasm_extended_const ( true ) ;
671720
672- // The spec requires relaxed-simd instructions to be deterministic
673- // within a run. We don't have any way configure the nondeterminism
674- // of the code after a snapshot restore, however we can at least
675- // use deterministic lowerings so that if the subsequent engine
676- // also uses deterministic lowerings, it'll match.
677- config. relaxed_simd_deterministic ( true ) ;
721+ // Enable `relaxed_simd_deterministic` if requested.
722+ config. relaxed_simd_deterministic ( self . relaxed_simd_deterministic ) ;
678723
679724 // Proposals that we should add support for.
680725 config. wasm_threads ( false ) ;
@@ -710,6 +755,7 @@ impl Wizer {
710755
711756 features. set ( WasmFeatures :: TAIL_CALL , true ) ;
712757 features. set ( WasmFeatures :: EXTENDED_CONST , true ) ;
758+ features. set ( WasmFeatures :: RELAXED_SIMD , true ) ;
713759
714760 return features;
715761 }
0 commit comments