llvm-project icon indicating copy to clipboard operation
llvm-project copied to clipboard

[AArch64] Incorrect register used for inline assembly input

Open Amanieu opened this issue 3 years ago • 2 comments

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));
}

Amanieu avatar Oct 15 '22 20:10 Amanieu

Causes an assertion failure:

X0 = COPY W8
unimplemented reg-to-reg copy

nikic avatar Oct 15 '22 20:10 nikic

@llvm/issue-subscribers-backend-aarch64

llvmbot avatar Oct 15 '22 20:10 llvmbot

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?

Amanieu avatar Nov 03 '22 07:11 Amanieu