Skip to content
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

assertion with 64-bit division #45

Closed
japaric opened this issue Sep 17, 2021 · 3 comments · Fixed by #51
Closed

assertion with 64-bit division #45

japaric opened this issue Sep 17, 2021 · 3 comments · Fixed by #51
Labels
bug Something isn't working

Comments

@japaric
Copy link
Owner

japaric commented Sep 17, 2021

Source code

static X: AtomicUsize = AtomicUsize::new(0);

#[entry]
fn main() -> ! {
    X.store(div64 as usize, Ordering::Relaxed);

    loop {}
}

fn div64(x: u64, y: u64) -> u64 {
    x / y
}

#[exception]
fn SysTick() {
    X.fetch_add(1, Ordering::Relaxed);
}

Error message

2021-09-17T10:55:53Z WARN  cargo_call_stack] no type information for `_ZN17compiler_builtins3int19specialized_div_rem11u64_div_rem17hfa5cc727e5163f40E`
thread 'main' panicked at 'assertion failed: `(left == right)`
  left: `8`,
 right: `24`: BUG: LLVM reported that `__aeabi_uldivmod` uses 8 bytes of stack but this doesn't match our analysis', src/main.rs:962:29

Machine code

000004ec <__aeabi_uldivmod>:
 4ec:   b510        push    {r4, lr}
 4ee:   b084        sub sp, #16
 4f0:   ac02        add r4, sp, #8
 4f2:   9400        str r4, [sp, #0]
 4f4:   f000 f925   bl  742 <__udivmoddi4>
 4f8:   9a02        ldr r2, [sp, #8]
 4fa:   9b03        ldr r3, [sp, #12]
 4fc:   b004        add sp, #16
 4fe:   bd10        pop {r4, pc}
@japaric japaric added the bug Something isn't working label Sep 17, 2021
@jonas-schievink
Copy link
Collaborator

Source:

#[naked]
#[cfg_attr(not(feature = "mangled-names"), no_mangle)]
pub unsafe extern "C" fn __aeabi_uldivmod() {
    asm!(
        "push {{r4, lr}}",
        "sub sp, sp, #16",
        "add r4, sp, #8",
        "str r4, [sp]",
        "bl __udivmoddi4",
        "ldr r2, [sp, #8]",
        "ldr r3, [sp, #12]",
        "add sp, sp, #16",
        "pop {{r4, pc}}",
        options(noreturn)
    );
}

@japaric
Copy link
Owner Author

japaric commented Sep 20, 2021

LLVM-IR:

; Function Attrs: naked noinline nounwind
define hidden void @__aeabi_uidivmod() unnamed_addr #1 {
start:
  tail call void asm sideeffect alignstack "push {lr}\0Asub sp, sp, #4\0Amov r2, sp\0Abl __udivmodsi4\0Aldr r1, [sp]\0Aadd sp, sp, #4\0Apop {pc}", "~{cc},~{memory}"() #16, !srcloc !0
  unreachable
}

I know -Zemit-stack-sizes (LLVM's stack-sizes feature) ignores all inline assembly when computing the stack usage of a function -- we already warn about this other places like cortex_m::asm where we assume the inline assembly uses 0 bytes of stack, which is usually the case.

So I guess the issue here is that stack-sizes also ignores the naked attribute so it considers this function to be a normal, empty function that uses a few bytes of stack -- even though no extra machine code is generated around the inline asm! call.

I think in general we should identify the #[naked] + inline asm! pattern in LLVM-IR and assume that LLVM is wrong on those and solely rely on cargo-call-stack's disassembler.
To get the LLVM-IR for compiler-builtins we would need to do #46

(It would have been nice if they had written these subroutines with global_asm! instead of #[naked] then we wouldn't be seeing this issue)

@jonas-schievink
Copy link
Collaborator

I know -Zemit-stack-sizes (LLVM's stack-sizes feature) ignores all inline assembly when computing the stack usage of a function

Ah, I wouldn't have expected that. I would've thought that the stack size analysis runs on MIR.

The proposed solution sounds good though!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants