{"id":"1c19055510ae08dc","repo":"rust-lang/rust","slug":"restore-register-for","errorCode":null,"errorMessage":"restore_register for {:?}","messagePattern":"restore_register for (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"compiler/rustc_codegen_cranelift/src/inline_asm.rs","lineNumber":822,"sourceCode":"                writeln!(generated_asm, \", [rbx+0x{:x}]\", offset.bytes()).unwrap();\n            }\n            InlineAsmArch::AArch64 => {\n                generated_asm.push_str(\"    ldr \");\n                match reg {\n                    InlineAsmReg::AArch64(reg) if reg.vreg_index().is_some() => {\n                        // rustc emits v0 rather than q0\n                        reg.emit(generated_asm, InlineAsmArch::AArch64, Some('q')).unwrap()\n                    }\n                    _ => reg.emit(generated_asm, InlineAsmArch::AArch64, None).unwrap(),\n                }\n                writeln!(generated_asm, \", [x19, 0x{:x}]\", offset.bytes()).unwrap();\n            }\n            InlineAsmArch::RiscV64 => {\n                generated_asm.push_str(\"    ld \");\n                reg.emit(generated_asm, InlineAsmArch::RiscV64, None).unwrap();\n                writeln!(generated_asm, \", 0x{:x}(s1)\", offset.bytes()).unwrap();\n            }\n            _ => unimplemented!(\"restore_register for {:?}\", arch),\n        }\n    }\n}\n\nfn call_inline_asm<'tcx>(\n    fx: &mut FunctionCx<'_, '_, 'tcx>,\n    asm_name: &str,\n    slot_size: Size,\n    inputs: Vec<(Size, Value)>,\n    outputs: Vec<(Size, CPlace<'tcx>)>,\n) {\n    let stack_slot =\n        fx.create_stack_slot(u32::try_from(slot_size.bytes().next_multiple_of(16)).unwrap(), 16);\n\n    let inline_asm_func = fx\n        .module\n        .declare_function(\n            asm_name,","sourceCodeStart":804,"sourceCodeEnd":840,"githubUrl":"https://github.com/rust-lang/rust/blob/22057b88b091743bc0fd8d592a9264f0a6951403/compiler/rustc_codegen_cranelift/src/inline_asm.rs#L804-L840","documentation":"Thrown by rustc_codegen_cranelift when restoring a register from its stack slot after a user asm! block. restore_register() emits the architecture-specific load (e.g. mov reg, [rbx+off]) to undo a clobber. Only X86_64, AArch64, and RiscV64 are implemented; other arches hit `_ => unimplemented!(\"restore_register for {:?}\", arch)`. It is the symmetric counterpart of save_register (error 73).","triggerScenarios":"Any asm! with out/inout register operands that clobber a callee-saved or allocated register, on a target other than X86_64/AArch64/RiscV64 with the Cranelift backend. The restore runs on the post-asm path for every register saved by save_register.","commonSituations":"Cross-compiling register-heavy inline asm (crypto, SIMD, bit manipulation) to LoongArch/PowerPC/Arm32/S390x/Mips under cg_clif; tier-3 target bring-up where the asm save/restore sequences were never ported.","solutions":["Use the LLVM backend for the unsupported target.","Gate the asm to x86_64/aarch64/riscv64 with cfg attributes.","Replace explicit register asm operands with portable Rust where possible.","Implement the arch arm in restore_register() (mirror the corresponding save_register() store as a load) and submit upstream."],"exampleFix":"// before\nlet mut v: u64;\nasm!(\"mov {}, 1\", inout(\"rax\") v, options(nostack));\n\n// after - no register clobber\nlet mut v: u64 = 1;","handlingStrategy":"validation","validationCode":"// Symmetric to save_register: scan for restore-path operands (out/inout\n// named registers) which trigger restore_register in cg_clif.\nlet re = regex::Regex::new(r#\"asm!.*\\b(out|inout)\\(\"(?:rax|rbx|rcx|rdx|rsi|rdi|rbp|r[0-9]+)\"\"#).unwrap();\nif src.contains(\"asm!\") && re.is_match(&src) {\n    return Err(\"restore_register path unimplemented in cranelift backend\");\n}","typeGuard":null,"tryCatchPattern":"// Not recoverable at runtime — rustc_codegen_cranelift panics.\n// Switch the affected crate to the LLVM codegen backend.","preventionTips":["Treat every asm! clobber as a potential save/restore pair; minimize them under cg_clif.","Keep a per-target `.cargo/config` that forces LLVM for crates containing inline asm.","Subscribe to cg_clif release notes; restore_register lands after save_register in the support timeline."],"tags":["rustc","cranelift","inline-asm","codegen","unimplemented","registers","target-arch"],"analyzedSha":"22057b88b091743bc0fd8d592a9264f0a6951403","analyzedAt":"2026-08-03T08:09:25.915Z","schemaVersion":2}