diff options
Diffstat (limited to 'test/CodeGen/x86_64-arguments.c')
-rw-r--r-- | test/CodeGen/x86_64-arguments.c | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/test/CodeGen/x86_64-arguments.c b/test/CodeGen/x86_64-arguments.c index f73e1f0..518ee84 100644 --- a/test/CodeGen/x86_64-arguments.c +++ b/test/CodeGen/x86_64-arguments.c @@ -354,3 +354,41 @@ void test46() { v46 x = {1,2}; f46(x,x,x,x,x,x,x,x,x,x); } struct s47 { unsigned a; }; void f47(int,int,int,int,int,int,struct s47); void test47(int a, struct s47 b) { f47(a, a, a, a, a, a, b); } + +// rdar://12723368 +// In the following example, there are holes in T4 at the 3rd byte and the 4th +// byte, however, T2 does not have those holes. T4 is chosen to be the +// representing type for union T1, but we can't use load or store of T4 since +// it will skip the 3rd byte and the 4th byte. +// In general, Since we don't accurately represent the data fields of a union, +// do not use load or store of the representing llvm type for the union. +typedef _Complex int T2; +typedef _Complex char T5; +typedef _Complex int T7; +typedef struct T4 { T5 field0; T7 field1; } T4; +typedef union T1 { T2 field0; T4 field1; } T1; +extern T1 T1_retval; +T1 test48(void) { +// CHECK: @test48 +// CHECK: memcpy +// CHECK: memcpy + return T1_retval; +} + +void test49_helper(double, ...); +void test49(double d, double e) { + test49_helper(d, e); +} +// CHECK: define void @test49( +// CHECK: [[T0:%.*]] = load double* +// CHECK-NEXT: [[T1:%.*]] = load double* +// CHECK-NEXT: call void (double, ...)* @test49_helper(double [[T0]], double [[T1]]) + +void test50_helper(); +void test50(double d, double e) { + test50_helper(d, e); +} +// CHECK: define void @test50( +// CHECK: [[T0:%.*]] = load double* +// CHECK-NEXT: [[T1:%.*]] = load double* +// CHECK-NEXT: call void (double, double, ...)* bitcast (void (...)* @test50_helper to void (double, double, ...)*)(double [[T0]], double [[T1]]) |