Skip to content

Commit

Permalink
fuzzgen: Add a few more ops (#5201)
Browse files Browse the repository at this point in the history
Adds `bitselect`,`select` and `select_spectre_guard`
  • Loading branch information
afonso360 authored Nov 7, 2022
1 parent 508dd81 commit 9814e8b
Show file tree
Hide file tree
Showing 2 changed files with 107 additions and 2 deletions.
104 changes: 104 additions & 0 deletions cranelift/fuzzgen/src/function_generator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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),
Expand Down
5 changes: 3 additions & 2 deletions cranelift/interpreter/src/step.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)?)?;
Expand Down

0 comments on commit 9814e8b

Please sign in to comment.