diff options
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; +} |