[LLVMdev] [BUG] Varargs example in LangRef segfaults
Ramkumar Ramachandra
artagnon at gmail.com
Tue Aug 26 14:36:41 PDT 2014
So I've written out this sample based on what Clang emitted:
-- 8< --
%struct.__va_list_tag = type { i32, i32, i8*, i8* }
define i32 @test(i32 %X, ...) {
; Initialize variable argument processing
%ap = alloca %struct.__va_list_tag
%ap2 = bitcast %struct.__va_list_tag* %ap to i8*
%retptr = alloca i32
call void @llvm.va_start(i8* %ap2)
; Read a single integer argument
%idxptr = getelementptr inbounds %struct.__va_list_tag* %ap, i32 0, i32 0
%idx = load i32* %idxptr
%tmp = getelementptr inbounds %struct.__va_list_tag* %ap, i32 0, i32 3
%extract = load i8** %tmp
%rawel = getelementptr i8* %extract, i32 %idx
%elptr = bitcast i8* %rawel to i32*
%newidx = add i32 %idx, 8
store i32 %idx, i32* %idxptr
; Store that argument in el
%el = load i32* %elptr
store i32 %el, i32* %retptr
%ret = load i32* %retptr
; Stop processing of arguments.
call void @llvm.va_end(i8* %ap2)
ret i32 %ret
}
define i32 @main() {
%call = call i32 (i32, ...)* @test(i32 1, i32 3)
ret i32 %call
}
declare void @llvm.va_start(i8*)
declare void @llvm.va_copy(i8*, i8*)
declare void @llvm.va_end(i8*)
-- 8< --
Can we include (a neater version of) this in the LangRef? Can it not
be simplified?
I understand that %struct.__va_list_tag will be different for each
platform, so the user can't gep into the structure in a
platform-independent manner, but what's the problem with this?
%ap = alloca_va_list
%ap2 = bitcast %struct.__va_list_tag* %ap to i8*
call void @llvm.va_start(i8* %ap2)
va_arg %ap i32
call void @llvm.va_end(i8* %ap2)
All we need is a sort of global %struct.__va_list_tag, right?
More information about the llvm-dev
mailing list