[AArch64] Incorrect register used for inline assembly input
define void @foo() {
%1 = call i32 asm sideeffect "", "={x0},0"(i32 435)
ret void
}
With llc -march=aarch64 -O0, this generates the following assembly.
foo: // @foo
.cfi_startproc
// %bb.0:
mov w8, #435
mrs x0, NZCV
//APP
//NO_APP
ret
Using ={x0},{x0} instead of ={x0},0 seems to avoid this issue,
~~This IR is generated by rustc's inline assembly for an inout("x8") operand, so perhaps this is rustc's fault?~~
Actually I can reproduce this bug in Clang as well, so it's definitely not an issue that is unique to rustc.
void foo() {
register int x asm("x8") = 435;
asm volatile("" : "+&r" (x));
}
Causes an assertion failure:
X0 = COPY W8
unimplemented reg-to-reg copy
@llvm/issue-subscribers-backend-aarch64
I worked around this in rustc (https://github.com/rust-lang/rust/pull/103897) by renaming the register to wN instead of xN if the type is 32-bit or smaller. Perhaps this should be solved in the frontend in Clang?