From 27fe50ce9ec639ecd1d8698972f368494656fc5b Mon Sep 17 00:00:00 2001 From: Nick Lewycky Date: Wed, 4 Dec 2019 10:38:28 -0800 Subject: [PATCH 1/2] Fix this regression test to detect the bug it was looking for in release builds too. This bug triggered an assertion failure in debug, and by examining the pre-opt IR, we can check for the bug in release mode too. --- lib/llvm-backend-tests/tests/compile.rs | 62 +++++++++++++++++++------ 1 file changed, 47 insertions(+), 15 deletions(-) diff --git a/lib/llvm-backend-tests/tests/compile.rs b/lib/llvm-backend-tests/tests/compile.rs index 17071a44a04..dc539bf2067 100644 --- a/lib/llvm-backend-tests/tests/compile.rs +++ b/lib/llvm-backend-tests/tests/compile.rs @@ -1,40 +1,72 @@ +use wasmer_llvm_backend::{InkwellMemoryBuffer, InkwellModule, LLVMBackendConfig, LLVMCallbacks}; use wasmer_llvm_backend_tests::{get_compiler, wat2wasm}; -use wasmer_runtime::imports; -use wasmer_runtime_core::compile_with; +use wasmer_runtime::{imports, CompilerConfig}; +use wasmer_runtime_core::{backend::BackendCompilerConfig, compile_with, compile_with_config}; + +use std::cell::RefCell; +use std::rc::Rc; #[test] fn crash_return_with_float_on_stack() { const MODULE: &str = r#" (module - (type (;0;) (func)) - (type (;1;) (func (param f64) (result f64))) + (type (func)) + (type (func (param f64) (result f64))) (func $_start (type 0)) (func $fmod (type 1) (param f64) (result f64) local.get 0 - f64.const 0x0p+0 (;=0;) + f64.const 0x0p+0 f64.mul - return) -) + return)) "#; let wasm_binary = wat2wasm(MODULE.as_bytes()).expect("WAST not valid or malformed"); let module = compile_with(&wasm_binary, &get_compiler()).unwrap(); module.instantiate(&imports! {}).unwrap(); } +#[derive(Debug, Default)] +pub struct RecordPreOptIR { + preopt_ir: String, +} + +impl LLVMCallbacks for RecordPreOptIR { + fn preopt_ir_callback(&mut self, module: &InkwellModule) { + self.preopt_ir = module.print_to_string().to_string(); + } + + fn postopt_ir_callback(&mut self, _: &InkwellModule) {} + + fn obj_memory_buffer_callback(&mut self, _: &InkwellMemoryBuffer) {} +} + #[test] fn crash_select_with_mismatched_pending() { - const MODULE: &str = r#" + const WAT: &str = r#" (module - (func (param f64) - f64.const 0x0p+0 (;=0;) + (func (param f64) (result f64) + f64.const 0x0p+0 local.get 0 f64.add - f64.const 0x0p+0 (;=0;) + f64.const 0x0p+0 i32.const 0 - select - drop)) + select)) "#; - let wasm_binary = wat2wasm(MODULE.as_bytes()).expect("WAST not valid or malformed"); - let module = compile_with(&wasm_binary, &get_compiler()).unwrap(); + let record_pre_opt_ir = Rc::new(RefCell::new(RecordPreOptIR::default())); + let compiler_config = CompilerConfig { + backend_specific_config: Some(BackendCompilerConfig(Box::new(LLVMBackendConfig { + callbacks: Some(record_pre_opt_ir.clone()), + }))), + ..Default::default() + }; + let wasm_binary = wat2wasm(WAT.as_bytes()).expect("WAST not valid or malformed"); + let module = compile_with_config(&wasm_binary, &get_compiler(), compiler_config).unwrap(); module.instantiate(&imports! {}).unwrap(); + const LLVM: &str = r#" + %s3 = fadd double 0.000000e+00, %s2 + %nan = fcmp uno double %s3, 0.000000e+00 + %2 = select i1 %nan, double 0x7FF8000000000000, double %s3 + %s5 = select i1 false, double %2, double 0.000000e+00 + br label %return +"#; + assert!(&record_pre_opt_ir.borrow().preopt_ir.contains(LLVM)); } From a221f1e5707fce40c08b09632341832483781e3a Mon Sep 17 00:00:00 2001 From: Nick Lewycky Date: Fri, 6 Dec 2019 12:09:34 -0800 Subject: [PATCH 2/2] Provide a default empty implementation for the LLVMCallbacks trait. --- lib/llvm-backend-tests/tests/compile.rs | 4 ---- lib/llvm-backend/src/lib.rs | 6 +++--- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/lib/llvm-backend-tests/tests/compile.rs b/lib/llvm-backend-tests/tests/compile.rs index dc539bf2067..1e32f6dd08d 100644 --- a/lib/llvm-backend-tests/tests/compile.rs +++ b/lib/llvm-backend-tests/tests/compile.rs @@ -33,10 +33,6 @@ impl LLVMCallbacks for RecordPreOptIR { fn preopt_ir_callback(&mut self, module: &InkwellModule) { self.preopt_ir = module.print_to_string().to_string(); } - - fn postopt_ir_callback(&mut self, _: &InkwellModule) {} - - fn obj_memory_buffer_callback(&mut self, _: &InkwellMemoryBuffer) {} } #[test] diff --git a/lib/llvm-backend/src/lib.rs b/lib/llvm-backend/src/lib.rs index 853cfac1195..a2db088a76a 100644 --- a/lib/llvm-backend/src/lib.rs +++ b/lib/llvm-backend/src/lib.rs @@ -37,9 +37,9 @@ pub type InkwellModule<'ctx> = inkwell::module::Module<'ctx>; pub type InkwellMemoryBuffer = inkwell::memory_buffer::MemoryBuffer; pub trait LLVMCallbacks: std::any::Any + 'static { - fn preopt_ir_callback(&mut self, module: &InkwellModule); - fn postopt_ir_callback(&mut self, module: &InkwellModule); - fn obj_memory_buffer_callback(&mut self, memory_buffer: &InkwellMemoryBuffer); + fn preopt_ir_callback(&mut self, _module: &InkwellModule) {} + fn postopt_ir_callback(&mut self, _module: &InkwellModule) {} + fn obj_memory_buffer_callback(&mut self, _memory_buffer: &InkwellMemoryBuffer) {} } pub struct LLVMBackendConfig {