Skip to content

Incorrect handling of pointer to return value in ARM64EC entry thunks #90229

Closed
@julliard

Description

@julliard

When a function returns a structure that doesn't fit in a register, a pointer to the storage for the return value is passed as hidden parameter. On x86-64 this takes the place of the first parameter (%rcx) but on aarch64 this uses the x8 register.

This means that ARM64EC entry thunks need to shuffle registers to move x0 -> x8, x1 -> x0, etc. Here's a test case:

#include <stdint.h>

struct s { intptr_t a, b, c; };

struct s func( struct s a )
{
    struct s ret = { a.a + 1, a.b + 2, a.c + 3 };
    return ret;
}

The corresponding entry thunk generated by LLVM doesn't convert anything:

0000000000000000 <.wowthk$aa>:
       0: adba9fe6     	stp	q6, q7, [sp, #-0xb0]!
       4: ad0127e8     	stp	q8, q9, [sp, #0x20]
       8: ad022fea     	stp	q10, q11, [sp, #0x40]
       c: ad0337ec     	stp	q12, q13, [sp, #0x60]
      10: ad043fee     	stp	q14, q15, [sp, #0x80]
      14: a90a7bfd     	stp	x29, x30, [sp, #0xa0]
      18: 910283fd     	add	x29, sp, #0xa0
      1c: d63f0120     	blr	x9
      20: 90000008     	adrp	x8, 0x0 <.wowthk$aa>
      24: f9400100     	ldr	x0, [x8]
      28: a94a7bfd     	ldp	x29, x30, [sp, #0xa0]
      2c: ad443fee     	ldp	q14, q15, [sp, #0x80]
      30: ad4337ec     	ldp	q12, q13, [sp, #0x60]
      34: ad422fea     	ldp	q10, q11, [sp, #0x40]
      38: ad4127e8     	ldp	q8, q9, [sp, #0x20]
      3c: acc59fe6     	ldp	q6, q7, [sp], #0xb0
      40: d61f0000     	br	x0

While MSVC generates code to shuffle registers:

0000000000000000 <.wowthk$aa>:
       0: d503237f     	pacibsp
       4: f8150ff3     	str	x19, [sp, #-0xb0]!
       8: ad009fe6     	stp	q6, q7, [sp, #0x10]
       c: ad01a7e8     	stp	q8, q9, [sp, #0x30]
      10: ad02afea     	stp	q10, q11, [sp, #0x50]
      14: ad03b7ec     	stp	q12, q13, [sp, #0x70]
      18: ad04bfee     	stp	q14, q15, [sp, #0x90]
      1c: a9bf7bfd     	stp	x29, x30, [sp, #-0x10]!
      20: 910003fd     	mov	x29, sp
      24: aa0003f3     	mov	x19, x0
      28: aa0103e0     	mov	x0, x1
      2c: aa1303e8     	mov	x8, x19
      30: d63f0120     	blr	x9
      34: aa1303e8     	mov	x8, x19
      38: a8c17bfd     	ldp	x29, x30, [sp], #0x10
      3c: ad44bfee     	ldp	q14, q15, [sp, #0x90]
      40: ad43b7ec     	ldp	q12, q13, [sp, #0x70]
      44: ad42afea     	ldp	q10, q11, [sp, #0x50]
      48: ad41a7e8     	ldp	q8, q9, [sp, #0x30]
      4c: ad409fe6     	ldp	q6, q7, [sp, #0x10]
      50: f84b07f3     	ldr	x19, [sp], #0xb0
      54: d50323ff     	autibsp
      58: 90000010     	adrp	x16, 0x0 <.wowthk$aa>
      5c: f9400210     	ldr	x16, [x16]
      60: d61f0200     	br	x16

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions