@@ -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,14 @@ 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+ #[ cfg_attr( feature = "structopt" , structopt( long, value_name = "true|false" ) ) ]
274+ wasm_relaxed_simd : Option < bool > ,
275+
255276 /// Enable or disable the Wasm reference-types proposal.
256277 ///
257278 /// Currently does not implement snapshotting or the use of references,
@@ -269,6 +290,7 @@ impl std::fmt::Debug for Wizer {
269290 init_func,
270291 func_renames,
271292 allow_wasi,
293+ relaxed_simd_deterministic,
272294 preload,
273295 preload_bytes,
274296 make_linker : _,
@@ -281,12 +303,14 @@ impl std::fmt::Debug for Wizer {
281303 wasm_multi_value,
282304 wasm_bulk_memory,
283305 wasm_simd,
306+ wasm_relaxed_simd,
284307 wasm_reference_types,
285308 } = self ;
286309 f. debug_struct ( "Wizer" )
287310 . field ( "init_func" , & init_func)
288311 . field ( "func_renames" , & func_renames)
289312 . field ( "allow_wasi" , & allow_wasi)
313+ . field ( "relaxed_simd_deterministic" , & relaxed_simd_deterministic)
290314 . field ( "preload" , & preload)
291315 . field ( "preload_bytes" , & preload_bytes)
292316 . field ( "make_linker" , & ".." )
@@ -299,6 +323,7 @@ impl std::fmt::Debug for Wizer {
299323 . field ( "wasm_multi_value" , & wasm_multi_value)
300324 . field ( "wasm_bulk_memory" , & wasm_bulk_memory)
301325 . field ( "wasm_simd" , & wasm_simd)
326+ . field ( "wasm_relaxed_simd" , & wasm_relaxed_simd)
302327 . field ( "wasm_reference_types" , & wasm_reference_types)
303328 . finish ( )
304329 }
@@ -352,6 +377,7 @@ impl Wizer {
352377 init_func : "wizer.initialize" . into ( ) ,
353378 func_renames : vec ! [ ] ,
354379 allow_wasi : false ,
380+ relaxed_simd_deterministic : false ,
355381 preload : vec ! [ ] ,
356382 preload_bytes : vec ! [ ] ,
357383 make_linker : None ,
@@ -364,6 +390,7 @@ impl Wizer {
364390 wasm_multi_value : None ,
365391 wasm_bulk_memory : None ,
366392 wasm_simd : None ,
393+ wasm_relaxed_simd : None ,
367394 wasm_reference_types : None ,
368395 }
369396 }
@@ -405,6 +432,19 @@ impl Wizer {
405432 Ok ( self )
406433 }
407434
435+ /// Use deterministic behavior for relaxed SIMD instructions.
436+ ///
437+ /// The relaxed SIMD instructions in Wasm are instructions which are
438+ /// permitted to have different results when run on different host
439+ /// CPU architectures. This flag tells wizer to instead execute relaxed
440+ /// SIMD instructions according to the [deterministic profile], which
441+ /// ensures that they're deterministic and platform-independent.
442+ ///
443+ /// [deterministic profile]: https://webassembly.github.io/spec/core/appendix/profiles.html#deterministic-profile-small-mathrm-det
444+ pub fn relaxed_simd_deterministic ( & mut self , deterministic : bool ) {
445+ self . relaxed_simd_deterministic = deterministic;
446+ }
447+
408448 /// Provide an additional preloaded module that is available to the
409449 /// main module.
410450 ///
@@ -583,6 +623,15 @@ impl Wizer {
583623 self
584624 }
585625
626+ /// Enable or disable the Wasm relaxed SIMD proposal.
627+ ///
628+ /// Defaults to `false`. When enabling, consdider whether to additionally
629+ /// use `relaxed_simd_deterministic`.
630+ pub fn wasm_relaxed_simd ( & mut self , enable : bool ) -> & mut Self {
631+ self . wasm_relaxed_simd = Some ( enable) ;
632+ self
633+ }
634+
586635 /// Initialize the given Wasm, snapshot it, and return the serialized
587636 /// snapshot as a new, pre-initialized Wasm module.
588637 pub fn run ( & self , wasm : & [ u8 ] ) -> anyhow:: Result < Vec < u8 > > {
@@ -658,6 +707,7 @@ impl Wizer {
658707 config. wasm_bulk_memory ( self . wasm_bulk_memory . unwrap_or ( DEFAULT_WASM_BULK_MEMORY ) ) ;
659708
660709 config. wasm_simd ( self . wasm_simd . unwrap_or ( DEFAULT_WASM_SIMD ) ) ;
710+ config. wasm_relaxed_simd ( self . wasm_relaxed_simd . unwrap_or ( DEFAULT_WASM_RELAXED_SIMD ) ) ;
661711
662712 // Note that reference_types are not actually supported,
663713 // but many compilers now enable them by default
@@ -669,6 +719,9 @@ impl Wizer {
669719 config. wasm_tail_call ( true ) ;
670720 config. wasm_extended_const ( true ) ;
671721
722+ // Enable `relaxed_simd_deterministic` if requested.
723+ config. relaxed_simd_deterministic ( self . relaxed_simd_deterministic ) ;
724+
672725 // Proposals that we should add support for.
673726 config. wasm_threads ( false ) ;
674727
@@ -703,6 +756,10 @@ impl Wizer {
703756
704757 features. set ( WasmFeatures :: TAIL_CALL , true ) ;
705758 features. set ( WasmFeatures :: EXTENDED_CONST , true ) ;
759+ features. set (
760+ WasmFeatures :: RELAXED_SIMD ,
761+ self . wasm_relaxed_simd . unwrap_or ( DEFAULT_WASM_RELAXED_SIMD ) ,
762+ ) ;
706763
707764 return features;
708765 }
0 commit comments