Change:
After upgrading Tock to use a recent nightly, compilation for the NRF51-DK (a Cortex-M0 based board) results in unexpected assembly for a particular match statement. The match statement looks like this: The LLVM IR that (seems to) corresponds is: which is a fairly straight forward translation. In general, the template for the expected output in assembly is something like: The match statement seems to end up being broken up (makes sense since the matched values are sparse), with one of the cases (which is called at least when is ) looking like this: This basically doesn't make any sense... it's grabbing a text segment address, multiplying it by two then loading a half-word from an address that's again multiplied by two (and at this point, completely outside the text segment so it could be anything really). In practice, that returns 0xffff, which after shifting left by one results in . Finally, adding that to the current PC is way way way outside of the text segment and results in a hardware fault. We can "fix" this in a variety of ways: Commenting out the valued branch (commenting out no other branch seems to do the trick) Making the function Using opt-level 0 or 1 Compiling for better supported architectures by LLVM (e.g. ) although those don't run on the same hardware so I can only confirm This is using Checkout commit from helena-project/tock and: the resulting binary will be , which you can read with :
/cc and who helped debug this a bit on #rust-internals
The last nightly where this works as expected is , which I believe is the last one before the upgrade to LLVM 4.0, which is at least some evidence that this is an LLVM bug.
I also compiled to thumb assembly the same LLVM-IR with from an older version of LLVM 3.9 and a newer version of LLVM from git. LLVM 3.9 seems to use an entirely different mechanism for compiling switch statements to thumb assembly and recent git-LLVM seems to use the same strategy but doesn't result in the same strange compilation bug as described above. I'm still figuring out if it's possible to link the result and run it on my hardware, but if I can confirm that (2) works as expected, it seems there may be an existing fix somewhere in the LLVM source tree between the 4.0 that Rust uses and bleeding edge.
As Tock is moving around this problem with the fix, could you add a link to a commit hash that exhibits this issue?
LLVM bugs that cause scary miscompilations are not that rare, especially on non-x86 architectures. Normally, we work with the LLVM devs to get them fixed and backport the fixes to our LLVM version. Can you upload LLVM IR that exhibits the problem?
This change looks relevant: It's not on our LLVM. If I had LLVM IR exhibiting the bug I could check whether it fixes the problem.
Can confirm issue. Let me see whether the LLVM changes fix it.
you are my hero and savior!
The bug is actually fixed by rather than the other commit. Now we only have to see what scary codegen bugs the other commits to that file fix.
triage: P-high
Will this be fixed by the llvm upgrade
says the upgrade does not include the fix.
Can you confirm the generated code works ? I can't read ARM that well.
Appears to as far as I can test. I've not been able to reliably get a minimal, repeatable example of the bug, but on code that breaks with previous nightly doesn't break with this one, so seems fixed to me!
Yay!
No no no! False alarm! I hadn't upgraded to the right Rust version when I pushed my changes to Tock upstream! It works! Sorry again!

Discussion:
<del> Subproject commit ee545e1d13e6f2191572aebcadb7d1640ce45c65 </del> <ins> Subproject commit 5415ff0264c134152cca65ae8f5d50b356d61162 </ins>

# If this file is modified, then llvm will be (optionally) cleaned and then rebuilt. # The actual contents of this file do not matter, but to trigger a change on the # build bots then the contents should be changed so git updates the mtime. <del> 2017-06-03 </del> <ins> 2017-06-18 </ins>