From 4f386b736aff1dccae9b0357b1aeb5aaae8c8b0a Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Wed, 20 Nov 2024 12:15:19 -0700 Subject: [PATCH] Refactor the `#[wasmtime_test]` macro (#9627) * Refactor the `#[wasmtime_test]` macro * Start tests with a blank slate of features instead of with the default set of features enables (ensures each test explicitly specifies required features) * Reuse test features from `wasmtime_wast_util` to avoid duplicating listings of features. Also shares logic for "should this compiler fail this test because of unsupported features". * Move logic in `tests/wast.rs` to apply test configuration to a `Config` to a new location that can be shared across suites. * Add a new feature for `simd` and flag tests that need it with the feature. This is done in preparation for adding a new compiler strategy of Pulley to be able to flag tests as passing for pulley or not. * Review feedback --- Cargo.lock | 2 + crates/fuzzing/src/generators/config.rs | 51 +++++--- crates/misc/component-test-util/Cargo.toml | 1 + crates/misc/component-test-util/src/lib.rs | 77 ++++++++++++ crates/test-macros/Cargo.toml | 1 + crates/test-macros/src/lib.rs | 107 +++++++--------- crates/wast-util/src/lib.rs | 116 +++++++++++++----- tests/all/func.rs | 14 +-- tests/misc_testsuite/int-to-float-splat.wast | 2 + tests/misc_testsuite/issue6562.wast | 2 + tests/misc_testsuite/memory64/simd.wast | 1 + tests/misc_testsuite/simd/almost-extmul.wast | 2 + .../misc_testsuite/simd/canonicalize-nan.wast | 1 + tests/misc_testsuite/simd/cvt-from-uint.wast | 3 +- .../simd/interesting-float-splat.wast | 2 + tests/misc_testsuite/simd/issue4807.wast | 2 + .../simd/issue6725-no-egraph-panic.wast | 2 + .../simd/issue_3173_select_v128.wast | 2 + .../simd/issue_3327_bnot_lowering.wast | 2 + .../simd/load_splat_out_of_bounds.wast | 2 + .../simd/replace-lane-preserve.wast | 2 + .../simd/spillslot-size-fuzzbug.wast | 2 + tests/misc_testsuite/simd/unaligned-load.wast | 2 + tests/misc_testsuite/simd/v128-select.wast | 2 + tests/misc_testsuite/winch/_simd_address.wast | 2 + tests/misc_testsuite/winch/_simd_const.wast | 2 + tests/misc_testsuite/winch/_simd_linking.wast | 2 + tests/misc_testsuite/winch/_simd_load.wast | 4 +- .../winch/_simd_multivalue.wast | 4 +- tests/misc_testsuite/winch/_simd_store.wast | 2 + tests/wast.rs | 51 +------- 31 files changed, 299 insertions(+), 168 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7fc82148c16c..1fa6bc6a63bc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -646,6 +646,7 @@ dependencies = [ "arbitrary", "env_logger 0.11.5", "wasmtime", + "wasmtime-wast-util", ] [[package]] @@ -4313,6 +4314,7 @@ dependencies = [ "proc-macro2", "quote", "syn 2.0.60", + "wasmtime-wast-util", ] [[package]] diff --git a/crates/fuzzing/src/generators/config.rs b/crates/fuzzing/src/generators/config.rs index 171ed9c49301..443b888af183 100644 --- a/crates/fuzzing/src/generators/config.rs +++ b/crates/fuzzing/src/generators/config.rs @@ -122,33 +122,50 @@ impl Config { /// This will additionally update limits in the pooling allocator to be able /// to execute all tests. pub fn make_wast_test_compliant(&mut self, test: &WastTest) -> WastConfig { + let wasmtime_wast_util::TestConfig { + memory64, + custom_page_sizes, + multi_memory, + threads, + gc, + function_references, + relaxed_simd, + reference_types, + tail_call, + extended_const, + wide_arithmetic, + component_model_more_flags, + simd, + + hogs_memory: _, + nan_canonicalization: _, + gc_types: _, + } = test.config; + // Enable/disable some proposals that aren't configurable in wasm-smith // but are configurable in Wasmtime. - self.module_config.function_references_enabled = test - .config - .function_references - .or(test.config.gc) - .unwrap_or(false); - self.module_config.component_model_more_flags = - test.config.component_model_more_flags.unwrap_or(false); + self.module_config.function_references_enabled = + function_references.or(gc).unwrap_or(false); + self.module_config.component_model_more_flags = component_model_more_flags.unwrap_or(false); // Enable/disable proposals that wasm-smith has knobs for which will be // read when creating `wasmtime::Config`. let config = &mut self.module_config.config; config.bulk_memory_enabled = true; config.multi_value_enabled = true; - config.simd_enabled = true; - config.wide_arithmetic_enabled = test.config.wide_arithmetic.unwrap_or(false); - config.memory64_enabled = test.config.memory64.unwrap_or(false); - config.tail_call_enabled = test.config.tail_call.unwrap_or(false); - config.custom_page_sizes_enabled = test.config.custom_page_sizes.unwrap_or(false); - config.threads_enabled = test.config.threads.unwrap_or(false); - config.gc_enabled = test.config.gc.unwrap_or(false); + config.wide_arithmetic_enabled = wide_arithmetic.unwrap_or(false); + config.memory64_enabled = memory64.unwrap_or(false); + config.relaxed_simd_enabled = relaxed_simd.unwrap_or(false); + config.simd_enabled = config.relaxed_simd_enabled || simd.unwrap_or(false); + config.tail_call_enabled = tail_call.unwrap_or(false); + config.custom_page_sizes_enabled = custom_page_sizes.unwrap_or(false); + config.threads_enabled = threads.unwrap_or(false); + config.gc_enabled = gc.unwrap_or(false); config.reference_types_enabled = config.gc_enabled || self.module_config.function_references_enabled - || test.config.reference_types.unwrap_or(false); - config.extended_const_enabled = test.config.extended_const.unwrap_or(false); - if test.config.multi_memory.unwrap_or(false) { + || reference_types.unwrap_or(false); + config.extended_const_enabled = extended_const.unwrap_or(false); + if multi_memory.unwrap_or(false) { config.max_memories = limits::MEMORIES_PER_MODULE as usize; } else { config.max_memories = 1; diff --git a/crates/misc/component-test-util/Cargo.toml b/crates/misc/component-test-util/Cargo.toml index 181a2f4e3e19..0d7a27bdbf41 100644 --- a/crates/misc/component-test-util/Cargo.toml +++ b/crates/misc/component-test-util/Cargo.toml @@ -12,3 +12,4 @@ env_logger = { workspace = true } anyhow = { workspace = true } arbitrary = { workspace = true, features = ["derive"] } wasmtime = { workspace = true, features = ["component-model", "async"] } +wasmtime-wast-util = { path = '../../wast-util' } diff --git a/crates/misc/component-test-util/src/lib.rs b/crates/misc/component-test-util/src/lib.rs index eddb7654722f..bc7993d69cd8 100644 --- a/crates/misc/component-test-util/src/lib.rs +++ b/crates/misc/component-test-util/src/lib.rs @@ -129,3 +129,80 @@ forward_impls! { Float32 => f32, Float64 => f64, } + +/// Helper method to apply `wast_config` to `config`. +pub fn apply_wast_config(config: &mut Config, wast_config: &wasmtime_wast_util::WastConfig) { + config.strategy(match wast_config.compiler { + wasmtime_wast_util::Compiler::Cranelift => wasmtime::Strategy::Cranelift, + wasmtime_wast_util::Compiler::Winch => wasmtime::Strategy::Winch, + }); + config.collector(match wast_config.collector { + wasmtime_wast_util::Collector::Auto => wasmtime::Collector::Auto, + wasmtime_wast_util::Collector::Null => wasmtime::Collector::Null, + wasmtime_wast_util::Collector::DeferredReferenceCounting => { + wasmtime::Collector::DeferredReferenceCounting + } + }); +} + +/// Helper method to apply `test_config` to `config`. +pub fn apply_test_config(config: &mut Config, test_config: &wasmtime_wast_util::TestConfig) { + let wasmtime_wast_util::TestConfig { + memory64, + custom_page_sizes, + multi_memory, + threads, + gc, + function_references, + relaxed_simd, + reference_types, + tail_call, + extended_const, + wide_arithmetic, + component_model_more_flags, + nan_canonicalization, + simd, + + hogs_memory: _, + gc_types: _, + } = *test_config; + // Note that all of these proposals/features are currently default-off to + // ensure that we annotate all tests accurately with what features they + // need, even in the future when features are stabilized. + let memory64 = memory64.unwrap_or(false); + let custom_page_sizes = custom_page_sizes.unwrap_or(false); + let multi_memory = multi_memory.unwrap_or(false); + let threads = threads.unwrap_or(false); + let gc = gc.unwrap_or(false); + let tail_call = tail_call.unwrap_or(false); + let extended_const = extended_const.unwrap_or(false); + let wide_arithmetic = wide_arithmetic.unwrap_or(false); + let component_model_more_flags = component_model_more_flags.unwrap_or(false); + let nan_canonicalization = nan_canonicalization.unwrap_or(false); + let relaxed_simd = relaxed_simd.unwrap_or(false); + + // Some proposals in wasm depend on previous proposals. For example the gc + // proposal depends on function-references which depends on reference-types. + // To avoid needing to enable all of them at once implicitly enable + // downstream proposals once the end proposal is enabled (e.g. when enabling + // gc that also enables function-references and reference-types). + let function_references = gc || function_references.unwrap_or(false); + let reference_types = function_references || reference_types.unwrap_or(false); + let simd = relaxed_simd || simd.unwrap_or(false); + + config + .wasm_multi_memory(multi_memory) + .wasm_threads(threads) + .wasm_memory64(memory64) + .wasm_function_references(function_references) + .wasm_gc(gc) + .wasm_reference_types(reference_types) + .wasm_relaxed_simd(relaxed_simd) + .wasm_simd(simd) + .wasm_tail_call(tail_call) + .wasm_custom_page_sizes(custom_page_sizes) + .wasm_extended_const(extended_const) + .wasm_wide_arithmetic(wide_arithmetic) + .wasm_component_model_more_flags(component_model_more_flags) + .cranelift_nan_canonicalization(nan_canonicalization); +} diff --git a/crates/test-macros/Cargo.toml b/crates/test-macros/Cargo.toml index c4871a35935d..e24076630908 100644 --- a/crates/test-macros/Cargo.toml +++ b/crates/test-macros/Cargo.toml @@ -21,3 +21,4 @@ quote = "1.0" proc-macro2 = "1.0" syn = { workspace = true, features = ["full"] } anyhow = { workspace = true } +wasmtime-wast-util = { path = '../wast-util' } diff --git a/crates/test-macros/src/lib.rs b/crates/test-macros/src/lib.rs index 2bd76b6b56b7..7c125bbc653c 100644 --- a/crates/test-macros/src/lib.rs +++ b/crates/test-macros/src/lib.rs @@ -29,7 +29,6 @@ //! If the wasm feature is not supported by any of the compiler strategies, no //! tests will be generated for such strategy. use proc_macro::TokenStream; -use proc_macro2::Span; use quote::{quote, ToTokens, TokenStreamExt}; use syn::{ braced, @@ -37,18 +36,12 @@ use syn::{ parse::{Parse, ParseStream}, parse_macro_input, token, Attribute, Ident, Result, ReturnType, Signature, Visibility, }; +use wasmtime_wast_util::Compiler; /// Test configuration. struct TestConfig { - /// Supported compiler strategies. - strategies: Vec, - /// Known WebAssembly features that will be turned on by default in the - /// resulting Config. - /// The identifiers in this list are features that are off by default in - /// Wasmtime's Config, which will be explicitly turned on for a given test. - wasm_features: Vec, - /// Flag to track if there are Wasm features not supported by Winch. - wasm_features_unsupported_by_winch: bool, + strategies: Vec, + flags: wasmtime_wast_util::TestConfig, /// The test attribute to use. Defaults to `#[test]`. test_attribute: Option, } @@ -58,9 +51,11 @@ impl TestConfig { meta.parse_nested_meta(|meta| { if meta.path.is_ident("not") { meta.parse_nested_meta(|meta| { - if meta.path.is_ident("Winch") || meta.path.is_ident("Cranelift") { - let id = meta.path.require_ident()?.clone(); - self.strategies.retain(|s| *s != id); + if meta.path.is_ident("Winch") { + self.strategies.retain(|s| *s != Compiler::Winch); + Ok(()) + } else if meta.path.is_ident("Cranelift") { + self.strategies.retain(|s| *s != Compiler::Cranelift); Ok(()) } else { Err(meta.error("Unknown strategy")) @@ -80,32 +75,15 @@ impl TestConfig { fn wasm_features_from(&mut self, meta: &ParseNestedMeta) -> Result<()> { meta.parse_nested_meta(|meta| { - if meta.path.is_ident("gc") || meta.path.is_ident("function_references") { - let feature = meta.path.require_ident()?.clone(); - self.wasm_features.push(feature.clone()); - self.wasm_features_unsupported_by_winch = true; - Ok(()) - } else if meta.path.is_ident("simd") - || meta.path.is_ident("relaxed_simd") - || meta.path.is_ident("reference_types") - || meta.path.is_ident("tail_call") - || meta.path.is_ident("threads") - { - self.wasm_features_unsupported_by_winch = true; - Ok(()) - } else { - Err(meta.error("Unsupported wasm feature")) + for (feature, enabled) in self.flags.options_mut() { + if meta.path.is_ident(feature) { + *enabled = Some(true); + return Ok(()); + } } + Err(meta.error("Unsupported test feature")) })?; - if self.wasm_features.len() > 2 { - return Err(meta.error("Expected at most 2 off-by-default wasm features")); - } - - if self.wasm_features_unsupported_by_winch { - self.strategies.retain(|s| s.to_string() != "Winch"); - } - Ok(()) } @@ -119,12 +97,8 @@ impl TestConfig { impl Default for TestConfig { fn default() -> Self { Self { - strategies: vec![ - Ident::new("Cranelift", Span::call_site()), - Ident::new("Winch", Span::call_site()), - ], - wasm_features: vec![], - wasm_features_unsupported_by_winch: false, + strategies: vec![Compiler::Cranelift, Compiler::Winch], + flags: Default::default(), test_attribute: None, } } @@ -216,9 +190,7 @@ pub fn wasmtime_test(attrs: TokenStream, item: TokenStream) -> TokenStream { } fn expand(test_config: &TestConfig, func: Fn) -> Result { - let mut tests = if test_config.strategies.len() == 1 - && test_config.strategies.get(0).map(|s| s.to_string()) == Some("Winch".to_string()) - { + let mut tests = if test_config.strategies == [Compiler::Winch] { vec![quote! { // This prevents dead code warning when the macro is invoked as: // #[wasmtime_test(strategies(not(Cranelift))] @@ -236,10 +208,10 @@ fn expand(test_config: &TestConfig, func: Fn) -> Result { .clone() .unwrap_or_else(|| quote! { #[test] }); - for ident in &test_config.strategies { - let strategy_name = ident.to_string(); + for strategy in &test_config.strategies { + let strategy_name = format!("{strategy:?}"); // Winch currently only offers support for x64. - let target = if strategy_name == "Winch" { + let target = if *strategy == Compiler::Winch { quote! { #[cfg(target_arch = "x86_64")] } } else { quote! {} @@ -250,31 +222,46 @@ fn expand(test_config: &TestConfig, func: Fn) -> Result { (quote! {}, quote! {}) }; let func_name = &func.sig.ident; - let ret = match &func.sig.output { + let expect = match &func.sig.output { ReturnType::Default => quote! {}, - ReturnType::Type(_, ty) => quote! { -> #ty }, + ReturnType::Type(..) => quote! { .expect("test is expected to pass") }, }; let test_name = Ident::new( &format!("{}_{}", strategy_name.to_lowercase(), func_name), func_name.span(), ); - let config_setup = test_config.wasm_features.iter().map(|f| { - let method_name = Ident::new(&format!("wasm_{f}"), f.span()); - quote! { - config.#method_name(true); - } - }); + let should_panic = if strategy.should_fail(&test_config.flags) { + quote!(#[should_panic]) + } else { + quote!() + }; + + let test_config = format!("wasmtime_wast_util::{:?}", test_config.flags) + .parse::() + .unwrap(); + let strategy_ident = quote::format_ident!("{strategy_name}"); let tok = quote! { #test_attr #target + #should_panic #(#attrs)* - #asyncness fn #test_name() #ret { + #asyncness fn #test_name() { let mut config = Config::new(); - config.strategy(Strategy::#ident); - #(#config_setup)* - #func_name(&mut config) #await_ + component_test_util::apply_test_config( + &mut config, + &#test_config, + ); + component_test_util::apply_wast_config( + &mut config, + &wasmtime_wast_util::WastConfig { + compiler: wasmtime_wast_util::Compiler::#strategy_ident, + pooling: false, + collector: wasmtime_wast_util::Collector::Auto, + }, + ); + #func_name(&mut config) #await_ #expect } }; diff --git a/crates/wast-util/src/lib.rs b/crates/wast-util/src/lib.rs index c1177ec099ec..a83b3732c248 100644 --- a/crates/wast-util/src/lib.rs +++ b/crates/wast-util/src/lib.rs @@ -76,6 +76,7 @@ fn spec_test_config(test: &Path) -> TestConfig { Some("multi-memory") => { ret.multi_memory = Some(true); ret.reference_types = Some(true); + ret.simd = Some(true); } Some("wide-arithmetic") => { ret.wide_arithmetic = Some(true); @@ -118,9 +119,14 @@ fn spec_test_config(test: &Path) -> TestConfig { ret.function_references = Some(true); ret.tail_call = Some(true); } - Some("annotations") => {} + Some("annotations") => { + ret.simd = Some(true); + } Some(proposal) => panic!("unsuported proposal {proposal:?}"), - None => ret.reference_types = Some(true), + None => { + ret.reference_types = Some(true); + ret.simd = Some(true); + } } ret @@ -162,25 +168,55 @@ impl fmt::Debug for WastTest { } } -/// Per-test configuration which is written down in the test file itself for -/// `misc_testsuite/**/*.wast` or in `spec_test_config` above for spec tests. -#[derive(Debug, PartialEq, Default, Deserialize, Clone)] -#[serde(deny_unknown_fields)] -pub struct TestConfig { - pub memory64: Option, - pub custom_page_sizes: Option, - pub multi_memory: Option, - pub threads: Option, - pub gc: Option, - pub function_references: Option, - pub relaxed_simd: Option, - pub reference_types: Option, - pub tail_call: Option, - pub extended_const: Option, - pub wide_arithmetic: Option, - pub hogs_memory: Option, - pub nan_canonicalization: Option, - pub component_model_more_flags: Option, +macro_rules! foreach_config_option { + ($m:ident) => { + $m! { + memory64 + custom_page_sizes + multi_memory + threads + gc + function_references + relaxed_simd + reference_types + tail_call + extended_const + wide_arithmetic + hogs_memory + nan_canonicalization + component_model_more_flags + simd + gc_types + } + }; +} + +macro_rules! define_test_config { + ($($option:ident)*) => { + /// Per-test configuration which is written down in the test file itself for + /// `misc_testsuite/**/*.wast` or in `spec_test_config` above for spec tests. + #[derive(Debug, PartialEq, Default, Deserialize, Clone)] + #[serde(deny_unknown_fields)] + pub struct TestConfig { + $(pub $option: Option,)* + } + } +} + +foreach_config_option!(define_test_config); + +impl TestConfig { + /// Returns an iterator over each option. + pub fn options_mut(&mut self) -> impl Iterator)> { + macro_rules! mk { + ($($option:ident)*) => { + [ + $((stringify!($option), &mut self.$option),)* + ].into_iter() + } + } + foreach_config_option!(mk) + } } /// Configuration that spec tests can run under. @@ -199,6 +235,29 @@ pub enum Compiler { Winch, } +impl Compiler { + pub fn should_fail(&self, config: &TestConfig) -> bool { + match self { + Compiler::Cranelift => {} + Compiler::Winch => { + // A few proposals that winch has no support for. + if config.gc == Some(true) + || config.threads == Some(true) + || config.tail_call == Some(true) + || config.function_references == Some(true) + || config.gc == Some(true) + || config.relaxed_simd == Some(true) + || config.gc_types == Some(true) + { + return true; + } + } + } + + false + } +} + #[derive(PartialEq, Debug, Copy, Clone)] pub enum Collector { Auto, @@ -229,19 +288,12 @@ impl WastTest { return true; } + if config.compiler.should_fail(&self.config) { + return true; + } + // Disable spec tests for proposals that Winch does not implement yet. if config.compiler == Compiler::Winch { - // A few proposals that winch has no support for. - if self.config.gc == Some(true) - || self.config.threads == Some(true) - || self.config.tail_call == Some(true) - || self.config.function_references == Some(true) - || self.config.gc == Some(true) - || self.config.relaxed_simd == Some(true) - { - return true; - } - let unsupported = [ // externref/reference-types related "component-model/modules.wast", diff --git a/tests/all/func.rs b/tests/all/func.rs index 65a8e69924db..d664765f86f4 100644 --- a/tests/all/func.rs +++ b/tests/all/func.rs @@ -233,7 +233,7 @@ fn call_array_to_array() -> Result<()> { Ok(()) } -#[wasmtime_test] +#[wasmtime_test(wasm_features(reference_types))] #[cfg_attr(miri, ignore)] fn call_indirect_native_from_wasm_import_global(config: &mut Config) -> Result<()> { let wasm = wat::parse_str( @@ -297,7 +297,7 @@ fn call_indirect_native_from_wasm_import_table(config: &mut Config) -> Result<() Ok(()) } -#[wasmtime_test] +#[wasmtime_test(wasm_features(reference_types))] #[cfg_attr(miri, ignore)] fn call_indirect_native_from_wasm_import_func_returns_funcref(config: &mut Config) -> Result<()> { let wasm = wat::parse_str( @@ -355,7 +355,7 @@ fn call_indirect_native_from_exported_table(config: &mut Config) -> Result<()> { } // wasm exports global, host puts native-call funcref in global, wasm calls funcref -#[wasmtime_test] +#[wasmtime_test(wasm_features(reference_types))] #[cfg_attr(miri, ignore)] fn call_indirect_native_from_exported_global(config: &mut Config) -> Result<()> { let wasm = wat::parse_str( @@ -1332,7 +1332,7 @@ fn wrap_multiple_results(config: &mut Config) -> anyhow::Result<()> { } } -#[wasmtime_test(wasm_features(reference_types))] +#[wasmtime_test(wasm_features(reference_types, gc_types))] #[cfg_attr(miri, ignore)] fn trampoline_for_declared_elem(config: &mut Config) -> anyhow::Result<()> { let engine = Engine::new(&config)?; @@ -1461,7 +1461,7 @@ fn typed_funcs_count_params_correctly_in_error_messages(config: &mut Config) -> Ok(()) } -#[wasmtime_test(wasm_features(reference_types))] +#[wasmtime_test(wasm_features(reference_types, gc_types))] #[cfg_attr(miri, ignore)] fn calls_with_funcref_and_externref(config: &mut Config) -> anyhow::Result<()> { let engine = Engine::new(&config)?; @@ -1901,7 +1901,7 @@ fn call_wasm_getting_subtype_func_return(config: &mut Config) -> anyhow::Result< Ok(()) } -#[wasmtime_test(wasm_features(simd))] +#[wasmtime_test(wasm_features(simd), strategies(not(Winch)))] #[cfg_attr(miri, ignore)] #[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))] fn typed_v128(config: &mut Config) -> anyhow::Result<()> { @@ -1971,7 +1971,7 @@ fn typed_v128(config: &mut Config) -> anyhow::Result<()> { Ok(()) } -#[wasmtime_test] +#[wasmtime_test(wasm_features(simd))] #[cfg_attr(miri, ignore)] #[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))] fn typed_v128_imports(config: &mut Config) -> anyhow::Result<()> { diff --git a/tests/misc_testsuite/int-to-float-splat.wast b/tests/misc_testsuite/int-to-float-splat.wast index 2a6110200293..18c4063812bc 100644 --- a/tests/misc_testsuite/int-to-float-splat.wast +++ b/tests/misc_testsuite/int-to-float-splat.wast @@ -1,3 +1,5 @@ +;;! simd = true + (module (func (param i32) (result v128) local.get 0 diff --git a/tests/misc_testsuite/issue6562.wast b/tests/misc_testsuite/issue6562.wast index 5335e2c99886..286101dc40a6 100644 --- a/tests/misc_testsuite/issue6562.wast +++ b/tests/misc_testsuite/issue6562.wast @@ -1,3 +1,5 @@ +;;! simd = true + (module (func (result v128) i32.const 0 diff --git a/tests/misc_testsuite/memory64/simd.wast b/tests/misc_testsuite/memory64/simd.wast index c812ba91831c..0007f6359e1a 100644 --- a/tests/misc_testsuite/memory64/simd.wast +++ b/tests/misc_testsuite/memory64/simd.wast @@ -1,4 +1,5 @@ ;;! memory64 = true +;;! simd = true ;; make sure everything codegens correctly and has no cranelift verifier errors (module diff --git a/tests/misc_testsuite/simd/almost-extmul.wast b/tests/misc_testsuite/simd/almost-extmul.wast index b7ef287d7284..b5321979a04a 100644 --- a/tests/misc_testsuite/simd/almost-extmul.wast +++ b/tests/misc_testsuite/simd/almost-extmul.wast @@ -1,3 +1,5 @@ +;;! simd = true + ;; regression test from #3337, there's a multiplication that sort of ;; looks like an extmul and codegen shouldn't pattern match too much (module diff --git a/tests/misc_testsuite/simd/canonicalize-nan.wast b/tests/misc_testsuite/simd/canonicalize-nan.wast index 848cfa9ae92b..057a126d2eaf 100644 --- a/tests/misc_testsuite/simd/canonicalize-nan.wast +++ b/tests/misc_testsuite/simd/canonicalize-nan.wast @@ -1,4 +1,5 @@ ;;! nan_canonicalization = true +;;! simd = true ;; This *.wast test should be run with `cranelift_nan_canonicalization` set to ;; `true` in `wast.rs` diff --git a/tests/misc_testsuite/simd/cvt-from-uint.wast b/tests/misc_testsuite/simd/cvt-from-uint.wast index 76a3337d2791..f39a7c7f933e 100644 --- a/tests/misc_testsuite/simd/cvt-from-uint.wast +++ b/tests/misc_testsuite/simd/cvt-from-uint.wast @@ -1,3 +1,4 @@ +;;! simd = true ;; Tests inspired by https://github.com/bytecodealliance/wasmtime/issues/3161 ;; which found issue in lowering Opcode::FcvtFromUint where valid instruction @@ -45,4 +46,4 @@ (v128.const f32x4 0 0 0 0)) (assert_return (invoke "i64x2.extend_low_i32x4_u" (v128.const i32x4 0x00000000 0x00000000 0x00000000 0x00000000)) - (v128.const f32x4 0 0 0 0)) \ No newline at end of file + (v128.const f32x4 0 0 0 0)) diff --git a/tests/misc_testsuite/simd/interesting-float-splat.wast b/tests/misc_testsuite/simd/interesting-float-splat.wast index ab19f12d2af1..56e8779de515 100644 --- a/tests/misc_testsuite/simd/interesting-float-splat.wast +++ b/tests/misc_testsuite/simd/interesting-float-splat.wast @@ -1,3 +1,5 @@ +;;! simd = true + (module (func (export "") (result v128) v128.const i32x4 0x3f803f80 0x3f803f80 0x3f803f80 0x3f803f80 diff --git a/tests/misc_testsuite/simd/issue4807.wast b/tests/misc_testsuite/simd/issue4807.wast index da129044042a..970ceef7dd73 100644 --- a/tests/misc_testsuite/simd/issue4807.wast +++ b/tests/misc_testsuite/simd/issue4807.wast @@ -1,3 +1,5 @@ +;;! simd = true + (module (func (result i32) global.get 0 diff --git a/tests/misc_testsuite/simd/issue6725-no-egraph-panic.wast b/tests/misc_testsuite/simd/issue6725-no-egraph-panic.wast index 08b1ede72982..2065cca2dd40 100644 --- a/tests/misc_testsuite/simd/issue6725-no-egraph-panic.wast +++ b/tests/misc_testsuite/simd/issue6725-no-egraph-panic.wast @@ -1,3 +1,5 @@ +;;! simd = true + (module (func (param v128) (result v128) (i8x16.eq (local.get 0) (local.get 0)) diff --git a/tests/misc_testsuite/simd/issue_3173_select_v128.wast b/tests/misc_testsuite/simd/issue_3173_select_v128.wast index 612d39b2835d..1ce4d4364fe4 100644 --- a/tests/misc_testsuite/simd/issue_3173_select_v128.wast +++ b/tests/misc_testsuite/simd/issue_3173_select_v128.wast @@ -1,3 +1,5 @@ +;;! simd = true + (; See issue https://github.com/bytecodealliance/wasmtime/issues/3173. ;) (module diff --git a/tests/misc_testsuite/simd/issue_3327_bnot_lowering.wast b/tests/misc_testsuite/simd/issue_3327_bnot_lowering.wast index 93faaf6df8c4..b92a0d3c38da 100644 --- a/tests/misc_testsuite/simd/issue_3327_bnot_lowering.wast +++ b/tests/misc_testsuite/simd/issue_3327_bnot_lowering.wast @@ -1,3 +1,5 @@ +;;! simd = true + (; See issue https://github.com/bytecodealliance/wasmtime/issues/3327 ;) (module diff --git a/tests/misc_testsuite/simd/load_splat_out_of_bounds.wast b/tests/misc_testsuite/simd/load_splat_out_of_bounds.wast index 9085aa67d72f..9cb8c5ba0cb4 100644 --- a/tests/misc_testsuite/simd/load_splat_out_of_bounds.wast +++ b/tests/misc_testsuite/simd/load_splat_out_of_bounds.wast @@ -1,3 +1,5 @@ +;;! simd = true + ;; aligned and out of bounds (module (func diff --git a/tests/misc_testsuite/simd/replace-lane-preserve.wast b/tests/misc_testsuite/simd/replace-lane-preserve.wast index 2f7903d9d207..da090a82f4f3 100644 --- a/tests/misc_testsuite/simd/replace-lane-preserve.wast +++ b/tests/misc_testsuite/simd/replace-lane-preserve.wast @@ -1,3 +1,5 @@ +;;! simd = true + ;; originally from #3216 (module (func (result i64) diff --git a/tests/misc_testsuite/simd/spillslot-size-fuzzbug.wast b/tests/misc_testsuite/simd/spillslot-size-fuzzbug.wast index 287b9274474a..c7a6a6367de0 100644 --- a/tests/misc_testsuite/simd/spillslot-size-fuzzbug.wast +++ b/tests/misc_testsuite/simd/spillslot-size-fuzzbug.wast @@ -1,3 +1,5 @@ +;;! simd = true + (module (func (export "test") (result f32 f32) i32.const 0 diff --git a/tests/misc_testsuite/simd/unaligned-load.wast b/tests/misc_testsuite/simd/unaligned-load.wast index 359dbe0a6faf..e8a03142e6c1 100644 --- a/tests/misc_testsuite/simd/unaligned-load.wast +++ b/tests/misc_testsuite/simd/unaligned-load.wast @@ -1,3 +1,5 @@ +;;! simd = true + (; See discussion at https://github.com/bytecodealliance/wasmtime/issues/2943 ;) (module (memory 1) diff --git a/tests/misc_testsuite/simd/v128-select.wast b/tests/misc_testsuite/simd/v128-select.wast index 5018a7901f2e..0c0eee9a04f0 100644 --- a/tests/misc_testsuite/simd/v128-select.wast +++ b/tests/misc_testsuite/simd/v128-select.wast @@ -1,3 +1,5 @@ +;;! simd = true + (module (func (export "select") (param v128 v128 i32) (result v128) local.get 0 diff --git a/tests/misc_testsuite/winch/_simd_address.wast b/tests/misc_testsuite/winch/_simd_address.wast index 9e023008bba1..e092214cde4c 100644 --- a/tests/misc_testsuite/winch/_simd_address.wast +++ b/tests/misc_testsuite/winch/_simd_address.wast @@ -1,3 +1,5 @@ +;;! simd = true + ;; Load/Store v128 data with different valid offset/alignment (module diff --git a/tests/misc_testsuite/winch/_simd_const.wast b/tests/misc_testsuite/winch/_simd_const.wast index 35e00243372f..4bd8160d4a28 100644 --- a/tests/misc_testsuite/winch/_simd_const.wast +++ b/tests/misc_testsuite/winch/_simd_const.wast @@ -1,3 +1,5 @@ +;;! simd = true + ;; v128.const normal parameter (e.g. (i8x16, i16x8 i32x4, f32x4)) (module (func (v128.const i8x16 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF) drop)) diff --git a/tests/misc_testsuite/winch/_simd_linking.wast b/tests/misc_testsuite/winch/_simd_linking.wast index 1a1d16355e9a..8e556b78bc99 100644 --- a/tests/misc_testsuite/winch/_simd_linking.wast +++ b/tests/misc_testsuite/winch/_simd_linking.wast @@ -1,3 +1,5 @@ +;;! simd = true + (module (global (export "g-v128") v128 (v128.const i64x2 0 0)) (global (export "mg-v128") (mut v128) (v128.const i64x2 0 0)) diff --git a/tests/misc_testsuite/winch/_simd_load.wast b/tests/misc_testsuite/winch/_simd_load.wast index 907b7cc2eaf3..e6dab2bf2b73 100644 --- a/tests/misc_testsuite/winch/_simd_load.wast +++ b/tests/misc_testsuite/winch/_simd_load.wast @@ -1,3 +1,5 @@ +;;! simd = true + ;; v128.load operater with normal argument (e.g. (i8x16, i16x8 i32x4)) (module @@ -185,4 +187,4 @@ (assert_invalid (module (memory 1) (func (drop (v128.load)))) "type mismatch" -) \ No newline at end of file +) diff --git a/tests/misc_testsuite/winch/_simd_multivalue.wast b/tests/misc_testsuite/winch/_simd_multivalue.wast index c4f70f2318e8..63a63a03a140 100644 --- a/tests/misc_testsuite/winch/_simd_multivalue.wast +++ b/tests/misc_testsuite/winch/_simd_multivalue.wast @@ -1,3 +1,5 @@ +;;! simd = true + ;; test that swapping the parameters results in swapped return values (module (func (export "f") (param v128) (param v128) (result v128) (result v128) (local.get 1) (local.get 0))) -(assert_return (invoke "f" (v128.const i64x2 2 1) (v128.const i64x2 1 2)) (v128.const i64x2 1 2) (v128.const i64x2 2 1)) \ No newline at end of file +(assert_return (invoke "f" (v128.const i64x2 2 1) (v128.const i64x2 1 2)) (v128.const i64x2 1 2) (v128.const i64x2 2 1)) diff --git a/tests/misc_testsuite/winch/_simd_store.wast b/tests/misc_testsuite/winch/_simd_store.wast index 50349c41bd82..9e59e8e316ab 100644 --- a/tests/misc_testsuite/winch/_simd_store.wast +++ b/tests/misc_testsuite/winch/_simd_store.wast @@ -1,3 +1,5 @@ +;;! simd = true + ;; v128.store operater with normal argument (e.g. (i8x16, i16x8, i32x4, f32x4)) (module diff --git a/tests/wast.rs b/tests/wast.rs index a016afff1f71..cfbd12a06899 100644 --- a/tests/wast.rs +++ b/tests/wast.rs @@ -104,65 +104,18 @@ fn run_wast(test: &WastTest, config: WastConfig) -> anyhow::Result<()> { // `crates/wast-util/src/lib.rs` file. let should_fail = test.should_fail(&config); - // Note that all of these proposals/features are currently default-off to - // ensure that we annotate all tests accurately with what features they - // need, even in the future when features are stabilized. - let memory64 = test_config.memory64.unwrap_or(false); - let custom_page_sizes = test_config.custom_page_sizes.unwrap_or(false); let multi_memory = test_config.multi_memory.unwrap_or(false); - let threads = test_config.threads.unwrap_or(false); - let gc = test_config.gc.unwrap_or(false); - let tail_call = test_config.tail_call.unwrap_or(false); - let extended_const = test_config.extended_const.unwrap_or(false); - let wide_arithmetic = test_config.wide_arithmetic.unwrap_or(false); let test_hogs_memory = test_config.hogs_memory.unwrap_or(false); - let component_model_more_flags = test_config.component_model_more_flags.unwrap_or(false); - let nan_canonicalization = test_config.nan_canonicalization.unwrap_or(false); let relaxed_simd = test_config.relaxed_simd.unwrap_or(false); - // Some proposals in wasm depend on previous proposals. For example the gc - // proposal depends on function-references which depends on reference-types. - // To avoid needing to enable all of them at once implicitly enable - // downstream proposals once the end proposal is enabled (e.g. when enabling - // gc that also enables function-references and reference-types). - let function_references = test_config - .function_references - .or(test_config.gc) - .unwrap_or(false); - let reference_types = test_config - .reference_types - .or(test_config.function_references) - .or(test_config.gc) - .unwrap_or(false); - let is_cranelift = match config.compiler { Compiler::Cranelift => true, _ => false, }; let mut cfg = Config::new(); - cfg.wasm_multi_memory(multi_memory) - .wasm_threads(threads) - .wasm_memory64(memory64) - .wasm_function_references(function_references) - .wasm_gc(gc) - .wasm_reference_types(reference_types) - .wasm_relaxed_simd(relaxed_simd) - .wasm_tail_call(tail_call) - .wasm_custom_page_sizes(custom_page_sizes) - .wasm_extended_const(extended_const) - .wasm_wide_arithmetic(wide_arithmetic) - .wasm_component_model_more_flags(component_model_more_flags) - .strategy(match config.compiler { - Compiler::Cranelift => wasmtime::Strategy::Cranelift, - Compiler::Winch => wasmtime::Strategy::Winch, - }) - .collector(match config.collector { - Collector::Auto => wasmtime::Collector::Auto, - Collector::Null => wasmtime::Collector::Null, - Collector::DeferredReferenceCounting => wasmtime::Collector::DeferredReferenceCounting, - }) - .cranelift_nan_canonicalization(nan_canonicalization); + component_test_util::apply_test_config(&mut cfg, &test_config); + component_test_util::apply_wast_config(&mut cfg, &config); if is_cranelift { cfg.cranelift_debug_verifier(true);