https://gcc.gnu.org/bugzilla/show_bug.cgi?id=121253

            Bug ID: 121253
           Summary: aarch64 inline asm: 128-bit output operands use
                    clobbered registers
           Product: gcc
           Version: 15.1.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: target
          Assignee: unassigned at gcc dot gnu.org
          Reporter: nate at thatsmathematics dot com
  Target Milestone: ---

Created attachment 61974
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=61974&action=edit
test case

On aarch64, a 128-bit type used as an output operand for an inline asm may be
allocated in a register marked as clobbered.

Consider the C code:

struct s128 {
    long a, b;
};

struct s128 foo(void) {
    struct s128 ret;
    asm("mov %0, #0 \n\t"
        "mov %R0, #0 \n\t"
        "mov x0, #12345"
        : "=r" (ret) : : "x0");
    return ret;
}

(Yes, I know the R operand modifier is undocumented; it's just to help
illustrate the problem.)

In all 15.x versions I tried including godbolt's trunk, the generated asm with
`-O1` or higher is

        mov x0, #0
        mov x1, #0
        mov x0, #12345
        ret

Note that the output operand `ret` has been allocated in {x0,x1} while x0 was
marked as clobbered.  This results in an incorrect return value {12345,0}
instead of {0,0}.

Try on godbolt: https://godbolt.org/z/5j1hGa5Gj

This can also be reproduced using `__int128` in place of `struct s128`.

This is a regression from 14.x and earlier, which handle this correctly (e.g.
allocating `ret` in {x2,x3}).

Reply via email to