{"id":"b5a1a57bbb0475f9","repo":"rust-lang/rust","slug":"epilogue-for","errorCode":null,"errorMessage":"epilogue for {:?}","messagePattern":"epilogue for (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"compiler/rustc_codegen_cranelift/src/inline_asm.rs","lineNumber":708,"sourceCode":"    fn epilogue(generated_asm: &mut String, arch: InlineAsmArch) {\n        match arch {\n            InlineAsmArch::X86_64 => {\n                generated_asm.push_str(\"    pop rbx\\n\");\n                generated_asm.push_str(\"    pop rbp\\n\");\n                generated_asm.push_str(\"    ret\\n\");\n            }\n            InlineAsmArch::AArch64 => {\n                generated_asm.push_str(\"    ldr x19, [sp, #24]\\n\");\n                generated_asm.push_str(\"    ldp fp, lr, [sp], #32\\n\");\n                generated_asm.push_str(\"    ret\\n\");\n            }\n            InlineAsmArch::RiscV64 => {\n                generated_asm.push_str(\"    ld s1, 0(sp)\\n\");\n                generated_asm.push_str(\"    ld ra, 8(sp)\\n\");\n                generated_asm.push_str(\"    addi sp, sp, 16\\n\");\n                generated_asm.push_str(\"    ret\\n\");\n            }\n            _ => unimplemented!(\"epilogue for {:?}\", arch),\n        }\n    }\n\n    fn epilogue_noreturn(generated_asm: &mut String, arch: InlineAsmArch) {\n        match arch {\n            InlineAsmArch::X86_64 => {\n                generated_asm.push_str(\"    ud2\\n\");\n            }\n            InlineAsmArch::AArch64 => {\n                generated_asm.push_str(\"    brk     #0x1\\n\");\n            }\n            InlineAsmArch::RiscV64 => {\n                generated_asm.push_str(\"    ebreak\\n\");\n            }\n            _ => unimplemented!(\"epilogue_noreturn for {:?}\", arch),\n        }\n    }\n","sourceCodeStart":690,"sourceCodeEnd":726,"githubUrl":"https://github.com/rust-lang/rust/blob/22057b88b091743bc0fd8d592a9264f0a6951403/compiler/rustc_codegen_cranelift/src/inline_asm.rs#L690-L726","documentation":"Thrown by rustc_codegen_cranelift when emitting the inline-asm epilogue that restores the base pointer and callee-saved register after a user asm! block returns. As with the prologue, only X86_64, AArch64, and RiscV64 have restore sequences; any other InlineAsmArch hits `_ => unimplemented!(\"epilogue for {:?}\", arch)`. It fires only for asm! blocks that fall through to a return (non-noreturn).","triggerScenarios":"Compiling asm! with register operands that need an epilogue restore, on a target other than X86_64/AArch64/RiscV64, using the Cranelift backend. Specifically asm! blocks that are not marked noreturn and therefore require restoring the saved base register (e.g. s1 on RiscV, rbx on x86_64) before ret.","commonSituations":"Using cg_clif on a tier-3 target (LoongArch64, PowerPC, S390x, Arm32) where the crate uses inline asm for perf counters, spinlocks, or CPUID-like probes; nightly toolchain with the cranelift codegen backend forced on.","solutions":["Switch the codegen backend to LLVM (default) for this build target.","Constrain the crate/arch to x86_64, aarch64, or riscv64 when using Cranelift.","Add #[cfg(not(target_arch = \"...\"))] gates around the offending asm! so it is skipped on unsupported arches.","Implement the arch arm in epilogue() (mirror the corresponding prologue() restore order) and patch upstream."],"exampleFix":"// before\nunsafe fn pause() { asm!(\"nop\", out(\"eax\") _, options(nostack)); }\n\n// after - only build the asm on backends/arches Cranelift supports\n#[cfg(any(target_arch = \"x86_64\", target_arch = \"aarch64\", target_arch = \"riscv64\"))]\nunsafe fn pause() { asm!(\"nop\", out(\"eax\") _, options(nostack)); }","handlingStrategy":"validation","validationCode":"// Reject asm! macros that contain prologue/epilogue-style register clobbers\n// before invoking the cranelift backend.\nlet src = std::fs::read_to_string(\"src/lib.rs\")?;\nif src.contains(\"asm!\") && (src.contains(\"in(\") || src.contains(\"out(\") || src.contains(\"clobber_abi\")) {\n    eprintln!(\"cg_clif epilogue path for inline asm is unimplemented; switch to LLVM.\");\n}","typeGuard":null,"tryCatchPattern":"// Unreachable at runtime: panics inside rustc_codegen_cranelift abort the\n// compiler process. Guard at build time instead.\n// build.rs:\nfn main() {\n    let backend = std::env::var(\"RUSTC_CODEGEN\").unwrap_or_default();\n    if backend == \"cranelift\" { println!(\"cargo:rustc-cfg=needs_llvm_codegen\"); }\n}","preventionTips":["Inline-asm epilogues (return-path clobber restore) are unimplemented in cg_clif; keep asm! out of hot paths compiled with cranelift.","Prefer intrinsics (`core::arch::x86_64::_...`) over hand-written asm where available.","When asm is unavoidable, build only that crate with the LLVM backend via `.cargo/config` per-target triple."],"tags":["rustc","cranelift","inline-asm","codegen","unimplemented","target-arch"],"analyzedSha":"22057b88b091743bc0fd8d592a9264f0a6951403","analyzedAt":"2026-08-03T08:09:25.915Z","schemaVersion":2}