diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2019-01-19 10:04:05 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2019-01-19 10:04:05 +0000 |
commit | 676fbe8105eeb6ff4bb2ed261cb212fcfdbe7b63 (patch) | |
tree | 02a1ac369cb734d0abfa5000dd86e5b7797e6a74 /test/CodeGen/arc | |
parent | c7e70c433efc6953dc3888b9fbf9f3512d7da2b0 (diff) |
Notes
Diffstat (limited to 'test/CodeGen/arc')
-rw-r--r-- | test/CodeGen/arc/arguments.c | 135 | ||||
-rw-r--r-- | test/CodeGen/arc/struct-align.c | 26 |
2 files changed, 161 insertions, 0 deletions
diff --git a/test/CodeGen/arc/arguments.c b/test/CodeGen/arc/arguments.c new file mode 100644 index 0000000000000..fdc6037da730a --- /dev/null +++ b/test/CodeGen/arc/arguments.c @@ -0,0 +1,135 @@ +// RUN: %clang_cc1 -triple arc-unknown-unknown %s -emit-llvm -o - \ +// RUN: | FileCheck %s + +// Basic argument tests for ARC. + +// CHECK: define void @f0(i32 inreg %i, i32 inreg %j, i64 inreg %k) +void f0(int i, long j, long long k) {} + +typedef struct { + int aa; + int bb; +} s1; +// CHECK: define void @f1(i32 inreg %i.coerce0, i32 inreg %i.coerce1) +void f1(s1 i) {} + +typedef struct { + char aa; char bb; char cc; char dd; +} cs1; +// CHECK: define void @cf1(i32 inreg %i.coerce) +void cf1(cs1 i) {} + +typedef struct { + int cc; +} s2; +// CHECK: define void @f2(%struct.s2* noalias sret %agg.result) +s2 f2() { + s2 foo; + return foo; +} + +typedef struct { + int cc; + int dd; +} s3; +// CHECK: define void @f3(%struct.s3* noalias sret %agg.result) +s3 f3() { + s3 foo; + return foo; +} + +// CHECK: define void @f4(i64 inreg %i) +void f4(long long i) {} + +// CHECK: define void @f5(i8 inreg signext %a, i16 inreg signext %b) +void f5(signed char a, short b) {} + +// CHECK: define void @f6(i8 inreg zeroext %a, i16 inreg zeroext %b) +void f6(unsigned char a, unsigned short b) {} + +enum my_enum { + ENUM1, + ENUM2, + ENUM3, +}; +// Enums should be treated as the underlying i32. +// CHECK: define void @f7(i32 inreg %a) +void f7(enum my_enum a) {} + +enum my_big_enum { + ENUM4 = 0xFFFFFFFFFFFFFFFF, +}; +// Big enums should be treated as the underlying i64. +// CHECK: define void @f8(i64 inreg %a) +void f8(enum my_big_enum a) {} + +union simple_union { + int a; + char b; +}; +// Unions should be passed inreg. +// CHECK: define void @f9(i32 inreg %s.coerce) +void f9(union simple_union s) {} + +typedef struct { + int b4 : 4; + int b3 : 3; + int b8 : 8; +} bitfield1; +// Bitfields should be passed inreg. +// CHECK: define void @f10(i32 inreg %bf1.coerce) +void f10(bitfield1 bf1) {} + +// CHECK: define inreg { float, float } @cplx1(float inreg %r) +_Complex float cplx1(float r) { + return r + 2.0fi; +} + +// CHECK: define inreg { double, double } @cplx2(double inreg %r) +_Complex double cplx2(double r) { + return r + 2.0i; +} + +// CHECK: define inreg { i32, i32 } @cplx3(i32 inreg %r) +_Complex int cplx3(int r) { + return r + 2i; +} + +// CHECK: define inreg { i64, i64 } @cplx4(i64 inreg %r) +_Complex long long cplx4(long long r) { + return r + 2i; +} + +// CHECK: define inreg { i8, i8 } @cplx6(i8 inreg signext %r) +_Complex signed char cplx6(signed char r) { + return r + 2i; +} + +// CHECK: define inreg { i16, i16 } @cplx7(i16 inreg signext %r) +_Complex short cplx7(short r) { + return r + 2i; +} + +typedef struct { + int aa; int bb; +} s8; + +typedef struct { + int aa; int bb; int cc; int dd; +} s16; + +// Use 16-byte struct 2 times, gets 8 registers. +void st2(s16 a, s16 b) {} +// CHECK: define void @st2(i32 inreg %a.coerce0, i32 inreg %a.coerce1, i32 inreg %a.coerce2, i32 inreg %a.coerce3, i32 inreg %b.coerce0, i32 inreg %b.coerce1, i32 inreg %b.coerce2, i32 inreg %b.coerce3) + +// Use 8-byte struct 3 times, gets 8 registers, 1 byval struct argument. +void st3(s16 a, s16 b, s16 c) {} +// CHECK: define void @st3(i32 inreg %a.coerce0, i32 inreg %a.coerce1, i32 inreg %a.coerce2, i32 inreg %a.coerce3, i32 inreg %b.coerce0, i32 inreg %b.coerce1, i32 inreg %b.coerce2, i32 inreg %b.coerce3, { i32, i32, i32, i32 } %c.coerce) + +// 1 sret + 1 i32 + 2*(i32 coerce) + 4*(i32 coerce) + 1 byval +s16 st4(int x, s8 a, s16 b, s16 c) { return b; } +// CHECK: define void @st4(%struct.s16* noalias sret %agg.result, i32 inreg %x, i32 inreg %a.coerce0, i32 inreg %a.coerce1, i32 inreg %b.coerce0, i32 inreg %b.coerce1, i32 inreg %b.coerce2, i32 inreg %b.coerce3, { i32, i32, i32, i32 } %c.coerce) + +// 1 sret + 2*(i32 coerce) + 4*(i32 coerce) + 4*(i32 coerce) +s16 st5(s8 a, s16 b, s16 c) { return b; } +// CHECK: define void @st5(%struct.s16* noalias sret %agg.result, i32 inreg %a.coerce0, i32 inreg %a.coerce1, i32 inreg %b.coerce0, i32 inreg %b.coerce1, i32 inreg %b.coerce2, i32 inreg %b.coerce3, { i32, i32, i32, i32 } %c.coerce) diff --git a/test/CodeGen/arc/struct-align.c b/test/CodeGen/arc/struct-align.c new file mode 100644 index 0000000000000..2aa7e7fc47ee8 --- /dev/null +++ b/test/CodeGen/arc/struct-align.c @@ -0,0 +1,26 @@ +// RUN: %clang_cc1 -triple arc-unknown-unknown %s -emit-llvm -o - \ +// RUN: | FileCheck %s + +// 64-bit fields need only be 32-bit aligned for arc. + +typedef struct { + int aa; + double bb; +} s1; + +// CHECK: define i32 @f1 +// CHECK: ret i32 12 +int f1() { + return sizeof(s1); +} + +typedef struct { + int aa; + long long bb; +} s2; +// CHECK: define i32 @f2 +// CHECK: ret i32 12 +int f2() { + return sizeof(s2); +} + |