fuzzgen: Add i128 support (#4529)

This commit is contained in:
Afonso Bordado
2022-07-26 17:40:12 +01:00
committed by GitHub
parent d041c4b376
commit 1183191d7d
3 changed files with 32 additions and 13 deletions

View File

@@ -116,26 +116,31 @@ const OPCODE_SIGNATURES: &'static [(
(Opcode::Iadd, &[I16, I16], &[I16], insert_opcode), (Opcode::Iadd, &[I16, I16], &[I16], insert_opcode),
(Opcode::Iadd, &[I32, I32], &[I32], insert_opcode), (Opcode::Iadd, &[I32, I32], &[I32], insert_opcode),
(Opcode::Iadd, &[I64, I64], &[I64], insert_opcode), (Opcode::Iadd, &[I64, I64], &[I64], insert_opcode),
(Opcode::Iadd, &[I128, I128], &[I128], insert_opcode),
// Isub // Isub
(Opcode::Isub, &[I8, I8], &[I8], insert_opcode), (Opcode::Isub, &[I8, I8], &[I8], insert_opcode),
(Opcode::Isub, &[I16, I16], &[I16], insert_opcode), (Opcode::Isub, &[I16, I16], &[I16], insert_opcode),
(Opcode::Isub, &[I32, I32], &[I32], insert_opcode), (Opcode::Isub, &[I32, I32], &[I32], insert_opcode),
(Opcode::Isub, &[I64, I64], &[I64], insert_opcode), (Opcode::Isub, &[I64, I64], &[I64], insert_opcode),
(Opcode::Isub, &[I128, I128], &[I128], insert_opcode),
// Imul // Imul
(Opcode::Imul, &[I8, I8], &[I8], insert_opcode), (Opcode::Imul, &[I8, I8], &[I8], insert_opcode),
(Opcode::Imul, &[I16, I16], &[I16], insert_opcode), (Opcode::Imul, &[I16, I16], &[I16], insert_opcode),
(Opcode::Imul, &[I32, I32], &[I32], insert_opcode), (Opcode::Imul, &[I32, I32], &[I32], insert_opcode),
(Opcode::Imul, &[I64, I64], &[I64], insert_opcode), (Opcode::Imul, &[I64, I64], &[I64], insert_opcode),
(Opcode::Imul, &[I128, I128], &[I128], insert_opcode),
// Udiv // Udiv
(Opcode::Udiv, &[I8, I8], &[I8], insert_opcode), (Opcode::Udiv, &[I8, I8], &[I8], insert_opcode),
(Opcode::Udiv, &[I16, I16], &[I16], insert_opcode), (Opcode::Udiv, &[I16, I16], &[I16], insert_opcode),
(Opcode::Udiv, &[I32, I32], &[I32], insert_opcode), (Opcode::Udiv, &[I32, I32], &[I32], insert_opcode),
(Opcode::Udiv, &[I64, I64], &[I64], insert_opcode), (Opcode::Udiv, &[I64, I64], &[I64], insert_opcode),
(Opcode::Udiv, &[I128, I128], &[I128], insert_opcode),
// Sdiv // Sdiv
(Opcode::Sdiv, &[I8, I8], &[I8], insert_opcode), (Opcode::Sdiv, &[I8, I8], &[I8], insert_opcode),
(Opcode::Sdiv, &[I16, I16], &[I16], insert_opcode), (Opcode::Sdiv, &[I16, I16], &[I16], insert_opcode),
(Opcode::Sdiv, &[I32, I32], &[I32], insert_opcode), (Opcode::Sdiv, &[I32, I32], &[I32], insert_opcode),
(Opcode::Sdiv, &[I64, I64], &[I64], insert_opcode), (Opcode::Sdiv, &[I64, I64], &[I64], insert_opcode),
(Opcode::Sdiv, &[I128, I128], &[I128], insert_opcode),
// Fadd // Fadd
(Opcode::Fadd, &[F32, F32], &[F32], insert_opcode), (Opcode::Fadd, &[F32, F32], &[F32], insert_opcode),
(Opcode::Fadd, &[F64, F64], &[F64], insert_opcode), (Opcode::Fadd, &[F64, F64], &[F64], insert_opcode),
@@ -193,15 +198,18 @@ const OPCODE_SIGNATURES: &'static [(
(Opcode::StackStore, &[I16], &[], insert_stack_store), (Opcode::StackStore, &[I16], &[], insert_stack_store),
(Opcode::StackStore, &[I32], &[], insert_stack_store), (Opcode::StackStore, &[I32], &[], insert_stack_store),
(Opcode::StackStore, &[I64], &[], insert_stack_store), (Opcode::StackStore, &[I64], &[], insert_stack_store),
(Opcode::StackStore, &[I128], &[], insert_stack_store),
(Opcode::StackLoad, &[], &[I8], insert_stack_load), (Opcode::StackLoad, &[], &[I8], insert_stack_load),
(Opcode::StackLoad, &[], &[I16], insert_stack_load), (Opcode::StackLoad, &[], &[I16], insert_stack_load),
(Opcode::StackLoad, &[], &[I32], insert_stack_load), (Opcode::StackLoad, &[], &[I32], insert_stack_load),
(Opcode::StackLoad, &[], &[I64], insert_stack_load), (Opcode::StackLoad, &[], &[I64], insert_stack_load),
(Opcode::StackLoad, &[], &[I128], insert_stack_load),
// Integer Consts // Integer Consts
(Opcode::Iconst, &[], &[I8], insert_const), (Opcode::Iconst, &[], &[I8], insert_const),
(Opcode::Iconst, &[], &[I16], insert_const), (Opcode::Iconst, &[], &[I16], insert_const),
(Opcode::Iconst, &[], &[I32], insert_const), (Opcode::Iconst, &[], &[I32], insert_const),
(Opcode::Iconst, &[], &[I64], insert_const), (Opcode::Iconst, &[], &[I64], insert_const),
(Opcode::Iconst, &[], &[I128], insert_const),
// Float Consts // Float Consts
(Opcode::F32const, &[], &[F32], insert_const), (Opcode::F32const, &[], &[F32], insert_const),
(Opcode::F64const, &[], &[F64], insert_const), (Opcode::F64const, &[], &[F64], insert_const),
@@ -270,8 +278,7 @@ where
let scalars = [ let scalars = [
// IFLAGS, FFLAGS, // IFLAGS, FFLAGS,
B1, // B8, B16, B32, B64, B128, B1, // B8, B16, B32, B64, B128,
I8, I16, I32, I64, // I128, I8, I16, I32, I64, I128, F32, F64,
F32, F64,
// R32, R64, // R32, R64,
]; ];
// TODO: vector types // TODO: vector types
@@ -340,6 +347,12 @@ where
/// Generates an instruction(`iconst`/`fconst`/etc...) to introduce a constant value /// Generates an instruction(`iconst`/`fconst`/etc...) to introduce a constant value
fn generate_const(&mut self, builder: &mut FunctionBuilder, ty: Type) -> Result<Value> { fn generate_const(&mut self, builder: &mut FunctionBuilder, ty: Type) -> Result<Value> {
Ok(match ty { Ok(match ty {
I128 => {
// See: https://github.com/bytecodealliance/wasmtime/issues/2906
let hi = builder.ins().iconst(I64, self.u.arbitrary::<i64>()?);
let lo = builder.ins().iconst(I64, self.u.arbitrary::<i64>()?);
builder.ins().iconcat(lo, hi)
}
ty if ty.is_int() => { ty if ty.is_int() => {
let imm64 = match ty { let imm64 = match ty {
I8 => self.u.arbitrary::<i8>()? as i64, I8 => self.u.arbitrary::<i8>()? as i64,
@@ -435,10 +448,7 @@ where
fn generate_br(&mut self, builder: &mut FunctionBuilder) -> Result<()> { fn generate_br(&mut self, builder: &mut FunctionBuilder) -> Result<()> {
let (block, args) = self.generate_target_block(builder)?; let (block, args) = self.generate_target_block(builder)?;
let condbr_types = [ let condbr_types = [I8, I16, I32, I64, I128, B1];
I8, I16, I32, I64, // TODO: I128
B1,
];
let _type = *self.u.choose(&condbr_types[..])?; let _type = *self.u.choose(&condbr_types[..])?;
let var = self.get_variable_of_type(_type)?; let var = self.get_variable_of_type(_type)?;
let val = builder.use_var(var); let val = builder.use_var(var);
@@ -459,7 +469,9 @@ where
let cond = self.generate_intcc()?; let cond = self.generate_intcc()?;
let bricmp_types = [ let bricmp_types = [
I8, I16, I32, I64, // TODO: I128 I8, I16, I32,
I64,
// I128 - TODO: https://github.com/bytecodealliance/wasmtime/issues/4406
]; ];
let _type = *self.u.choose(&bricmp_types[..])?; let _type = *self.u.choose(&bricmp_types[..])?;
@@ -479,11 +491,7 @@ where
} }
fn generate_switch(&mut self, builder: &mut FunctionBuilder) -> Result<()> { fn generate_switch(&mut self, builder: &mut FunctionBuilder) -> Result<()> {
let _type = *self.u.choose( let _type = *self.u.choose(&[I8, I16, I32, I64, I128][..])?;
&[
I8, I16, I32, I64, // TODO: I128
][..],
)?;
let switch_var = self.get_variable_of_type(_type)?; let switch_var = self.get_variable_of_type(_type)?;
let switch_val = builder.use_var(switch_var); let switch_val = builder.use_var(switch_var);
@@ -579,6 +587,7 @@ where
/// Zero initializes the stack slot by inserting `stack_store`'s. /// Zero initializes the stack slot by inserting `stack_store`'s.
fn initialize_stack_slots(&mut self, builder: &mut FunctionBuilder) -> Result<()> { fn initialize_stack_slots(&mut self, builder: &mut FunctionBuilder) -> Result<()> {
let i128_zero = builder.ins().iconst(I128, 0);
let i64_zero = builder.ins().iconst(I64, 0); let i64_zero = builder.ins().iconst(I64, 0);
let i32_zero = builder.ins().iconst(I32, 0); let i32_zero = builder.ins().iconst(I32, 0);
let i16_zero = builder.ins().iconst(I16, 0); let i16_zero = builder.ins().iconst(I16, 0);
@@ -592,6 +601,7 @@ where
while size != 0 { while size != 0 {
let offset = (init_size - size) as i32; let offset = (init_size - size) as i32;
let (val, filled) = match size { let (val, filled) = match size {
sz if sz / 16 > 0 => (i128_zero, 16),
sz if sz / 8 > 0 => (i64_zero, 8), sz if sz / 8 > 0 => (i64_zero, 8),
sz if sz / 4 > 0 => (i32_zero, 4), sz if sz / 4 > 0 => (i32_zero, 4),
sz if sz / 2 > 0 => (i16_zero, 2), sz if sz / 2 > 0 => (i16_zero, 2),

View File

@@ -57,6 +57,7 @@ where
I16 => self.u.arbitrary::<i16>()? as i128, I16 => self.u.arbitrary::<i16>()? as i128,
I32 => self.u.arbitrary::<i32>()? as i128, I32 => self.u.arbitrary::<i32>()? as i128,
I64 => self.u.arbitrary::<i64>()? as i128, I64 => self.u.arbitrary::<i64>()? as i128,
I128 => self.u.arbitrary::<i128>()?,
_ => unreachable!(), _ => unreachable!(),
}; };
DataValue::from_integer(imm, ty)? DataValue::from_integer(imm, ty)?

View File

@@ -3,6 +3,8 @@
use libfuzzer_sys::fuzz_target; use libfuzzer_sys::fuzz_target;
use cranelift_codegen::data_value::DataValue; use cranelift_codegen::data_value::DataValue;
use cranelift_codegen::settings;
use cranelift_codegen::settings::Configurable;
use cranelift_filetests::function_runner::{CompiledFunction, SingleFunctionCompiler}; use cranelift_filetests::function_runner::{CompiledFunction, SingleFunctionCompiler};
use cranelift_fuzzgen::*; use cranelift_fuzzgen::*;
use cranelift_interpreter::environment::FuncIndex; use cranelift_interpreter::environment::FuncIndex;
@@ -60,7 +62,13 @@ fuzz_target!(|testcase: TestCase| {
}; };
// Native fn // Native fn
let mut host_compiler = SingleFunctionCompiler::with_default_host_isa().unwrap(); let flags = {
let mut builder = settings::builder();
// We need llvm ABI extensions for i128 values on x86
builder.set("enable_llvm_abi_extensions", "true").unwrap();
settings::Flags::new(builder)
};
let mut host_compiler = SingleFunctionCompiler::with_host_isa(flags).unwrap();
let compiled_fn = host_compiler.compile(testcase.func.clone()).unwrap(); let compiled_fn = host_compiler.compile(testcase.func.clone()).unwrap();
for args in &testcase.inputs { for args in &testcase.inputs {