[PATCH v2] LangRef: clarify that va_arg doesn't work on x86_64
Ramkumar Ramachandra
artagnon at gmail.com
Wed Oct 29 13:10:48 PDT 2014
Hi Tim,
Tim Northover wrote:
> I'm actually still unconvinced by the need to call out x86_64
> specifically (especially having discovered that there *is* partial
> support for "va_arg"). I'd just go for something like "Note that not
> all targets support the va_arg instruction".
The example in LangRef actually crashes on my x86_64 machine, and this
is the problem I'm trying to fix for others. Should we replace it with
a working example on x86_64 like:
-- 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*
call void @llvm.va_start(i8* %ap2)
; Read a single integer argument
%tmp = va_arg %struct.__va_list_tag* %ap, i32
; Demonstrate usage of llvm.va_copy and llvm.va_end
%aq = alloca %struct.__va_list_tag
%aq2 = bitcast %struct.__va_list_tag* %aq to i8*
call void @llvm.va_copy(i8* %aq2, i8* %ap2)
call void @llvm.va_end(i8* %aq2)
; Stop processing of arguments.
call void @llvm.va_end(i8* %ap2)
ret i32 %tmp
}
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< --
If the user tries to read anything other than a builtin type, LLVM
will error out. Are we okay with a minimal working example?
> On 29 October 2014 12:21, Ramkumar Ramachandra <artagnon at gmail.com> wrote:
>> -This example shows how the :ref:`va_arg <i_va_arg>` instruction and the
>> -variable argument handling intrinsic functions are used.
>> +This example shows how the :ref:`va_arg <i_va_arg>` instruction and
>> +the variable argument handling intrinsic functions are used. Note that
>> +this is for platforms where ``va_list`` is an ``i8**``, most notably
>> +not x86_64.
>
> This isn't quite right. As far as I know (x86, ARM, AArch64) all
> in-tree targets that accept va_arg use it with an i8**, but with
> certain caveats (around type lowering & alignment in particular) even
> the x86_64 ABI could be supported. In fact, X86 actually seems to
> support certain common cases.
Do you mean that the va_list on those platforms is something other
than i8**, but the varargs mechanism exposes a pseudo i8** interface?
> It's just rather easier and more efficient to do it in Clang -- the
> optimisation passes can be rather useful for simplifying the special
> cases.
True, but wouldn't it be nice to support the common cases for people
starting out?
In any case, it would be nice to have the vaarg intricacies of x86_64
documented somewhere (like "look in the other i8* if reading over 40
bits").
Cheers.
Ram
More information about the llvm-commits
mailing list