Hi, <br><br>I made a simple test about aggregates in llvm IR.  My simple LLVM code <br>is running as expected under linux 32/64, but not under windows 32.  <br>After searched on the web on multiple return values, I'm still not sure if<br>
this test case can be flagged as the ABI issue. Or this would be a llvm <br>code generator bug on window 32. The complete IR is attached as a text file<br>and I checked the test with lli. <br><br>(1) Pass a struct of type {void*, uint64_t} by pointer (in fact this is generated from Clang 3.0). <br>
The returned value of @call_by_pointer is 4 as expected, on both windows XP ia32 <br>and linux ubuntu x64 I tested. <br><br>%0 = type { i8*, i64 }<br><br>define void @foo_by_pointer(%0* %agg_addr, i8*, i64) nounwind {<br>
entry:<br>  %agg_addr.0 = getelementptr inbounds %0* %agg_addr, i32 0, i32 0<br>  store i8* %0, i8** %agg_addr.0, align 8<br>  %agg_addr.1 = getelementptr inbounds %0* %agg_addr, i32 0, i32 1<br>  store i64 %1, i64* %agg_addr.1, align 8<br>
  ret void <br>}<br><br>define i64 @call_by_pointer() {<br>
  %a_ptr = alloca float, align 4<br>
  %a_opq = bitcast float* %a_ptr to i8*<br>
  %agg_addr = alloca %0, align 8<br>
  call void @foo_by_pointer(%0* %agg_addr, i8* %a_opq, i64 4)  <br>
  %agg_addr.1 = getelementptr inbounds %0* %agg_addr, i32 0, i32 1<br>
  %result.1 = load i64* %agg_addr.1, align 8<br>
  ret i64 %result.1<br>
}<br><br>(2) Pass the struct by value (minor modifications on above code). <br>The only difference is that we build the structure inside callee @foo_by_value<br>and pass it by value to the caller @call_by_value. The returned value of  <br>
@call_by_value is a random number on windows XP ia32. But on linux<br>ubuntu x64 it is correct, 4. <br><br>define %0 @foo_by_value(i8*, i64) nounwind {<br>entry:<br>  %agg_addr = alloca %0, align 8<br>  %agg_addr.0 = getelementptr inbounds %0* %agg_addr, i32 0, i32 0<br>
  store i8* %0, i8** %agg_addr.0, align 8<br>  %agg_addr.1 = getelementptr inbounds %0* %agg_addr, i32 0, i32 1<br>  store i64 %1, i64* %agg_addr.1, align 8<br>  %result = load %0* %agg_addr, align 8<br>  ret %0 %result<br>
}<br><br>define i64 @call_by_value() {<br>  %a_ptr = alloca float, align 4<br>  %a_opq = bitcast float* %a_ptr to i8*<br>  %result = call %0 @foo_by_value(i8* %a_opq, i64 4)<br>  %agg_addr = alloca %0, align 8<br>  store %0 %result, %0* %agg_addr, align 8<br>
  %agg_addr.1 = getelementptr inbounds %0* %agg_addr, i32 0, i32 1  <br>  %result.1 = load i64* %agg_addr.1, align 8<br>  ret i64 %result.1<br>}<br><br>Is this a LLVM bug? Or call_by_value with foo_by_valye is invalid LLVM code? <br>
<br>Thanks,<br><br>Wei<br><br>