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