[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