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