Skip to content

Commit eb0db5b

Browse files
committed
fuzz: improve Options control over generated functions
Previously, the ranges of the knobs for generating components of a functions were hard-coded in `Func::arbitrary_with_options`. This change extracts some of them to `Options` to (a) allow for more control from outside and (b) to explain what these parameters are doing. The one functional change here is that `num_clobbers_per_inst = 0..=10` is used both times clobbers are created (callsite-ish arm and clobbers arm); previously the clobbers arm only clobbered `0..=5` registers. It seemed possible that this was just an oversight (?).
1 parent 96f0b9d commit eb0db5b

File tree

4 files changed

+23
-9
lines changed

4 files changed

+23
-9
lines changed

fuzz/fuzz_targets/fastalloc_checker.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ impl Arbitrary<'_> for TestCase {
2626
clobbers: true,
2727
reftypes: false,
2828
callsite_ish_constraints: true,
29+
..Options::default()
2930
},
3031
)?,
3132
})
@@ -37,8 +38,8 @@ fuzz_target!(|testcase: TestCase| {
3738
let _ = env_logger::try_init();
3839
log::trace!("func:\n{:?}", func);
3940
let env = regalloc2::fuzzing::func::machine_env();
40-
let out =
41-
regalloc2::fuzzing::fastalloc::run(&func, &env, true, false).expect("regalloc did not succeed");
41+
let out = regalloc2::fuzzing::fastalloc::run(&func, &env, true, false)
42+
.expect("regalloc did not succeed");
4243

4344
let mut checker = Checker::new(&func, &env);
4445
checker.prepare(&out);

fuzz/fuzz_targets/ion_checker.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ impl Arbitrary<'_> for TestCase {
2626
clobbers: true,
2727
reftypes: true,
2828
callsite_ish_constraints: true,
29+
..Options::default()
2930
},
3031
)?,
3132
})

fuzz/fuzz_targets/ssagen.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ impl Arbitrary<'_> for TestCase {
2727
clobbers: true,
2828
reftypes: true,
2929
callsite_ish_constraints: true,
30+
..Options::default()
3031
},
3132
)?,
3233
})

src/fuzzing/func.rs

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use crate::{
1010

1111
use alloc::vec::Vec;
1212
use alloc::{format, vec};
13+
use core::ops::RangeInclusive;
1314

1415
use super::arbitrary::Result as ArbitraryResult;
1516
use super::arbitrary::{Arbitrary, Unstructured};
@@ -257,14 +258,19 @@ fn choose_dominating_block(
257258
Ok(block)
258259
}
259260

260-
#[derive(Clone, Copy, Debug)]
261+
#[derive(Clone, Debug)]
261262
pub struct Options {
262263
pub reused_inputs: bool,
263264
pub fixed_regs: bool,
264265
pub fixed_nonallocatable: bool,
265266
pub clobbers: bool,
266267
pub reftypes: bool,
267268
pub callsite_ish_constraints: bool,
269+
pub num_blocks: RangeInclusive<usize>,
270+
pub num_vregs_per_block: RangeInclusive<usize>,
271+
pub num_uses_per_inst: RangeInclusive<usize>,
272+
pub num_callsite_ish_vregs_per_inst: RangeInclusive<usize>,
273+
pub num_clobbers_per_inst: RangeInclusive<usize>,
268274
}
269275

270276
impl core::default::Default for Options {
@@ -276,6 +282,11 @@ impl core::default::Default for Options {
276282
clobbers: false,
277283
reftypes: false,
278284
callsite_ish_constraints: false,
285+
num_blocks: 1..=100,
286+
num_vregs_per_block: 5..=15,
287+
num_uses_per_inst: 0..=10,
288+
num_callsite_ish_vregs_per_inst: 0..=20,
289+
num_clobbers_per_inst: 0..=10,
279290
}
280291
}
281292
}
@@ -298,7 +309,7 @@ impl Func {
298309
// or one defined in a dominating block.
299310

300311
let mut builder = FuncBuilder::new();
301-
for _ in 0..u.int_in_range(1..=100)? {
312+
for _ in 0..u.int_in_range(opts.num_blocks.clone())? {
302313
builder.add_block();
303314
}
304315
let num_blocks = builder.f.blocks.len();
@@ -357,7 +368,7 @@ impl Func {
357368
let mut block_params = vec![vec![]; num_blocks];
358369
for block in 0..num_blocks {
359370
let mut vregs = vec![];
360-
for _ in 0..u.int_in_range(5..=15)? {
371+
for _ in 0..u.int_in_range(opts.num_vregs_per_block.clone())? {
361372
let vreg = alloc_vreg(&mut builder, u)?;
362373
vregs.push(vreg);
363374
if opts.reftypes && bool::arbitrary(u)? {
@@ -415,7 +426,7 @@ impl Func {
415426
def_pos,
416427
)];
417428
let mut allocations = vec![Allocation::none()];
418-
for _ in 0..u.int_in_range(0..=10)? {
429+
for _ in 0..u.int_in_range(opts.num_uses_per_inst.clone())? {
419430
let vreg = if avail.len() > 0
420431
&& (remaining_nonlocal_uses == 0 || bool::arbitrary(u)?)
421432
{
@@ -507,7 +518,7 @@ impl Func {
507518
if opts.callsite_ish_constraints && bool::arbitrary(u)? {
508519
// Define some new vregs with `any`
509520
// constraints.
510-
for _ in 0..u.int_in_range(0..=20)? {
521+
for _ in 0..u.int_in_range(opts.num_callsite_ish_vregs_per_inst.clone())? {
511522
let vreg = alloc_vreg(&mut builder, u)?;
512523
operands.push(Operand::new(
513524
vreg,
@@ -524,7 +535,7 @@ impl Func {
524535
// than the number of registers in any single
525536
// class, so the resulting problem is always
526537
// allocatable.
527-
for _ in 0..u.int_in_range(0..=10)? {
538+
for _ in 0..u.int_in_range(opts.num_clobbers_per_inst.clone())? {
528539
let reg = u.int_in_range(0..=30)?;
529540
let preg = PReg::new(reg, RegClass::arbitrary(u)?);
530541
if operands
@@ -542,7 +553,7 @@ impl Func {
542553
}
543554
}
544555
} else if opts.clobbers && bool::arbitrary(u)? {
545-
for _ in 0..u.int_in_range(0..=5)? {
556+
for _ in 0..u.int_in_range(opts.num_clobbers_per_inst.clone())? {
546557
let reg = u.int_in_range(0..=30)?;
547558
if clobbers.iter().any(|r| r.hw_enc() == reg) {
548559
continue;

0 commit comments

Comments
 (0)