summaryrefslogtreecommitdiffstats
path: root/clang/test/CodeGenCXX
diff options
context:
space:
mode:
authorTim Northover <tnorthover@apple.com>2014-03-29 15:09:45 +0000
committerTim Northover <tnorthover@apple.com>2014-03-29 15:09:45 +0000
commita2ee433c8d99632419d4a13a66cc4d06eada4014 (patch)
treee6ab2db8facbc4c5ed2fb11df260db8138572ace /clang/test/CodeGenCXX
parentaf3698066a1ea2e5ab4cc08ae9a59620cf18adb7 (diff)
downloadbcm5719-llvm-a2ee433c8d99632419d4a13a66cc4d06eada4014.tar.gz
bcm5719-llvm-a2ee433c8d99632419d4a13a66cc4d06eada4014.zip
ARM64: initial clang support commit.
This adds Clang support for the ARM64 backend. There are definitely still some rough edges, so please bring up any issues you see with this patch. As with the LLVM commit though, we think it'll be more useful for merging with AArch64 from within the tree. llvm-svn: 205100
Diffstat (limited to 'clang/test/CodeGenCXX')
-rw-r--r--clang/test/CodeGenCXX/arm64-constructor-return.cpp19
-rw-r--r--clang/test/CodeGenCXX/arm64-darwinpcs.cpp15
-rw-r--r--clang/test/CodeGenCXX/arm64-empty-struct.cpp27
-rw-r--r--clang/test/CodeGenCXX/arm64.cpp88
-rw-r--r--clang/test/CodeGenCXX/empty-nontrivially-copyable.cpp1
-rw-r--r--clang/test/CodeGenCXX/mangle-neon-vectors.cpp43
-rw-r--r--clang/test/CodeGenCXX/poly-unsigned.cpp20
7 files changed, 209 insertions, 4 deletions
diff --git a/clang/test/CodeGenCXX/arm64-constructor-return.cpp b/clang/test/CodeGenCXX/arm64-constructor-return.cpp
new file mode 100644
index 00000000000..0d5b3b38258
--- /dev/null
+++ b/clang/test/CodeGenCXX/arm64-constructor-return.cpp
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 %s -triple=arm64-apple-ios7.0.0 -emit-llvm -o - | FileCheck %s
+// rdar://12162905
+
+struct S {
+ S();
+ int iField;
+};
+
+S::S() {
+ iField = 1;
+};
+
+// CHECK: %struct.S* @_ZN1SC2Ev(%struct.S* returned %this)
+
+// CHECK: %struct.S* @_ZN1SC1Ev(%struct.S* returned %this)
+// CHECK: [[THISADDR:%[a-zA-z0-9.]+]] = alloca %struct.S*
+// CHECK: store %struct.S* %this, %struct.S** [[THISADDR]]
+// CHECK: [[THIS1:%.*]] = load %struct.S** [[THISADDR]]
+// CHECK: ret %struct.S* [[THIS1]]
diff --git a/clang/test/CodeGenCXX/arm64-darwinpcs.cpp b/clang/test/CodeGenCXX/arm64-darwinpcs.cpp
new file mode 100644
index 00000000000..0a0ec3af49c
--- /dev/null
+++ b/clang/test/CodeGenCXX/arm64-darwinpcs.cpp
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -triple arm64-linux-gnu -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple arm64-linux-gnu -emit-llvm -o - %s -target-abi darwinpcs | FileCheck %s --check-prefix=CHECK-DARWIN
+
+void test_extensions(bool a, char b, short c) {}
+// CHECK: define void @_Z15test_extensionsbcs(i1 %a, i8 %b, i16 %c)
+// CHECK-DARWIN: define void @_Z15test_extensionsbcs(i1 zeroext %a, i8 signext %b, i16 signext %c)
+
+struct Empty {};
+void test_empty(Empty e) {}
+// CHECK: define void @_Z10test_empty5Empty(i8
+// CHECK-DARWIN: define void @_Z10test_empty5Empty()
+
+struct HFA {
+ float a[3];
+};
diff --git a/clang/test/CodeGenCXX/arm64-empty-struct.cpp b/clang/test/CodeGenCXX/arm64-empty-struct.cpp
new file mode 100644
index 00000000000..6fa4e95295b
--- /dev/null
+++ b/clang/test/CodeGenCXX/arm64-empty-struct.cpp
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -triple arm64-apple-ios -target-abi darwinpcs -emit-llvm -o - %s | FileCheck %s
+struct Empty {};
+
+Empty emptyvar;
+
+int take_args(int a, ...) {
+ __builtin_va_list l;
+ __builtin_va_start(l, a);
+// CHECK: call void @llvm.va_start
+
+ emptyvar = __builtin_va_arg(l, Empty);
+// CHECK: load i8**
+// CHECK-NOT: getelementptr
+// CHECK: [[EMPTY_PTR:%[a-zA-Z0-9._]+]] = bitcast i8* {{%[a-zA-Z0-9._]+}} to %struct.Empty*
+
+ // It's conceivable that EMPTY_PTR may not actually be a valid pointer
+ // (e.g. it's at the very bottom of the stack and the next page is
+ // invalid). This doesn't matter provided it's never loaded (there's no
+ // well-defined way to tell), but it becomes a problem if we do try to use it.
+// CHECK-NOT: load %struct.Empty* [[EMPTY_PTR]]
+
+ int i = __builtin_va_arg(l, int);
+// CHECK: va_arg i8** {{%[a-zA-Z0-9._]+}}, i32
+
+ __builtin_va_end(l);
+ return i;
+}
diff --git a/clang/test/CodeGenCXX/arm64.cpp b/clang/test/CodeGenCXX/arm64.cpp
new file mode 100644
index 00000000000..d0d4f4f70ef
--- /dev/null
+++ b/clang/test/CodeGenCXX/arm64.cpp
@@ -0,0 +1,88 @@
+// RUN: %clang_cc1 %s -triple=arm64-apple-ios -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 %s -triple=arm64-apple-ios -emit-llvm -o - | FileCheck -check-prefix=CHECK-GLOBALS %s
+
+// __cxa_guard_acquire argument is 64-bit
+// rdar://11540122
+struct A {
+ A();
+};
+
+void f() {
+ // CHECK: call i32 @__cxa_guard_acquire(i64*
+ static A a;
+}
+
+// ARM64 uses the C++11 definition of POD.
+// rdar://12650514
+namespace test1 {
+ // This class is POD in C++11 and cannot have objects allocated in
+ // its tail-padding.
+ struct ABase {};
+ struct A : ABase {
+ int x;
+ char c;
+ };
+
+ struct B : A {
+ char d;
+ };
+
+ int test() {
+ return sizeof(B);
+ }
+ // CHECK: define i32 @_ZN5test14testEv()
+ // CHECK: ret i32 12
+}
+
+namespace std {
+ class type_info;
+}
+
+// ARM64 uses string comparisons for what would otherwise be
+// default-visibility weak RTTI. rdar://12650568
+namespace test2 {
+ struct A {
+ virtual void foo();
+ };
+ void A::foo() {}
+ // Tested below because these globals get kindof oddly rearranged.
+
+ struct __attribute__((visibility("hidden"))) B {};
+ const std::type_info &b0 = typeid(B);
+ // CHECK-GLOBALS: @_ZTSN5test21BE = linkonce_odr hidden constant
+ // CHECK-GLOBALS: @_ZTIN5test21BE = linkonce_odr hidden constant { {{.*}}, i8* getelementptr inbounds ([11 x i8]* @_ZTSN5test21BE, i32 0, i32 0) }
+
+ const std::type_info &b1 = typeid(B*);
+ // CHECK-GLOBALS: @_ZTSPN5test21BE = linkonce_odr hidden constant
+ // CHECK-GLOBALS: @_ZTIPN5test21BE = linkonce_odr hidden constant { {{.*}}, i8* getelementptr inbounds ([12 x i8]* @_ZTSPN5test21BE, i32 0, i32 0), i32 0, i8* bitcast
+
+ struct C {};
+ const std::type_info &c0 = typeid(C);
+ // CHECK-GLOBALS: @_ZTSN5test21CE = linkonce_odr hidden constant
+ // CHECK-GLOBALS: @_ZTIN5test21CE = linkonce_odr hidden constant { {{.*}}, i8* inttoptr (i64 add (i64 ptrtoint ([11 x i8]* @_ZTSN5test21CE to i64), i64 -9223372036854775808) to i8*) }
+
+ const std::type_info &c1 = typeid(C*);
+ // CHECK-GLOBALS: @_ZTSPN5test21CE = linkonce_odr hidden constant
+ // CHECK-GLOBALS: @_ZTIPN5test21CE = linkonce_odr hidden constant { {{.*}}, i8* inttoptr (i64 add (i64 ptrtoint ([12 x i8]* @_ZTSPN5test21CE to i64), i64 -9223372036854775808) to i8*), i32 0, i8* bitcast
+
+ // This class is explicitly-instantiated, but that instantiation
+ // doesn't guarantee to emit RTTI, so we can still demote the visibility.
+ template <class T> class D {};
+ template class D<int>;
+ const std::type_info &d0 = typeid(D<int>);
+ // CHECK-GLOBALS: @_ZTSN5test21DIiEE = linkonce_odr hidden constant
+ // CHECK-GLOBALS: @_ZTIN5test21DIiEE = linkonce_odr hidden constant { {{.*}}, i8* inttoptr (i64 add (i64 ptrtoint ([14 x i8]* @_ZTSN5test21DIiEE to i64), i64 -9223372036854775808) to i8*) }
+
+ // This class is explicitly-instantiated and *does* guarantee to
+ // emit RTTI, so we're stuck with having to use default visibility.
+ template <class T> class E {
+ virtual void foo() {}
+ };
+ template class E<int>;
+ // CHECK-GLOBALS: @_ZTSN5test21EIiEE = weak_odr constant [14 x i8]
+ // CHECK-GLOBALS: @_ZTIN5test21EIiEE = weak_odr constant { {{.*}}, i8* inttoptr (i64 add (i64 ptrtoint ([14 x i8]* @_ZTSN5test21EIiEE to i64), i64 -9223372036854775808) to i8*) }
+
+ // CHECK-GLOBALS: @_ZTSN5test21AE = constant [11 x i8]
+ // CHECK-GLOBALS: @_ZTIN5test21AE = constant { {{.*}}, i8* getelementptr inbounds ([11 x i8]* @_ZTSN5test21AE, i32 0, i32 0) }
+
+}
diff --git a/clang/test/CodeGenCXX/empty-nontrivially-copyable.cpp b/clang/test/CodeGenCXX/empty-nontrivially-copyable.cpp
index 9ee3281505e..9457293ce46 100644
--- a/clang/test/CodeGenCXX/empty-nontrivially-copyable.cpp
+++ b/clang/test/CodeGenCXX/empty-nontrivially-copyable.cpp
@@ -1,4 +1,5 @@
// RUN: %clang_cc1 -triple armv7-apple-ios -x c++ -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple arm64-apple-ios -x c++ -emit-llvm -o - %s | FileCheck %s
// According to the Itanium ABI (3.1.1), types with non-trivial copy
// constructors passed by value should be passed indirectly, with the caller
diff --git a/clang/test/CodeGenCXX/mangle-neon-vectors.cpp b/clang/test/CodeGenCXX/mangle-neon-vectors.cpp
index 249ec2e99b6..a9d0b8d83c1 100644
--- a/clang/test/CodeGenCXX/mangle-neon-vectors.cpp
+++ b/clang/test/CodeGenCXX/mangle-neon-vectors.cpp
@@ -1,10 +1,18 @@
-// RUN: %clang_cc1 -triple arm-none-linux-gnueabi -target-feature +neon %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -triple armv7-apple-ios -target-feature +neon %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -triple arm64-apple-ios %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -triple arm64-linux-gnu %s -emit-llvm -o - | FileCheck %s --check-prefix=CHECK-AARCH64
typedef float float32_t;
+typedef double float64_t;
typedef __fp16 float16_t;
+#if defined(__aarch64__)
+typedef unsigned char poly8_t;
+typedef unsigned short poly16_t;
+#else
typedef signed char poly8_t;
typedef short poly16_t;
-typedef unsigned long long uint64_t;
+#endif
+typedef unsigned __INT64_TYPE__ uint64_t;
typedef __attribute__((neon_vector_type(2))) int int32x2_t;
typedef __attribute__((neon_vector_type(4))) int int32x4_t;
@@ -14,26 +22,53 @@ typedef __attribute__((neon_vector_type(2))) float32_t float32x2_t;
typedef __attribute__((neon_vector_type(4))) float32_t float32x4_t;
typedef __attribute__((neon_vector_type(4))) float16_t float16x4_t;
typedef __attribute__((neon_vector_type(8))) float16_t float16x8_t;
-typedef __attribute__((neon_polyvector_type(16))) poly8_t poly8x16_t;
-typedef __attribute__((neon_polyvector_type(8))) poly16_t poly16x8_t;
+#ifdef __aarch64__
+typedef __attribute__((neon_vector_type(2))) float64_t float64x2_t;
+#endif
+typedef __attribute__((neon_polyvector_type(16))) poly8_t poly8x16_t;
+typedef __attribute__((neon_polyvector_type(8))) poly16_t poly16x8_t;
// CHECK: 16__simd64_int32_t
+// CHECK-AARCH64: 11__Int32x2_t
void f1(int32x2_t v) { }
+
// CHECK: 17__simd128_int32_t
+// CHECK-AARCH64: 11__Int32x4_t
void f2(int32x4_t v) { }
+
// CHECK: 17__simd64_uint64_t
+// CHECK-AARCH64: 12__Uint64x1_t
void f3(uint64x1_t v) { }
+
// CHECK: 18__simd128_uint64_t
+// CHECK-AARCH64: 12__Uint64x2_t
void f4(uint64x2_t v) { }
+
// CHECK: 18__simd64_float32_t
+// CHECK-AARCH64: 13__Float32x2_t
void f5(float32x2_t v) { }
+
// CHECK: 19__simd128_float32_t
+// CHECK-AARCH64: 13__Float32x4_t
void f6(float32x4_t v) { }
+
// CHECK: 18__simd64_float16_t
+// CHECK-AARCH64: 13__Float16x4_t
void f7(float16x4_t v) {}
+
// CHECK: 19__simd128_float16_t
+// CHECK-AARCH64: 13__Float16x8_t
void f8(float16x8_t v) {}
+
// CHECK: 17__simd128_poly8_t
+// CHECK-AARCH64: 12__Poly8x16_t
void f9(poly8x16_t v) {}
+
// CHECK: 18__simd128_poly16_t
+// CHECK-AARCH64: 12__Poly16x8_t
void f10(poly16x8_t v) {}
+
+#ifdef __aarch64__
+// CHECK-AARCH64: 13__Float64x2_t
+void f11(float64x2_t v) { }
+#endif
diff --git a/clang/test/CodeGenCXX/poly-unsigned.cpp b/clang/test/CodeGenCXX/poly-unsigned.cpp
new file mode 100644
index 00000000000..9851a06089d
--- /dev/null
+++ b/clang/test/CodeGenCXX/poly-unsigned.cpp
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -triple arm64-apple-ios -ffreestanding -S -emit-llvm -o - %s | FileCheck --check-prefix=CHECK-UNSIGNED-POLY %s
+// RUN: %clang_cc1 -triple arm64-linux-gnu -ffreestanding -S -emit-llvm -o - %s | FileCheck --check-prefix=CHECK-UNSIGNED-POLY %s
+// RUN: %clang_cc1 -triple armv7-apple-ios -ffreestanding -target-cpu cortex-a8 -S -emit-llvm -o - %s | FileCheck --check-prefix=CHECK-SIGNED-POLY %s
+
+#include <arm_neon.h>
+
+// Polynomial types really should be universally unsigned, otherwise casting
+// (say) poly8_t "x^7" to poly16_t would change it to "x^15 + x^14 + ... +
+// x^7". Unfortunately 32-bit ARM ended up in a slightly delicate ABI situation
+// so for now it got that wrong.
+
+poly16_t test_poly8(poly8_t pIn) {
+// CHECK-UNSIGNED-POLY: @_Z10test_poly8h
+// CHECK-UNSIGNED-POLY: zext i8 {{.*}} to i16
+
+// CHECK-SIGNED-POLY: @_Z10test_poly8a
+// CHECK-SIGNED-POLY: sext i8 {{.*}} to i16
+
+ return pIn;
+}
OpenPOWER on IntegriCloud