diff options
author | Tim Northover <tnorthover@apple.com> | 2014-03-29 15:09:45 +0000 |
---|---|---|
committer | Tim Northover <tnorthover@apple.com> | 2014-03-29 15:09:45 +0000 |
commit | a2ee433c8d99632419d4a13a66cc4d06eada4014 (patch) | |
tree | e6ab2db8facbc4c5ed2fb11df260db8138572ace /clang/test/CodeGenCXX | |
parent | af3698066a1ea2e5ab4cc08ae9a59620cf18adb7 (diff) | |
download | bcm5719-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.cpp | 19 | ||||
-rw-r--r-- | clang/test/CodeGenCXX/arm64-darwinpcs.cpp | 15 | ||||
-rw-r--r-- | clang/test/CodeGenCXX/arm64-empty-struct.cpp | 27 | ||||
-rw-r--r-- | clang/test/CodeGenCXX/arm64.cpp | 88 | ||||
-rw-r--r-- | clang/test/CodeGenCXX/empty-nontrivially-copyable.cpp | 1 | ||||
-rw-r--r-- | clang/test/CodeGenCXX/mangle-neon-vectors.cpp | 43 | ||||
-rw-r--r-- | clang/test/CodeGenCXX/poly-unsigned.cpp | 20 |
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; +} |