Paul Robinson | d30e2ee | 2015-07-14 20:52:32 +0000 | [diff] [blame] | 1 | // TLS variable cannot be aligned to more than 32 bytes on PS4. |
| 2 | |
| 3 | // RUN: %clang_cc1 -triple x86_64-scei-ps4 -fsyntax-only -verify %s |
| 4 | |
| 5 | |
| 6 | // A non-aligned type. |
| 7 | struct non_aligned_struct { |
| 8 | int some_data[16]; // 64 bytes of stuff, non aligned. |
| 9 | }; |
| 10 | |
| 11 | // An aligned type. |
| 12 | struct __attribute__(( aligned(64) )) aligned_struct { |
| 13 | int some_data[12]; // 48 bytes of stuff, aligned to 64. |
| 14 | }; |
| 15 | |
| 16 | // A type with an aligned field. |
| 17 | struct struct_with_aligned_field { |
| 18 | int some_aligned_data[12] __attribute__(( aligned(64) )); // 48 bytes of stuff, aligned to 64. |
| 19 | }; |
| 20 | |
| 21 | // A typedef of the aligned struct. |
| 22 | typedef aligned_struct another_aligned_struct; |
| 23 | |
| 24 | // A typedef to redefine a non-aligned struct as aligned. |
| 25 | typedef __attribute__(( aligned(64) )) non_aligned_struct yet_another_aligned_struct; |
| 26 | |
| 27 | // Non aligned variable doesn't cause an error. |
| 28 | __thread non_aligned_struct foo; |
| 29 | |
| 30 | // Variable aligned because of its type should cause an error. |
| 31 | __thread aligned_struct bar; // expected-error{{alignment (64) of thread-local variable}} |
| 32 | |
| 33 | // Variable explicitly aligned in the declaration should cause an error. |
| 34 | __thread non_aligned_struct bar2 __attribute__(( aligned(64) )); // expected-error{{alignment (64) of thread-local variable}} |
| 35 | |
| 36 | // Variable aligned because of one of its fields should cause an error. |
| 37 | __thread struct_with_aligned_field bar3; // expected-error{{alignment (64) of thread-local variable}} |
| 38 | |
| 39 | // Variable aligned because of typedef, first case. |
| 40 | __thread another_aligned_struct bar4; // expected-error{{alignment (64) of thread-local variable}} |
| 41 | |
| 42 | // Variable aligned because of typedef, second case. |
| 43 | __thread yet_another_aligned_struct bar5; // expected-error{{alignment (64) of thread-local variable}} |
| 44 | |
| 45 | int baz () |
| 46 | { |
| 47 | return foo.some_data[0] + bar.some_data[1] + bar2.some_data[2] + |
| 48 | bar3.some_aligned_data[3] + bar4.some_data[4] + |
| 49 | bar5.some_data[5]; |
| 50 | } |
| 51 | |
| 52 | |
| 53 | // Verify alignment check where a dependent type is involved. |
| 54 | // The check is (correctly) not performed on "t", but the check still is |
| 55 | // performed on the structure as a whole once it has been instantiated. |
| 56 | |
| 57 | template<class T> struct templated_tls { |
| 58 | static __thread T t; |
| 59 | T other_t __attribute__(( aligned(64) )); |
| 60 | }; |
| 61 | __thread templated_tls<int> blah; // expected-error{{alignment (64) of thread-local variable}} |
| 62 | |
| 63 | int blag() { |
| 64 | return blah.other_t * 2; |
| 65 | } |
| 66 | |
| 67 | |
| 68 | // Verify alignment check where the alignment is a template parameter. |
| 69 | // The check is only performed during instantiation. |
| 70 | template <int N> |
| 71 | struct S { |
| 72 | static int __thread __attribute__((aligned(N))) x; // expected-error{{alignment (64) of thread-local variable}} |
| 73 | }; |
| 74 | |
| 75 | S<64> s_instance; // expected-note{{in instantiation of template class 'S<64>' requested here}} |