-
Notifications
You must be signed in to change notification settings - Fork 13.2k
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
thumbv6m-none-eabi compiler builtin ABI bug #39056
Comments
I was recently hit by this bug as well and after further investigation I think that this might be a LLVM bug. I was able to reduce your test case to the following standalone LLVM-IR: define i32 @invalid_call(i32, i32) {
%3 = call { i32, i1 } @llvm.smul.with.overflow.i32(i32 %0, i32 %1)
%4 = extractvalue { i32, i1 } %3, 0
%5 = extractvalue { i32, i1 } %3, 1
br i1 %5, label %overflow, label %no_overflow
no_overflow:
ret i32 %4
overflow:
ret i32 0
}
declare { i32, i1 } @llvm.smul.with.overflow.i32(i32, i32) This compiles ( push {r7, lr}
mov r2, r1
asrs r1, r2, #31
asrs r3, r0, #31
bl __aeabi_lmul
... As you have correctly noticed this extends |
triage: P-low |
Suspected to be LLVM bug, so filing a bug there might be prudent. |
I just wanted to do so and it seems that someone noticed the bug. I guess this bug can be closed once Rust upgrades LLVM. |
@kaini If you feel this is urgent to fix, you can backport that patch to the rust-lang/llvm fork and then update the llvm submodule in this repo. |
@dnseitz This should be fixed in the latest nightly now. |
I'm helping to build a small operating system to run on Cortex-M0 processors. I'm compiling for the
thumbv6m-none-eabi
target. When using the compiler builtin function__aeabi_lmul
it seems that the compiler is passing in the arguments to the wrong registers. For example, this piece of code:Gets compiled down to:
According the the ARM ABI Documentation (Section 5.1.1.1), passing a 64bit value as an argument should store them in registers
r0
andr1
orr2
andr3
as a pair. With the low bits being stored inr0/2
and the high bits stored inr1/3
.Looking at the dissasembled code, the first argument, which was initially stored in
r0
gets its low and high bits split intor0
andr3
respectively, not the expectedr0
andr1
. The second argument also gets split intor2
andr1
for its low and high bits. So it appears that the high bits for the two values have been swapped.Because the values are sign extended from 32 bits, this is only an issue if the signs of the two arguments differ. If they're the same the high bit registers will happen to be the same. But when the signs differ the function returns a wrong result in the
r1
register. This causes a panic if overflow checking is enabled.I've not noticed this issue anywhere else, but it could possibly be hidden around in some of the other compiler builtins.
I've created a sample repo here that shows off the bug. You'll need an ARM toolchain to actually compile it down to a binary, but you should still be able to cross compile it into a static library. (the command I was using was
xargo build --target=thumbv6m-none-eabi
)Version info:
The text was updated successfully, but these errors were encountered: