Issue 89615
Summary Invalid calling convention used for passing structures to varargs functions on ARM64EC
Labels new issue
Assignees
Reporter julliard
    On ARM64EC, passing structures to varargs functions uses the arm64 calling convention, but it should use the x64 convention, as documented at https://learn.microsoft.com/en-us/windows/arm/arm64ec-abi#variadic-calling-convention

Below is a short test case showing that a 5-byte structure is passed by value, but according to the ARM64EC ABI it should be passed by reference:

```
struct s { char a, b, c, d, e; };

extern void foo( int a, ... );

void bar(void)
{
    struct s s = { 1, 2, 3, 4, 5 };
    foo( 0, s );
}
```

LLVM generates this (structure contents in x1):

```
       0: d2804021     	mov	x1, #0x201
 4: 910003e4     	mov	x4, sp
       8: 2a1f03e0     	mov	w0, wzr
       c: f2a08061     	movk	x1, #0x403, lsl #16
      10: aa1f03e5     	mov	x5, xzr
      14: f2c000a1     	movk	x1, #0x5, lsl #32
      18: 14000000     	b	0x18 <.text+0x18>
```

while MSVC does this (structure contents on stack, pointer in x1):

```
 0: f81f0ffe     	str	x30, [sp, #-0x10]!
       4: d10043ff 	sub	sp, sp, #0x10
       8: 910003e1     	mov	x1, sp
       c: d2800000     	mov	x0, #0x0
      10: 910003e4     	mov	x4, sp
 14: d2800005     	mov	x5, #0x0
      18: 52804028     	mov	w8, #0x201
      1c: 72a08068     	movk	w8, #0x403, lsl #16
      20: b90003e8     	str	w8, [sp]
      24: 528000a8     	mov	w8, #0x5
 28: 390013e8     	strb	w8, [sp, #0x4]
      2c: 94000000 	bl	0x2c <.text$mn+0x2c>
      30: 910043ff     	add	sp, sp, #0x10
 34: f84107fe     	ldr	x30, [sp], #0x10
      38: d65f03c0 	ret
```

_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to