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