Skip to content
Jake Goulding edited this page Jun 13, 2020 · 9 revisions

As a more-maintained but less AVR-specific reference, see the rustc developer guide.

Generating testcases

Get the offending Rust code as LLVM IR

cargo build --release --target=./arduino.json --verbose
# grab the `rustc ...` invocation
# add `--emit=llvm-ir`
# Look for `target/arduino/release/deps/foo.0.ll`

You can also investigate using a tool like cargo llvm-ir.

Build LLVM

  1. Clone the repository

  2. Check out the corresponding source code of the version of the Rust compiler

    rustc --version
    
    rustc 1.46.0-nightly (f4fbb9311 2020-06-12)
    #                     ^^^^^^^^^
    % git checkout f4fbb9311
    
  3. Configure LLVM with debugging information

    ./configure \
      --disable-optimize-llvm \
      --enable-llvm-assertions
    

    Your config.toml should contain these keys in the [llvm] section:

    optimize = false
    assertions = true
  4. Build LLVM:

    ./x.py build llvm 
    

The LLVM tools will be available in $RUST_DIRECTORY/build/$TARGET/llvm

Reduce the testcase

Create the two supporting files, then run it against your LLVM IR (./bugpoint.sh myfile.ll). This will produce a bugpoint-reduced-simplified.bc, which you can convert back to IR with llvm-dis.

bugpoint.sh

This is the main script used to invoke LLVM's bugpoint tool.

#!/bin/bash

set -eux

root=$RUST_DIRECTORY/build/$TARGET/ # Edit this line
export PATH=$root/llvm/bin/:$PATH

bugpoint $1 -compile-custom -compile-command ./repro.sh -safe-tool-args -march=avr -mcpu=atmega328p -filetype=obj

repro.sh

This is the script that, when run with your test file path as an argument, should return an error code if your bug is successfully reproduced.

Edit this file to look for your error

#!/bin/bash

set -eux

root=$RUST_DIRECTORY/build/$TARGET/ # Edit this line
export PATH=$root/llvm/bin/:$PATH

! llc -march=avr -mcpu=atmega328p -filetype=obj $1 2>&1 | \
    grep 'error: my unique error text' # Edit this line

Apply human touch

Look at the LLVM IR. Are there a bunch of defined types or functions that aren't needed? Try removing them. If you remove a bunch, try throwing it back into bugpoint. Repeat until it's "small enough" or you give up.

Metadata generally lives at the bottom of the IR file and is prefixed with !. You should be able to remove metadata from the testcase in almost every single case and it will have no effect on the test itself. If metadata is deleted, make sure to delete references to it.

Metadata references usually live after function declarations like so

define void @foo() !3 {
   ...
}

!3 = ...

In this case, to remove the metadata reference, remove !3 from both lines