Description
Defining labels in inline assembly is broken because inlining, function cloning and other compiler optimizations may result in an asm!
block being emitted more than once in the final binary. This can cause duplicate symbol errors or even compiler crashes (#74262). For this reason it is recommended to only use GAS local labels when using asm!
(#76704).
To improve user experience when using asm!
, rustc should automatically rewrite label names into a unique name. For example:
asm!(
"popcnt {popcnt}, {v}",
"loop:",
"blsi rax, {v}",
"jz exit",
"xor {v}, rax",
"tzcnt rax, rax",
"stosb",
"jmp loop",
"exit:",
v = inout(reg) value => _,
popcnt = out(reg) popcnt,
out("rax") _, // scratch
inout("rdi") bits.as_mut_ptr() => _,
);
rustc should search for lines beginning with <ident>:
to find label names and then replace all instances of <ident>
in the assembly code with .Lasm_label_<ident><unique id>
. The .L
instructs the assembler that the label is local to the current compilation unit and should never be exported, even as a debug symbol. The unique ID can be generated by LLVM using ${:uid}
and is guaranteed to be unique within the current compilation unit.