Coverage Report

Created: 2026-06-07 07:42

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/regalloc2/src/fuzzing/fastalloc.rs
Line
Count
Source
1
//! Fuzz the `fastalloc` register allocator.
2
3
use crate::{checker, fastalloc, fuzzing::func};
4
use arbitrary::{Arbitrary, Result, Unstructured};
5
6
/// `fastalloc`-specific options for generating functions.
7
const OPTIONS: func::Options = func::Options {
8
    reused_inputs: true,
9
    fixed_regs: true,
10
    fixed_nonallocatable: true,
11
    clobbers: true,
12
    reftypes: false,
13
    callsite_ish_constraints: true,
14
    ..func::Options::DEFAULT
15
};
16
17
/// A convenience wrapper to generate a [`func::Func`] with `fastalloc`-specific
18
/// options enabled.
19
#[derive(Clone, Debug)]
20
pub struct TestCase {
21
    func: func::Func,
22
    annotate: bool,
23
    check_ssa: bool,
24
}
25
26
impl Arbitrary<'_> for TestCase {
27
0
    fn arbitrary(u: &mut Unstructured) -> Result<TestCase> {
28
0
        let func = func::Func::arbitrary_with_options(u, &OPTIONS)?;
29
0
        let annotate = bool::arbitrary(u)?;
30
0
        let check_ssa = bool::arbitrary(u)?;
31
0
        Ok(TestCase {
32
0
            func,
33
0
            annotate,
34
0
            check_ssa,
35
0
        })
36
0
    }
37
}
38
39
/// Test a single function with the `fastalloc` allocator.
40
///
41
/// This also:
42
/// - optionally creates annotations
43
/// - optionally verifies the incoming SSA
44
/// - runs the [`checker`].
45
0
pub fn check(t: TestCase) {
46
    let TestCase {
47
0
        func,
48
0
        annotate,
49
0
        check_ssa,
50
0
    } = &t;
51
0
    log::trace!("func:\n{func:?}");
52
53
0
    let env = func::machine_env();
54
0
    let out = fastalloc::run(func, &env, *annotate, *check_ssa).expect("regalloc did not succeed");
55
56
0
    let mut checker = checker::Checker::new(func, &env);
57
0
    checker.prepare(&out);
58
0
    checker.run().expect("checker failed");
59
0
}
60
61
#[test]
62
fn smoke() {
63
    arbtest::arbtest(|u| {
64
        let test_case = TestCase::arbitrary(u)?;
65
        check(test_case);
66
        Ok(())
67
    })
68
    .budget_ms(1_000);
69
}