2014-01-23 04:11:01 +08:00
|
|
|
// RUN: %clang_cc1 -triple le32-unknown-nacl -emit-llvm -o - %s | FileCheck %s
|
|
|
|
#include <stdarg.h>
|
|
|
|
|
|
|
|
int get_int(va_list *args) {
|
|
|
|
return va_arg(*args, int);
|
|
|
|
}
|
|
|
|
// CHECK: define i32 @get_int
|
|
|
|
// CHECK: [[RESULT:%[a-z_0-9]+]] = va_arg {{.*}}, i32{{$}}
|
Default vaarg lowering should support indirect struct types.
Fixes PR11517 for SPARC.
On most targets, clang lowers va_arg itself, eschewing the use of the
llvm vaarg instruction. This is necessary (at least for now) as the type
argument to the vaarg instruction cannot represent all the ABI
information that is needed to support complex calling conventions.
However, on targets with a simpler varrags ABIs, the LLVM instruction
can work just fine, and clang can simply lower to it. Unfortunately,
even on such targets, vaarg with a struct argument would fail, because
the default lowering to vaarg was naive: it didn't take into account the
ABI attribute computed by classifyArgumentType. In particular, for the
DefaultABIInfo, structs are supposed to be passed indirectly and so
llvm's vaarg instruction should be emitted with a pointer argument.
Now, vaarg instruction emission is able to use computed ABIArgInfo for
the provided argument type, which allows the default ABI support to work
for structs too.
I haven't touched the EmitVAArg implementation for PPC32_SVR4 or XCore,
although I believe both are now redundant, and could be switched over to
use the default implementation as well.
Differential Revision: http://reviews.llvm.org/D16154
llvm-svn: 261717
2016-02-24 10:59:33 +08:00
|
|
|
// CHECK: store i32 [[RESULT]], i32* [[LOC:%[a-z_0-9]+]]
|
|
|
|
// CHECK: [[RESULT2:%[a-z_0-9]+]] = load i32, i32* [[LOC]]
|
|
|
|
// CHECK: ret i32 [[RESULT2]]
|
2014-01-23 04:11:01 +08:00
|
|
|
|
|
|
|
struct Foo {
|
|
|
|
int x;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct Foo dest;
|
|
|
|
|
|
|
|
void get_struct(va_list *args) {
|
|
|
|
dest = va_arg(*args, struct Foo);
|
|
|
|
}
|
|
|
|
// CHECK: define void @get_struct
|
|
|
|
// CHECK: [[RESULT:%[a-z_0-9]+]] = va_arg {{.*}}, %struct.Foo{{$}}
|
Default vaarg lowering should support indirect struct types.
Fixes PR11517 for SPARC.
On most targets, clang lowers va_arg itself, eschewing the use of the
llvm vaarg instruction. This is necessary (at least for now) as the type
argument to the vaarg instruction cannot represent all the ABI
information that is needed to support complex calling conventions.
However, on targets with a simpler varrags ABIs, the LLVM instruction
can work just fine, and clang can simply lower to it. Unfortunately,
even on such targets, vaarg with a struct argument would fail, because
the default lowering to vaarg was naive: it didn't take into account the
ABI attribute computed by classifyArgumentType. In particular, for the
DefaultABIInfo, structs are supposed to be passed indirectly and so
llvm's vaarg instruction should be emitted with a pointer argument.
Now, vaarg instruction emission is able to use computed ABIArgInfo for
the provided argument type, which allows the default ABI support to work
for structs too.
I haven't touched the EmitVAArg implementation for PPC32_SVR4 or XCore,
although I believe both are now redundant, and could be switched over to
use the default implementation as well.
Differential Revision: http://reviews.llvm.org/D16154
llvm-svn: 261717
2016-02-24 10:59:33 +08:00
|
|
|
// CHECK: store %struct.Foo [[RESULT]], %struct.Foo* [[LOC:%[a-z_0-9]+]]
|
|
|
|
// CHECK: [[LOC2:%[a-z_0-9]+]] = bitcast {{.*}} [[LOC]] to i8*
|
|
|
|
// CHECK: call void @llvm.memcpy{{.*}}@dest{{.*}}, i8* [[LOC2]]
|
2014-01-23 04:11:01 +08:00
|
|
|
|
|
|
|
void skip_struct(va_list *args) {
|
|
|
|
va_arg(*args, struct Foo);
|
|
|
|
}
|
|
|
|
// CHECK: define void @skip_struct
|
|
|
|
// CHECK: va_arg {{.*}}, %struct.Foo{{$}}
|