Skip to content

Stack-returned struct prevents tail-calls and moving operations to registers #61195

Open
@dzaima

Description

@dzaima
typedef struct {
  long long a, b, c;
} S;

S ext1(void);
int ext2(int);

int f() {
  S v = ext1();
  v.a+= v.b;
  return ext2(v.a);
}
f:                                      # @f
        sub     rsp, 24
        mov     rdi, rsp
        call    ext1
        mov     rdi, qword ptr [rsp]
        add     rdi, qword ptr [rsp + 8]
        mov     qword ptr [rsp], rdi
        call    ext2
        add     rsp, 24
        ret

https://godbolt.org/z/zdr339Ke6 - gcc does a tail call, and doesn't store the result of the addition.

A related scenario is a stack-allocated value whose lifetime ends before the return, e.g.

typedef struct {
  long long a, b, c;
} S;

void ext1(S*);
int ext2(int);

int f(int a) {
  {
    S v;
    ext1(&v);
  }
  return ext2(a);
}

https://godbolt.org/z/fz58qWcos - gcc again tail-calls when clang doesn't.

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