(&mut self, func: Function, isa: &dyn TargetIsa)
| 100 | } |
| 101 | |
| 102 | fn run_func_passes(&mut self, func: Function, isa: &dyn TargetIsa) -> Result<Function> { |
| 103 | // Do a NaN Canonicalization pass on the generated function. |
| 104 | // |
| 105 | // Both IEEE754 and the Wasm spec are somewhat loose about what is allowed |
| 106 | // to be returned from NaN producing operations. And in practice this changes |
| 107 | // from X86 to Aarch64 and others. Even in the same host machine, the |
| 108 | // interpreter may produce a code sequence different from cranelift that |
| 109 | // generates different NaN's but produces legal results according to the spec. |
| 110 | // |
| 111 | // These differences cause spurious failures in the fuzzer. To fix this |
| 112 | // we enable the NaN Canonicalization pass that replaces any NaN's produced |
| 113 | // with a single fixed canonical NaN value. |
| 114 | // |
| 115 | // This is something that we can enable via flags for the compiled version, however |
| 116 | // the interpreter won't get that version, so call that pass manually here. |
| 117 | |
| 118 | let mut ctx = Context::for_function(func); |
| 119 | |
| 120 | // We disable the verifier here, since if it fails it prevents a test case from |
| 121 | // being generated and formatted by `cargo fuzz fmt`. |
| 122 | // We run the verifier before compiling the code, so it always gets verified. |
| 123 | let flags = settings::Flags::new({ |
| 124 | let mut builder = settings::builder(); |
| 125 | builder.set("enable_verifier", "false").unwrap(); |
| 126 | builder |
| 127 | }); |
| 128 | |
| 129 | // Create a new TargetISA from the given ISA, this ensures that we copy all ISA |
| 130 | // flags, which may have an effect on the code generated by the passes below. |
| 131 | let isa = Builder::from_target_isa(isa) |
| 132 | .finish(flags) |
| 133 | .expect("Failed to build TargetISA"); |
| 134 | |
| 135 | // Finally run the NaN canonicalization pass |
| 136 | ctx.canonicalize_nans(isa.as_ref()) |
| 137 | .expect("Failed NaN canonicalization pass"); |
| 138 | |
| 139 | // Run the int_divz pass |
| 140 | // |
| 141 | // This pass replaces divs and rems with sequences that do not trap |
| 142 | passes::do_int_divz_pass(self, &mut ctx.func)?; |
| 143 | |
| 144 | // This pass replaces fcvt* instructions with sequences that do not trap |
| 145 | passes::do_fcvt_trap_pass(self, &mut ctx.func)?; |
| 146 | |
| 147 | Ok(ctx.func) |
| 148 | } |
| 149 | |
| 150 | pub fn generate_func( |
| 151 | &mut self, |
no test coverage detected