[cfe-dev] Redundant byval in C codegen?

Zhongxing Xu xuzhongxing at gmail.com
Sat Jan 16 03:59:21 CST 2010


For this C code,

struct s {
  int a[40];
};

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

void f() {
  struct s a;
  g(a);
}

clang generates llvm IR:

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

define void @f() nounwind {
entry:
  %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:

f:
.Leh_func_begin2:
pushq %rbp
.Llabel3:
movq %rsp, %rbp
.Llabel4:
subq $496, %rsp


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


More information about the cfe-dev mailing list