-
Notifications
You must be signed in to change notification settings - Fork 12.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Broken match statement when compiling for thumbv6-none-eabi (ARM cortex-m0) #42248
Comments
The last nightly where this works as expected is |
I also compiled to thumb assembly the same LLVM-IR with
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 |
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. |
@arielb1 you are my hero and savior! |
The bug is actually fixed by llvm-mirror/llvm@f4523b0 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 #42410? |
@arielb1 says the upgrade does not include the fix. |
So ARM had quite a few codegen bugs on LLVM 4.0 which are fixed on LLVM trunk. This backports 5 of them: r297871 - ARM: avoid clobbering register in v6 jump-table expansion. - fixes rust-lang#42248 r294949 - [Thumb-1] TBB generation: spot redefinitions of index r295816 - [ARM] Fix constant islands pass. r300870 - [Thumb-1] Fix corner cases for compressed jump tables r302650 - [IfConversion] Add missing check in IfConversion/canFallThroughTo - unblocks rust-lang#39409
Backport fixes to LLVM 4.0 ARM codegen bugs So ARM had quite a few codegen bugs on LLVM 4.0 which are fixed on LLVM trunk. This backports 5 of them: r297871 - ARM: avoid clobbering register in v6 jump-table expansion. - fixes #42248 r294949 - [Thumb-1] TBB generation: spot redefinitions of index r295816 - [ARM] Fix constant islands pass. r300870 - [Thumb-1] Fix corner cases for compressed jump tables r302650 - [IfConversion] Add missing check in IfConversion/canFallThroughTo - unblocks #39409 r? @alexcrichton beta-nominating because this fixes regressions introduced by LLVM 4.0.
Can you confirm the generated code works @alevy ? 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! |
Rust nightly 06-19-17 included LLVM upstream fixes that address an issue we were running into on Cortex-M0 targets. rust-lang/rust#42248
Turns out this Rust upstream issue is not resolved (actually an LLVM issue, but we thought it was just about upgrading the version of LLVM Rust uses): rust-lang/rust#42248 It seems as though the assembly _is_ different, but still incorrect (generating `add pc, r1` instead of `mov r0, r1; br pc` which is why I wasn't catching it...)
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! |
So ARM had quite a few codegen bugs on LLVM 4.0 which are fixed on LLVM trunk. This backports 5 of them: r297871 - ARM: avoid clobbering register in v6 jump-table expansion. - fixes rust-lang#42248 r294949 - [Thumb-1] TBB generation: spot redefinitions of index r295816 - [ARM] Fix constant islands pass. r300870 - [Thumb-1] Fix corner cases for compressed jump tables r302650 - [IfConversion] Add missing check in IfConversion/canFallThroughTo - unblocks rust-lang#39409
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
driver_num
is3
) 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
0x1fffe
. Finally, adding that to the current PC is way way way outside of the text segment and results in a hardware fault.Notes
We can "fix" this in a variety of ways:
Commenting out the
17
valued branch (commenting out no other branch seems to do the trick)Making the function
inline(never)
Using opt-level 0 or 1
Compiling for better supported architectures by LLVM (e.g.
thumbv7m-none-eabi
) although those don't run on the same hardware so I can only confirmMeta
This is using
rustc 1.19.0-nightly (5b13bff52 2017-05-23)
Reproducing
Checkout commit
d5565a227f8aa40e8c94efa9877a425003d02752
from helena-project/tock and:the resulting binary will be
boards/nrf51dk/target/thumbv6-none-eabi/release/nrf51dk
, which you can read withobjdump
:The text was updated successfully, but these errors were encountered: