Skip to content

[AArch64] Use zero register directly for inline assembly #162567

@nathanchance

Description

@nathanchance

Forwarded on from a downstream report: ClangBuiltLinux/linux#2127

GCC directly generates xzr or wzr for the rZ constraint when the %x or %w modifier are used, whereas clang always stores to an intermediate register.

void write_zero_x(volatile unsigned long *addr)
{
    asm volatile("str %x1, %0\n" : : "Qo" (*addr), "rZ" (0));
}

void write_zero_w(volatile unsigned long *addr)
{
    asm volatile("str %w1, %0\n" : : "Qo" (*addr), "rZ" (0));
}

GCC 15.2.0:

$ aarch64-linux-gcc -O2 -c test.c

$ llvm-objdump -dr test.o

test.o: file format elf64-littleaarch64

Disassembly of section .text:

0000000000000000 <write_zero_x>:
       0: f900001f      str     xzr, [x0]
       4: d65f03c0      ret

0000000000000008 <write_zero_w>:
       8: b900001f      str     wzr, [x0]
       c: d65f03c0      ret

clang @ cd33c6b:

$ clang --target=aarch64-linux -O2 -c test.c

$ llvm-objdump -dr test.o

test.o: file format elf64-littleaarch64

Disassembly of section .text:

0000000000000000 <write_zero_x>:
       0: 2a1f03e8      mov     w8, wzr
       4: f9000008      str     x8, [x0]
       8: d65f03c0      ret

000000000000000c <write_zero_w>:
       c: 2a1f03e8      mov     w8, wzr
      10: b9000008      str     w8, [x0]
      14: d65f03c0      ret

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions