xref: /llvm-project/clang/test/AST/ByteCode/vectors.cpp (revision 7802fb5f514be327576b69569556ec9096e5fdd7)
1 // RUN: %clang_cc1 -fexperimental-new-constant-interpreter -verify=expected,both %s
2 // RUN: %clang_cc1 -verify=ref,both %s
3 
4 typedef int __attribute__((vector_size(16))) VI4;
5 constexpr VI4 A = {1,2,3,4};
6 static_assert(A[0] == 1, "");
7 static_assert(A[1] == 2, "");
8 static_assert(A[2] == 3, "");
9 static_assert(A[3] == 4, "");
10 
11 
12 /// FIXME: It would be nice if the note said 'vector' instead of 'array'.
13 static_assert(A[12] == 4, ""); // both-error {{not an integral constant expression}} \
14                                // both-note {{cannot refer to element 12 of array of 4 elements in a constant expression}}
15 
16 
17 /// VectorSplat casts
18 typedef __attribute__(( ext_vector_type(4) )) float float4;
19 constexpr float4 vec4_0 = (float4)0.5f;
20 static_assert(vec4_0[0] == 0.5, "");
21 static_assert(vec4_0[1] == 0.5, "");
22 static_assert(vec4_0[2] == 0.5, "");
23 static_assert(vec4_0[3] == 0.5, "");
24 constexpr int vec4_0_discarded = ((float4)12.0f, 0);
25 
26 
27 /// ImplicitValueInitExpr of vector type
28 constexpr float4 arr4[2] = {
29   {1,2,3,4},
30 };
31 static_assert(arr4[0][0] == 1, "");
32 static_assert(arr4[0][1] == 2, "");
33 static_assert(arr4[0][2] == 3, "");
34 static_assert(arr4[0][3] == 4, "");
35 static_assert(arr4[1][0] == 0, "");
36 static_assert(arr4[1][0] == 0, "");
37 static_assert(arr4[1][0] == 0, "");
38 static_assert(arr4[1][0] == 0, "");
39 
40 constexpr VI4 B = __extension__(A);
41 
42 /// From constant-expression-cxx11.cpp
43 namespace Vector {
44   typedef int __attribute__((vector_size(16))) VI4;
45   constexpr VI4 f(int n) {
46     return VI4 { n * 3, n + 4, n - 5, n / 6 };
47   }
48   constexpr auto v1 = f(10);
49   static_assert(__builtin_vectorelements(v1) == (16 / sizeof(int)), "");
50 
51   typedef double __attribute__((vector_size(32))) VD4;
52   constexpr VD4 g(int n) {
53     return (VD4) { n / 2.0, n + 1.5, n - 5.4, n * 0.9 };
54   }
55   constexpr auto v2 = g(4);
56   static_assert(__builtin_vectorelements(v2) == (32 / sizeof(double)), "");
57 }
58 
59 namespace {
60   typedef float __attribute__((vector_size(16))) VI42;
61   constexpr VI42 A2 = A;
62 }
63 
64 namespace BoolToSignedIntegralCast{
65   typedef __attribute__((__ext_vector_type__(4))) unsigned int int4;
66   constexpr int4 intsT = (int4)true;
67   static_assert(intsT[0] == -1, "");
68   static_assert(intsT[1] == -1, "");
69   static_assert(intsT[2] == -1, "");
70   static_assert(intsT[3] == -1, "");
71 }
72 
73 namespace VectorElementExpr {
74   typedef int int2 __attribute__((ext_vector_type(2)));
75   typedef int int4 __attribute__((ext_vector_type(4)));
76   constexpr int oneElt = int4(3).x;
77   static_assert(oneElt == 3);
78 
79   constexpr int2 twoElts = ((int4){11, 22, 33, 44}).yz;
80   static_assert(twoElts.x == 22, "");
81   static_assert(twoElts.y == 33, "");
82 }
83 
84 namespace Temporaries {
85   typedef __attribute__((vector_size(16))) int vi4a;
86   typedef __attribute__((ext_vector_type(4))) int vi4b;
87   struct S {
88     vi4a v;
89     vi4b w;
90   };
91   int &&s = S().w[1];
92 }
93 
94 #ifdef __SIZEOF_INT128__
95 namespace bigint {
96   typedef __attribute__((__ext_vector_type__(4))) __int128 bigint4;
97   constexpr bigint4 A = (bigint4)true;
98   static_assert(A[0] == -1, "");
99   static_assert(A[1] == -1, "");
100   static_assert(A[2] == -1, "");
101   static_assert(A[3] == -1, "");
102 }
103 #endif
104 
105 using VI __attribute__((ext_vector_type(4))) = int;
106 
107 constexpr int a1() {
108     VI a = {0, 0, 0, 0};
109     VI b = {1,1,1,1};
110 
111     VI C = (a += b);
112 
113     return 0;
114 }
115 
116 static_assert(a1() == 0);
117 
118 constexpr int a2() {
119     VI a = {0, 0, 0, 0};
120     VI b = {1,1,1,1};
121 
122     VI C = (a + b);
123 
124     return 0;
125 }
126 
127 static_assert(a2() == 0);
128 
129 namespace {
130   /// convertvector expr with a per-element floating-point cast
131 
132   typedef float __m128 __attribute__((__vector_size__(16), __aligned__(16)));
133   typedef double __m128d __attribute__((__vector_size__(16), __aligned__(16)));
134   typedef float __v4sf __attribute__((__vector_size__(16)));
135   typedef double __v2df __attribute__((__vector_size__(16)));
136 
137   static inline constexpr __m128d
138   _mm_cvtps_pd(__m128 __a) {
139     return __builtin_convertvector(__builtin_shufflevector(__a, __a, 0, 1), __v2df);
140   }
141 
142   constexpr __m128 kf1 {-1.0f,+2.0f,-3.0f,+4.0f};
143   constexpr __m128d v_mm_cvtps_pd = _mm_cvtps_pd(kf1);
144   static_assert(v_mm_cvtps_pd[0] == -1.0 && v_mm_cvtps_pd[1] == +2.0);
145 }
146