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>