Question about 'byval'

Hello, I am seeking a clarification of the semantics of ‘byval’ parameter attribute in llvm IR.

Let’s assume the ABI says the caller should create the ‘hidden copy’ of the pointee. My question is which part of the compiler chain should generate the alloca and copy code. My understanding is that it is the target code generator, not the provider of the llvm IR.

But given the following simple test case,

typedef struct {
int a;
int b[1000];
} A;

void bar(A s) {
s.a = 1;
}

void foo(void) {
A s;
s.a = 100;
bar(s);
}

I see ‘clang’ generates an extra copy in foo() and the parameter for bar() also has the ‘byval’ attribute.

Running the generated bc file through various backends , I see different behaviors,

  • x86 and ppc32 create yet another copy on the caller site, while
  • arm, sparc, and mips do not.

What am I missing? Thanks.

– Yuan

Hello, I am seeking a clarification of the semantics of ‘byval’ parameter attribute in llvm IR.

Let’s assume the ABI says the caller should create the ‘hidden copy’ of the pointee. My question is which part of the compiler chain should generate the alloca and copy code. My understanding is that it is the target code generator, not the provider of the llvm IR.

But given the following simple test case,

typedef struct {
    int a;
    int b[1000];
} A;

void bar(A s) {
    s.a = 1;
}

void foo(void) {
    A s;
    s.a = 100;
    bar(s);
}

I see ‘clang’ generates an extra copy in foo() and the parameter for bar() also has the ‘byval’ attribute.

Running the generated bc file through various backends , I see different behaviors,
- x86 and ppc32 create yet another copy on the caller site, while
- arm, sparc, and mips do not.

What am I missing? Thanks.

The ARM backend does not support "byval", at least not very well. It wouldn't surprise me if the same is true for Mips and Sparc. The X86 and PPC behavior is what you want to look at.

Hi Yuan,

Hello, I am seeking a clarification of the semantics of ‘byval’ parameter
attribute in llvm IR.

none of the explicit copies you see are needed. On x86 and x86-64, the latest
llvm-gcc does not create any explicit copies in the LLVM IR. The code generator
introduces a copy because of the 'byval' attribute (at -O0 and -O1; at -O2 and
above that copy is removed too).

Ciao,

Duncan.