A Rust Mid-level Intermediate Representation fuzzer
It can generate custom MIR programs containing:
- All primitive integer and floating point types,
bool
,char
, arrays, tuples, references, raw pointers, structs, and enums. - Functions containing multiple basic blocks
- Terminators:
Goto
,Return
,SwitchInt
(match
),Call
. - Intrinsic functions:
arith_offset
(for pointer arithmetics),transmute
,bswap
,fmaf64
. - Operators: all arithmetic, logical and bitwise operations on integers and floating points, and checked arithmetic (Add, Sub, Mul) on integers
- All primitive literal expressions, as well as tuple, array, and struct aggregate expressions
- Creating references and raw pointers, and dereferencing them
- Casts between integers, floating points,
char
, andbool
Generated programs are terminating, UB-free, and deterministic. A discrepancy between testing backends always indicate a bug in them (or a bug in Rustlantis).
- Rust nightly
- rustup
Install Miri and Cranelift with Rustup rustup component add miri rustc-codegen-cranelift-preview
, then copy config.toml.example
to config.toml
To generate and difftest one seed, run
./fuzz-one.sh <seed>
A program will be generated to $TMPDIR
and tested. If difftest passes (no bug), it will exit with 0. If difftest spots a difference between testing backends, it will exit with 1 and save the reproduction file to ./repros/
.
To generate a program only, run generate
Usage: generate [OPTIONS] <seed>
Arguments:
<seed> generation seed
Options:
-d, --debug generate a program where values are printed instead of hashed (slow)
--call-syntax <call-syntax> switch between different versions of Call syntaxes [default: v4] [possible values: v1, v2, v3, v4]
-h, --help Print help
-V, --version Print version
To difftest an existing program, run difftest
Usage: difftest <file>
Arguments:
<file>
Options:
-h, --help Print help
- Cranelift not supported on AArch64 macOS: https://github.com/bjorn3/rustc_codegen_cranelift/issues/1248
rustc_codegen_gcc
can be used as a backend, but it doesn't support enough language features yet to be usable
The Space Shuttle Atlantis docked with Mir space station seven times: https://en.wikipedia.org/wiki/Shuttle%E2%80%93Mir_program
🦀: Root cause in Rust 🐉: Root cause in LLVM 🏗️: Root cause in Cranelift
- 🦀
RenameReturnPlace
is broken: rust-lang/rust#110902 - 🦀
ReferencePropagation
prevents partial initialisation: rust-lang/rust#111426 - 🐉 phi nodes assumed to be non-empty: llvm/llvm-project#63013
- 🐉 Assertion failure in
RegisterCoalescer
: llvm/llvm-project#63033 - 🦀 MIR inlining inserts statements at the wrong place: rust-lang/rust#117355
- 🏗️ Overflowing shift triggers panic in Cranelift: rust-lang/rustc_codegen_cranelift#1455 & bytecodealliance/wasmtime#7865
- 🦀
ConstProp
propagates over mutating borrows: rust-lang/rust#110947 - 🦀
*const T
in function parameters annotated withreadonly
: rust-lang/rust#111502 - 🐉 Aliasing analysis merges loads from different offsets: rust-lang/rust#112061 & llvm/llvm-project#63019
- 🐉 Constant folding produces invalid boolean values: rust-lang/rust#112170 & llvm/llvm-project#63055
- 🐉 Aliasing analysis broken for overflowing pointer offsets: rust-lang/rust#112526 & llvm/llvm-project#63266
- rust-lang/rust#112548
- 🐉 Copy elision corrupts stack arguments with two parts: rust-lang/rust#112767 & llvm/llvm-project#63430
- 🐉 Copy elision reads stack arguments from the wrong offsets: llvm/llvm-project#63475
- 🦀 Subnormal f64 to f32 cast is wrong: rust-lang/rust#113407
- 🐉 AST size merging is wrong: llvm/llvm-project#64897
- 🦀
ConstProp
propagates over assignment of unknown values: rust-lang/rust#118328 - 🐉 Bad
undef
/poison
handling inInstCombine
: llvm/llvm-project#74890 - 🦀
GVN
merges moved function arguments: rust-lang/rust#120613 - 🐉
GVNPass
forgets to remove poison generating flags: llvm/llvm-project#82884 - 🏗️ Misoptimization of imul + ireduce: rust-lang/rustc_codegen_cranelift#1460 & bytecodealliance/wasmtime#7999
- 🐉
InstCombine
calculates wronginsertelement
instructions: rust-lang/rust#121996 & llvm/llvm-project#84025
- 🦀 Const eval gives
x % x
wrong sign whenx
is a negative float: rust-lang/rust#109567 (first reported rust-lang/rust#102403) - 🐉 Write to dangling pointer is hoisted outside of condition: rust-lang/rust#112213 (first reported llvm/llvm-project#51838)