[cfe-dev] Redundant byval in C codegen?

Zhongxing Xu xuzhongxing at gmail.com
Sat Jan 16 01:59:21 PST 2010

For this C code,

struct s {
  int a[40];

void g(struct s a) {
  a.a[0] = 4;

void f() {
  struct s a;

clang generates llvm IR:

define void @g(%struct.s* byval %a) nounwind {
  %tmp = getelementptr inbounds %struct.s* %a, i32 0, i32 0 ; <[40 x i32]*>
  %arraydecay = getelementptr inbounds [40 x i32]* %tmp, i32 0, i32 0 ;
<i32*> [#uses=1]
  %arrayidx = getelementptr inbounds i32* %arraydecay, i64 0 ; <i32*>
  store i32 4, i32* %arrayidx
  ret void

define void @f() nounwind {
  %a = alloca %struct.s, align 4                  ; <%struct.s*> [#uses=1]
  %agg.tmp = alloca %struct.s                     ; <%struct.s*> [#uses=2]
  %tmp = bitcast %struct.s* %agg.tmp to i8*       ; <i8*> [#uses=1]
  %tmp1 = bitcast %struct.s* %a to i8*            ; <i8*> [#uses=1]
  call void @llvm.memcpy.i64(i8* %tmp, i8* %tmp1, i64 160, i32 4)
  call void @g(%struct.s* byval %agg.tmp)
  ret void

Since we have already alloca'ed a temporary struct.s %agg.tmp, why is there
still a 'byval' in g's parameter? The consequence of this is when assembly
code is generated, we end up with allocating 3 structs on the stack:

pushq %rbp
movq %rsp, %rbp
subq $496, %rsp

Could somebody explain the rationale behind this behavior? Thanks.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20100116/c2b0f7c7/attachment.html>

More information about the cfe-dev mailing list