-
-
Notifications
You must be signed in to change notification settings - Fork 14.7k
Broken match statement when compiling for thumbv6-none-eabi (ARM cortex-m0) #42248
Copy link
Copy link
Closed
Closed
Copy link
Labels
A-LLVMArea: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues.Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues.O-ArmTarget: 32-bit Arm processors (armv6, armv7, thumb...), including 64-bit Arm in AArch32 stateTarget: 32-bit Arm processors (armv6, armv7, thumb...), including 64-bit Arm in AArch32 stateP-highHigh priorityHigh priorityT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.regression-from-stable-to-nightlyPerformance or correctness regression from stable to nightly.Performance or correctness regression from stable to nightly.
Metadata
Metadata
Assignees
Labels
A-LLVMArea: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues.Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues.O-ArmTarget: 32-bit Arm processors (armv6, armv7, thumb...), including 64-bit Arm in AArch32 stateTarget: 32-bit Arm processors (armv6, armv7, thumb...), including 64-bit Arm in AArch32 stateP-highHigh priorityHigh priorityT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.regression-from-stable-to-nightlyPerformance or correctness regression from stable to nightly.Performance or correctness regression from stable to nightly.
Type
Fields
Give feedbackNo fields configured for issues without a type.
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_numis3) 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
17valued 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
d5565a227f8aa40e8c94efa9877a425003d02752from helena-project/tock and:the resulting binary will be
boards/nrf51dk/target/thumbv6-none-eabi/release/nrf51dk, which you can read withobjdump: