summaryrefslogtreecommitdiff
path: root/test/CodeGen/arc
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2019-01-19 10:04:05 +0000
committerDimitry Andric <dim@FreeBSD.org>2019-01-19 10:04:05 +0000
commit676fbe8105eeb6ff4bb2ed261cb212fcfdbe7b63 (patch)
tree02a1ac369cb734d0abfa5000dd86e5b7797e6a74 /test/CodeGen/arc
parentc7e70c433efc6953dc3888b9fbf9f3512d7da2b0 (diff)
Notes
Diffstat (limited to 'test/CodeGen/arc')
-rw-r--r--test/CodeGen/arc/arguments.c135
-rw-r--r--test/CodeGen/arc/struct-align.c26
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);
+}
+