You can do this.
You can figure out what the LLVM code is for sample C by copying and pasting the C code into LLVM's online demo at http://llvm.org/demo/index.cgi.
If you copy and paste the code at codepad.org in, you'll see that LLVM generates the following for myFunction:
define void @_Z10myFunction10MyStruct_t(i8* %myStructAsParam.coerce0, i32 %myStructAsParam.coerce1) nounwind uwtable {
%1 = tail call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([23 x i8]* @.str, i64 0, i64 0), i8* %myStructAsParam.coerce0, i32 %myStructAsParam.coerce1)
ret void
}
Of course, if you look at the call you'll notice that no copy is being made. It's up to the calling function to do that. If we write a small C function:
void myCallingFunction(MyStruct_t *foobar)
{
myFunction(*foobar);
}
We can see that the LLVM bitcode generated for myCallingFunction is:
define void @_Z17myCallingFunctionP10MyStruct_t(%struct.MyStruct_t* nocapture %foobar) nounwind uwtable {
%foobar.0 = getelementptr inbounds %struct.MyStruct_t* %foobar, i64 0, i32 0
%tmp = load i8** %foobar.0, align 8
%foobar.1 = getelementptr inbounds %struct.MyStruct_t* %foobar, i64 0, i32 1
%tmp1 = load i32* %foobar.1, align 8
%1 = tail call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([23 x i8]* @.str, i64 0, i64 0), i8* %tmp, i32 %tmp1) nounwind
ret void
}
The calling function makes a copy of the struct, and then passes in the address of the copy.