[LLVMdev] Returning a structure

Rob Rix rob at monochromeindustries.com
Tue Jan 26 13:52:40 PST 2010


I’m using the C API (with a few additions in a single cpp file) to write a compiler. In one part of my code, I want to build a function that returns a structure. The LLVM Assembly Language Reference Manual gives this as a possible return value:

> ret { i32, i8 } { i32 4, i8 2 }

Meanwhile, compiling this C function:

> Range make_range(Index location, Index length) {
> 	return (Range){ location, length };
> }

reveals clang’s IR output to be quite a bit more complex:

> 	%struct._Range = type <{ i64, i64 }>
> 
> define void @make_range(%struct._Range* noalias sret %agg.result, i64 %location, i64 %length) nounwind {
> 	%1 = alloca %struct._Range		; <%struct._Range*> [#uses=2]
> 	%location.addr = alloca i64		; <i64*> [#uses=2]
> 	%length.addr = alloca i64		; <i64*> [#uses=2]
> 	%range = alloca %struct._Range, align 4		; <%struct._Range*> [#uses=3]
> 	store i64 %location, i64* %location.addr
> 	store i64 %length, i64* %length.addr
> 	%2 = getelementptr %struct._Range* %range, i32 0, i32 0		; <i64*> [#uses=1]
> 	%3 = load i64* %location.addr		; <i64> [#uses=1]
> 	store i64 %3, i64* %2
> 	%4 = getelementptr %struct._Range* %range, i32 0, i32 1		; <i64*> [#uses=1]
> 	%5 = load i64* %length.addr		; <i64> [#uses=1]
> 	store i64 %5, i64* %4
> 	%6 = bitcast %struct._Range* %1 to i8*		; <i8*> [#uses=1]
> 	%7 = bitcast %struct._Range* %range to i8*		; <i8*> [#uses=1]
> 	call void @llvm.memcpy.i32(i8* %6, i8* %7, i32 16, i32 4)
> 	%8 = bitcast %struct._Range* %agg.result to i8*		; <i8*> [#uses=1]
> 	%9 = bitcast %struct._Range* %1 to i8*		; <i8*> [#uses=1]
> 	call void @llvm.memcpy.i32(i8* %8, i8* %9, i32 16, i32 4)
> 	ret void
> }


If the Range type’s fields are i32 instead, then it returns a single i64 directly.

Returning a structure packed into a single i64 value or by reference in an argument would seem to be details of the platform’s ABI. Does my compiler really need to be aware of these details, or can I just return a structure as per the documentation quoted above?

If the latter case, how do I build that instruction with the builder? Attempts to use LLVMConstStruct are crashing, I assume because the arguments to it in my use are not actually constants (: A quick search through IRBuilder didn’t give me any clues either, so here I am (:

Thanks in advance for any help you can give me,

Sincerely,
Rob

--
Rob Rix, Unknown Quantity
Monochrome Industries





More information about the llvm-dev mailing list