Skip to content
Dylan McKay edited this page Feb 20, 2018 · 9 revisions

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`

Build LLVM

Basically, recreate what the build system does

cmake \
  -D CMAKE_BUILD_TYPE=Debug \
  -D LLVM_ENABLE_ASSERTIONS=ON \
  -D LLVM_TARGETS_TO_BUILD="X86" \
  -D LLVM_EXPERIMENTAL_TARGETS_TO_BUILD="AVR" \
  -D LLVM_INCLUDE_EXAMPLES=OFF \
  -D LLVM_INCLUDE_TESTS=OFF \
  -D LLVM_INCLUDE_DOCS=OFF \
  -D LLVM_ENABLE_ZLIB=OFF \
  -D WITH_POLLY=OFF \
  -D LLVM_ENABLE_TERMINFO=OFF \
  -D LLVM_ENABLE_LIBEDIT=OFF \
  ..

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

export PATH=../debug/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

# NOTE: You may need to update the path of llc if you
#       do not have the avr-rust/llvm binaries as the
#       highest precedence LLVM toolchain in your path.
! llc -march=avr -mcpu=atmega328p -filetype=obj $1 2>&1 | grep 'No instruction defining live value'

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, simply remove !3 from both lines

Clone this wiki locally