Hi,<br><br>I am using clang on the following code, <br><br>struct S {<br>  float a,b,c;<br>};<br><br>void foo(struct S obj) {<br>  obj.a = 1.2;<br>}<br><br>int main() {<br>  struct S s;<br>  s.a = 1.0;<br>  s.b = 1.0;<br>  s.c = 1.0;<br>

  foo(s);<br>  return 0;<br>}<br><br>The generated code for foo, changes the type of the argument to foo to be {double, double} . <br><br>llvm-gcc was converting this to {double, float} which was an ABI requirement, as par an older discussion(<a href="http://lists.cs.uiuc.edu/pipermail/llvmdev/2010-January/028870.html">http://lists.cs.uiuc.edu/pipermail/llvmdev/2010-January/028870.html</a>)<br>

<br>Why does clang change it to a struct with a different size?<br><br>The generated IR is below.<br><br>Thanks<br>Arushi<br><br><br>; ModuleID = 'mrv.cpp'<br>target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"<br>

target triple = "x86_64-unknown-linux-gnu"<br><br>%0 = type { double, double }<br>%struct.S = type { float, float, float }<br><br>define void @_Z3foo1S(%0) {<br>entry:<br>  %obj = alloca %struct.S, align 4                ; <%struct.S*> [#uses=2]<br>

  %tmp = alloca %0                                ; <%0*> [#uses=2]<br>  store %0 %0, %0* %tmp<br>  %1 = bitcast %0* %tmp to %struct.S*             ; <%struct.S*> [#uses=1]<br>  %2 = load %struct.S* %1, align 1                ; <%struct.S> [#uses=1]<br>

  store %struct.S %2, %struct.S* %obj<br>  %tmp1 = getelementptr inbounds %struct.S* %obj, i32 0, i32 0 ; <float*> [#uses=1]<br>  store float 0x3FF3333340000000, float* %tmp1<br>  ret void<br>}<br><br>define i32 @main() {<br>

entry:<br>  %retval = alloca i32, align 4                   ; <i32*> [#uses=3]<br>  %s = alloca %struct.S, align 4                  ; <%struct.S*> [#uses=4]<br>  %agg.tmp = alloca %struct.S, align 4            ; <%struct.S*> [#uses=2]<br>

  %tmp5 = alloca %0                               ; <%0*> [#uses=2]<br>  store i32 0, i32* %retval<br>  %tmp = getelementptr inbounds %struct.S* %s, i32 0, i32 0 ; <float*> [#uses=1]<br>  store float 1.000000e+00, float* %tmp<br>

  %tmp1 = getelementptr inbounds %struct.S* %s, i32 0, i32 1 ; <float*> [#uses=1]<br>  store float 1.000000e+00, float* %tmp1<br>  %tmp2 = getelementptr inbounds %struct.S* %s, i32 0, i32 2 ; <float*> [#uses=1]<br>

  store float 1.000000e+00, float* %tmp2<br>  %tmp3 = bitcast %struct.S* %agg.tmp to i8*      ; <i8*> [#uses=1]<br>  %tmp4 = bitcast %struct.S* %s to i8*            ; <i8*> [#uses=1]<br>  call void @llvm.memcpy.i64(i8* %tmp3, i8* %tmp4, i64 12, i32 4)<br>

  %0 = bitcast %0* %tmp5 to %struct.S*            ; <%struct.S*> [#uses=1]<br>  %1 = load %struct.S* %agg.tmp                   ; <%struct.S> [#uses=1]<br>  store %struct.S %1, %struct.S* %0, align 1<br>  %2 = load %0* %tmp5                             ; <%0> [#uses=1]<br>

  call void @_Z3foo1S(%0 %2)<br>  store i32 0, i32* %retval<br>  %3 = load i32* %retval                          ; <i32> [#uses=1]<br>  ret i32 %3<br>}<br><br>declare void @llvm.memcpy.i64(i8* nocapture, i8* nocapture, i64, i32) nounwind<br>

<br><br>