From 9814e8bfebcaa63e9fdbdb36f99223aa94e011ba Mon Sep 17 00:00:00 2001 From: Afonso Bordado Date: Mon, 7 Nov 2022 17:08:26 +0000 Subject: [PATCH] fuzzgen: Add a few more ops (#5201) Adds `bitselect`,`select` and `select_spectre_guard` --- cranelift/fuzzgen/src/function_generator.rs | 104 ++++++++++++++++++++ cranelift/interpreter/src/step.rs | 5 +- 2 files changed, 107 insertions(+), 2 deletions(-) diff --git a/cranelift/fuzzgen/src/function_generator.rs b/cranelift/fuzzgen/src/function_generator.rs index 103c5d78f9..4bd1522ade 100644 --- a/cranelift/fuzzgen/src/function_generator.rs +++ b/cranelift/fuzzgen/src/function_generator.rs @@ -73,6 +73,33 @@ fn insert_opcode( Ok(()) } +// `select_spectre_guard` is only implemented when preceded by a `icmp` +// This ensures that we always insert it that way. +fn insert_select_spectre_guard( + fgen: &mut FunctionGenerator, + builder: &mut FunctionBuilder, + _opcode: Opcode, + args: &'static [Type], + rets: &'static [Type], +) -> Result<()> { + let icmp_ty = args[0]; + let icmp_lhs = builder.use_var(fgen.get_variable_of_type(icmp_ty)?); + let icmp_rhs = builder.use_var(fgen.get_variable_of_type(icmp_ty)?); + let cc = *fgen.u.choose(IntCC::all())?; + let icmp_res = builder.ins().icmp(cc, icmp_lhs, icmp_rhs); + + let select_lhs = builder.use_var(fgen.get_variable_of_type(args[1])?); + let select_rhs = builder.use_var(fgen.get_variable_of_type(args[2])?); + let select_res = builder + .ins() + .select_spectre_guard(icmp_res, select_lhs, select_rhs); + + let var = fgen.get_variable_of_type(rets[0])?; + builder.def_var(var, select_res); + + Ok(()) +} + fn insert_call( fgen: &mut FunctionGenerator, builder: &mut FunctionBuilder, @@ -232,6 +259,7 @@ type OpcodeInserter = fn( ) -> Result<()>; // TODO: Derive this from the `cranelift-meta` generator. +#[rustfmt::skip] const OPCODE_SIGNATURES: &'static [( Opcode, &'static [Type], // Args @@ -676,6 +704,82 @@ const OPCODE_SIGNATURES: &'static [( (Opcode::Bswap, &[I32], &[I32], insert_opcode), (Opcode::Bswap, &[I64], &[I64], insert_opcode), (Opcode::Bswap, &[I128], &[I128], insert_opcode), + // Bitselect + // TODO: Some ops disabled: + // x64: https://github.com/bytecodealliance/wasmtime/issues/5197 + // AArch64: https://github.com/bytecodealliance/wasmtime/issues/5198 + #[cfg(not(target_arch = "x86_64"))] + (Opcode::Bitselect, &[I8, I8, I8], &[I8], insert_opcode), + #[cfg(not(target_arch = "x86_64"))] + (Opcode::Bitselect, &[I16, I16, I16], &[I16], insert_opcode), + #[cfg(not(target_arch = "x86_64"))] + (Opcode::Bitselect, &[I32, I32, I32], &[I32], insert_opcode), + #[cfg(not(target_arch = "x86_64"))] + (Opcode::Bitselect, &[I64, I64, I64], &[I64], insert_opcode), + #[cfg(not(any(target_arch = "x86_64", target_arch = "aarch64")))] + (Opcode::Bitselect, &[I128, I128, I128], &[I128], insert_opcode), + // Select + // TODO: Some ops disabled: + // x64: https://github.com/bytecodealliance/wasmtime/issues/5199 + // AArch64: https://github.com/bytecodealliance/wasmtime/issues/5200 + (Opcode::Select, &[I8, I8, I8], &[I8], insert_opcode), + (Opcode::Select, &[I8, I16, I16], &[I16], insert_opcode), + (Opcode::Select, &[I8, I32, I32], &[I32], insert_opcode), + (Opcode::Select, &[I8, I64, I64], &[I64], insert_opcode), + (Opcode::Select, &[I8, I128, I128], &[I128], insert_opcode), + (Opcode::Select, &[I16, I8, I8], &[I8], insert_opcode), + (Opcode::Select, &[I16, I16, I16], &[I16], insert_opcode), + (Opcode::Select, &[I16, I32, I32], &[I32], insert_opcode), + (Opcode::Select, &[I16, I64, I64], &[I64], insert_opcode), + (Opcode::Select, &[I16, I128, I128], &[I128], insert_opcode), + (Opcode::Select, &[I32, I8, I8], &[I8], insert_opcode), + (Opcode::Select, &[I32, I16, I16], &[I16], insert_opcode), + (Opcode::Select, &[I32, I32, I32], &[I32], insert_opcode), + (Opcode::Select, &[I32, I64, I64], &[I64], insert_opcode), + (Opcode::Select, &[I32, I128, I128], &[I128], insert_opcode), + (Opcode::Select, &[I64, I8, I8], &[I8], insert_opcode), + (Opcode::Select, &[I64, I16, I16], &[I16], insert_opcode), + (Opcode::Select, &[I64, I32, I32], &[I32], insert_opcode), + (Opcode::Select, &[I64, I64, I64], &[I64], insert_opcode), + (Opcode::Select, &[I64, I128, I128], &[I128], insert_opcode), + #[cfg(not(any(target_arch = "x86_64", target_arch = "aarch64")))] + (Opcode::Select, &[I128, I8, I8], &[I8], insert_opcode), + #[cfg(not(any(target_arch = "x86_64", target_arch = "aarch64")))] + (Opcode::Select, &[I128, I16, I16], &[I16], insert_opcode), + #[cfg(not(any(target_arch = "x86_64", target_arch = "aarch64")))] + (Opcode::Select, &[I128, I32, I32], &[I32], insert_opcode), + #[cfg(not(any(target_arch = "x86_64", target_arch = "aarch64")))] + (Opcode::Select, &[I128, I64, I64], &[I64], insert_opcode), + #[cfg(not(any(target_arch = "x86_64", target_arch = "aarch64")))] + (Opcode::Select, &[I128, I128, I128], &[I128], insert_opcode), + // SelectSpectreGuard + // select_spectre_guard is only implemented on x86_64 and aarch64 + // when a icmp is preceding it. + (Opcode::SelectSpectreGuard, &[I8, I8, I8], &[I8], insert_select_spectre_guard), + (Opcode::SelectSpectreGuard, &[I8, I16, I16], &[I16], insert_select_spectre_guard), + (Opcode::SelectSpectreGuard, &[I8, I32, I32], &[I32], insert_select_spectre_guard), + (Opcode::SelectSpectreGuard, &[I8, I64, I64], &[I64], insert_select_spectre_guard), + (Opcode::SelectSpectreGuard, &[I8, I128, I128], &[I128], insert_select_spectre_guard), + (Opcode::SelectSpectreGuard, &[I16, I8, I8], &[I8], insert_select_spectre_guard), + (Opcode::SelectSpectreGuard, &[I16, I16, I16], &[I16], insert_select_spectre_guard), + (Opcode::SelectSpectreGuard, &[I16, I32, I32], &[I32], insert_select_spectre_guard), + (Opcode::SelectSpectreGuard, &[I16, I64, I64], &[I64], insert_select_spectre_guard), + (Opcode::SelectSpectreGuard, &[I16, I128, I128], &[I128], insert_select_spectre_guard), + (Opcode::SelectSpectreGuard, &[I32, I8, I8], &[I8], insert_select_spectre_guard), + (Opcode::SelectSpectreGuard, &[I32, I16, I16], &[I16], insert_select_spectre_guard), + (Opcode::SelectSpectreGuard, &[I32, I32, I32], &[I32], insert_select_spectre_guard), + (Opcode::SelectSpectreGuard, &[I32, I64, I64], &[I64], insert_select_spectre_guard), + (Opcode::SelectSpectreGuard, &[I32, I128, I128], &[I128], insert_select_spectre_guard), + (Opcode::SelectSpectreGuard, &[I64, I8, I8], &[I8], insert_select_spectre_guard), + (Opcode::SelectSpectreGuard, &[I64, I16, I16], &[I16], insert_select_spectre_guard), + (Opcode::SelectSpectreGuard, &[I64, I32, I32], &[I32], insert_select_spectre_guard), + (Opcode::SelectSpectreGuard, &[I64, I64, I64], &[I64], insert_select_spectre_guard), + (Opcode::SelectSpectreGuard, &[I64, I128, I128], &[I128], insert_select_spectre_guard), + (Opcode::SelectSpectreGuard, &[I128, I8, I8], &[I8], insert_select_spectre_guard), + (Opcode::SelectSpectreGuard, &[I128, I16, I16], &[I16], insert_select_spectre_guard), + (Opcode::SelectSpectreGuard, &[I128, I32, I32], &[I32], insert_select_spectre_guard), + (Opcode::SelectSpectreGuard, &[I128, I64, I64], &[I64], insert_select_spectre_guard), + (Opcode::SelectSpectreGuard, &[I128, I128, I128], &[I128], insert_select_spectre_guard), // Fadd (Opcode::Fadd, &[F32, F32], &[F32], insert_opcode), (Opcode::Fadd, &[F64, F64], &[F64], insert_opcode), diff --git a/cranelift/interpreter/src/step.rs b/cranelift/interpreter/src/step.rs index 9173fe0418..c158f699e8 100644 --- a/cranelift/interpreter/src/step.rs +++ b/cranelift/interpreter/src/step.rs @@ -544,8 +544,9 @@ where Opcode::Vconst => assign(imm()), Opcode::Null => unimplemented!("Null"), Opcode::Nop => ControlFlow::Continue, - Opcode::Select => choose(arg(0)?.into_bool()?, arg(1)?, arg(2)?), - Opcode::SelectSpectreGuard => unimplemented!("SelectSpectreGuard"), + Opcode::Select | Opcode::SelectSpectreGuard => { + choose(arg(0)?.into_bool()?, arg(1)?, arg(2)?) + } Opcode::Bitselect => { let mask_a = Value::and(arg(0)?, arg(1)?)?; let mask_b = Value::and(Value::not(arg(0)?)?, arg(2)?)?;