-
Notifications
You must be signed in to change notification settings - Fork 15.2k
Description
| Bugzilla Link | 2230 |
| Resolution | FIXED |
| Resolved on | Apr 18, 2008 15:57 |
| Version | trunk |
| OS | All |
| CC | @asl |
Extended Description
For this testcase:
#include <stdarg.h>
void foo(va_list *a, va_list *b) {
va_copy(*a, *b);
}
llvm-gcc -m64 emits this:
define void @foo([1 x %struct.__va_list_tag]* %a, [1 x %struct.__va_list_tag]* %b) nounwind {
entry:
%memtmp = alloca %struct.__va_list_tag*
%tmp1 = getelementptr [1 x %struct.__va_list_tag]* %b, i32 0, i32 0
store %struct.__va_list_tag* %tmp1, %struct.__va_list_tag** %memtmp
%tmp234 = bitcast [1 x %struct.__va_list_tag]* %a to i8*
%memtmp5 = bitcast %struct.__va_list_tag** %memtmp to i8*
call void @llvm.va_copy( i8* %tmp234, i8* %memtmp5 )
ret void
}
It's storing the second argument to a stack location, and passing the address
of that location to @llvm.va_copy instead of passing the value of the second
argument itself.
The LLVM Language Reference entry for va_copy says that
"The second argument is a pointer to a va_list element to copy from."
As it happens, LLVM codegen is currently compensating for this bug by
performing an extra load on the second argument. As a result, the llvm-gcc
compiler produces correct code, but the intermediate form is incorrect and
other frontends won't work properly.