Skip to content

__aeabi_lmul on thumbv6m-none-eabi #127

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

Closed
seeday opened this issue Dec 16, 2016 · 5 comments · Fixed by #132
Closed

__aeabi_lmul on thumbv6m-none-eabi #127

seeday opened this issue Dec 16, 2016 · 5 comments · Fixed by #132

Comments

@seeday
Copy link

seeday commented Dec 16, 2016

Managed to track a crash when using lmul down to what seems to be a stack overflow, with a loop between the __aeabi_lmul and __muldi3 functions. I think it's due to 0x6ccc in this dump.

@japaric
Copy link
Member

japaric commented Dec 16, 2016

I think this is how the disassembly was produced:

$ cargo new --bin app && cd $_
$ edit src/main.rs && cat $_
#![feature(compiler_builtins_lib)]
#![feature(lang_items)]
#![no_main]
#![no_std]

extern crate compiler_builtins;

use core::ptr;

#[no_mangle]
pub fn _start() -> ! {
    let x = unsafe {
        ptr::read_volatile(0x0 as *const u32)
    };
    let y = x * (48000000 / 1000000) / 3;

    loop {}
}

#[lang = "panic_fmt"]
#[no_mangle]
fn panic_fmt() {}

#[no_mangle]
pub fn __aeabi_unwind_cpp_pr0() {}
$ xargo rustc --target thumbv6m-none-eabi -- -C link-arg=-nostartfiles

@seeday
Copy link
Author

seeday commented Dec 16, 2016

@japaric correct. For completeness here's the full function.

pub fn udelay(us: u32) {
    if us == 0 {
        return;
    }

    let n = us * (48_000_000 / 1_000_000) / 3;
    unsafe {
        asm!("1:
          subs $0, #1
          bne 1b
         " :: "r" (n));
    }
}

@parched
Copy link
Contributor

parched commented Dec 29, 2016

I had a look at the LLVM IR on playground and it seems that rustc calls the intrinsic @llvm.umul.with.overflow.i32 for all the normal multiplications in __muldi3 here in debug mode. That instrinic calls __aeabi_lmul as @seeday spotted which calls __muldi3 and hence the infinite recursion. Replacing the normal multiplications with wrapping_mul should solve the problem I believe.

@nezza
Copy link

nezza commented Jan 2, 2017

@parched Hi, thanks for taking the time to look at this! Do you happen to have a rough patch idea for that? I am unfortunately not yet deep enough into the compiler-rt code but am facing the same issue.
Thanks in advance!

@nezza
Copy link

nezza commented Jan 2, 2017

@parched Wow, thanks for the fast patch. I can confirm this works for me and stops the infinite recursion from happening.

bors added a commit that referenced this issue Jan 2, 2017
mul.rs: use wrapping_mul to avoid infinite recursion

rustc in debug mode with a plain multiplication will call @llvm.umul.with.overflow.* which may call the builtin resulting in infinite recursion.

Fixes #127.

Cc @nezza this should be the fix you can try. Note I made this patch in github's web Ui so it's completely untested.
@bors bors closed this as completed in #132 Jan 2, 2017
tgross35 pushed a commit to tgross35/compiler-builtins that referenced this issue Feb 23, 2025
127: update changelog; add more copyright notices r=japaric a=japaric



Co-authored-by: Jorge Aparicio <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants