1 // RUN: %clang_cc1 -std=c++11 -fenable-matrix -triple x86_64-apple-darwin %s -emit-llvm -disable-llvm-passes -o - | FileCheck %s
2
3 template <typename X>
4 using matrix_4_4 = X __attribute__((matrix_type(4, 4)));
5
6 template <typename Y>
7 using matrix_5_5 = Y __attribute__((matrix_type(5, 5)));
8
9 // CHECK-LABEL: define{{.*}} void @_Z25CastCharMatrixToIntCStylev()
CastCharMatrixToIntCStyle()10 void CastCharMatrixToIntCStyle() {
11 // CHECK: [[C:%.*]] = load <25 x i8>, ptr {{.*}}, align 1
12 // CHECK-NEXT: [[CONV:%.*]] = sext <25 x i8> [[C]] to <25 x i32>
13 // CHECK-NEXT: store <25 x i32> [[CONV]], ptr {{.*}}, align 4
14
15 matrix_5_5<char> c;
16 matrix_5_5<int> i;
17 i = (matrix_5_5<int>)c;
18 }
19
20 // CHECK-LABEL: define{{.*}} void @_Z29CastCharMatrixToIntStaticCastv()
CastCharMatrixToIntStaticCast()21 void CastCharMatrixToIntStaticCast() {
22 // CHECK: [[C:%.*]] = load <25 x i8>, ptr {{.*}}, align 1
23 // CHECK-NEXT: [[CONV:%.*]] = sext <25 x i8> [[C]] to <25 x i32>
24 // CHECK-NEXT: store <25 x i32> [[CONV]], ptr {{.*}}, align 4
25
26 matrix_5_5<char> c;
27 matrix_5_5<int> i;
28 i = static_cast<matrix_5_5<int>>(c);
29 }
30
31 // CHECK-LABEL: define{{.*}} void @_Z33CastCharMatrixToUnsignedIntCStylev
CastCharMatrixToUnsignedIntCStyle()32 void CastCharMatrixToUnsignedIntCStyle() {
33 // CHECK: [[C:%.*]] = load <25 x i8>, ptr {{.*}}, align 1
34 // CHECK-NEXT: [[CONV:%.*]] = sext <25 x i8> [[C]] to <25 x i32>
35 // CHECK-NEXT: store <25 x i32> [[CONV]], ptr {{.*}}, align 4
36 // CHECK-NEXT: ret void
37
38 matrix_5_5<char> c;
39 matrix_5_5<unsigned int> u;
40 u = (matrix_5_5<unsigned int>)c;
41 }
42
43 // CHECK-LABEL: define{{.*}} void @_Z37CastCharMatrixToUnsignedIntStaticCastv
CastCharMatrixToUnsignedIntStaticCast()44 void CastCharMatrixToUnsignedIntStaticCast() {
45 // CHECK: [[C:%.*]] = load <25 x i8>, ptr {{.*}}, align 1
46 // CHECK-NEXT: [[CONV:%.*]] = sext <25 x i8> [[C]] to <25 x i32>
47 // CHECK-NEXT: store <25 x i32> [[CONV]], ptr {{.*}}, align 4
48 // CHECK-NEXT: ret void
49
50 matrix_5_5<char> c;
51 matrix_5_5<unsigned int> u;
52 u = static_cast<matrix_5_5<unsigned int>>(c);
53 }
54
55 // CHECK-LABEL: define{{.*}} void @_Z38CastUnsignedLongIntMatrixToShortCStylev
CastUnsignedLongIntMatrixToShortCStyle()56 void CastUnsignedLongIntMatrixToShortCStyle() {
57 // CHECK: [[U:%.*]] = load <25 x i64>, ptr {{.*}}, align 8
58 // CHECK-NEXT: [[CONV:%.*]] = trunc <25 x i64> {{.*}} to <25 x i16>
59 // CHECK-NEXT: store <25 x i16> [[CONV]], ptr {{.*}}, align 2
60 // CHECK-NEXT: ret void
61
62 matrix_5_5<unsigned long int> u;
63 matrix_5_5<short int> s;
64 s = (matrix_5_5<short int>)u;
65 }
66
67 // CHECK-LABEL: define{{.*}} void @_Z42CastUnsignedLongIntMatrixToShortStaticCastv
CastUnsignedLongIntMatrixToShortStaticCast()68 void CastUnsignedLongIntMatrixToShortStaticCast() {
69 // CHECK: [[U:%.*]] = load <25 x i64>, ptr {{.*}}, align 8
70 // CHECK-NEXT: [[CONV:%.*]] = trunc <25 x i64> {{.*}} to <25 x i16>
71 // CHECK-NEXT: store <25 x i16> [[CONV]], ptr {{.*}}, align 2
72 // CHECK-NEXT: ret void
73
74 matrix_5_5<unsigned long int> u;
75 matrix_5_5<short int> s;
76 s = static_cast<matrix_5_5<short int>>(u);
77 }
78
79 // CHECK-LABEL: define{{.*}} void @_Z26CastIntMatrixToShortCStylev()
CastIntMatrixToShortCStyle()80 void CastIntMatrixToShortCStyle() {
81 // CHECK: [[I:%.*]] = load <25 x i32>, ptr {{.*}}, align 4
82 // CHECK-NEXT: [[CONV:%.*]] = trunc <25 x i32> [[I]] to <25 x i16>
83 // CHECK-NEXT: store <25 x i16> [[CONV]], ptr {{.*}}, align 2
84 // CHECK-NEXT: ret void
85
86 matrix_5_5<int> i;
87 matrix_5_5<short int> s;
88 s = (matrix_5_5<short int>)i;
89 }
90
91 // CHECK-LABEL: define{{.*}} void @_Z30CastIntMatrixToShortStaticCastv()
CastIntMatrixToShortStaticCast()92 void CastIntMatrixToShortStaticCast() {
93 // CHECK: [[I:%.*]] = load <25 x i32>, ptr {{.*}}, align 4
94 // CHECK-NEXT: [[CONV:%.*]] = trunc <25 x i32> [[I]] to <25 x i16>
95 // CHECK-NEXT: store <25 x i16> [[CONV]], ptr {{.*}}, align 2
96 // CHECK-NEXT: ret void
97
98 matrix_5_5<int> i;
99 matrix_5_5<short int> s;
100 s = static_cast<matrix_5_5<short int>>(i);
101 }
102
103 // CHECK-LABEL: define{{.*}} void @_Z26CastIntMatrixToFloatCStylev()
CastIntMatrixToFloatCStyle()104 void CastIntMatrixToFloatCStyle() {
105 // CHECK: [[I:%.*]] = load <25 x i32>, ptr {{.*}}, align 4
106 // CHECK-NEXT: [[CONV]] = sitofp <25 x i32> {{.*}} to <25 x float>
107 // CHECK-NEXT: store <25 x float> [[CONV]], ptr {{.*}}, align 4
108 // CHECK-NEXT: ret void
109
110 matrix_5_5<int> i;
111 matrix_5_5<float> f;
112 f = (matrix_5_5<float>)i;
113 }
114
115 // CHECK-LABEL: define{{.*}} void @_Z30CastIntMatrixToFloatStaticCastv()
CastIntMatrixToFloatStaticCast()116 void CastIntMatrixToFloatStaticCast() {
117 // CHECK: [[I:%.*]] = load <25 x i32>, ptr {{.*}}, align 4
118 // CHECK-NEXT: [[CONV]] = sitofp <25 x i32> {{.*}} to <25 x float>
119 // CHECK-NEXT: store <25 x float> [[CONV]], ptr {{.*}}, align 4
120 // CHECK-NEXT: ret void
121
122 matrix_5_5<int> i;
123 matrix_5_5<float> f;
124 f = static_cast<matrix_5_5<float>>(i);
125 }
126
127 // CHECK-LABEL: define{{.*}} void @_Z34CastUnsignedIntMatrixToFloatCStylev()
CastUnsignedIntMatrixToFloatCStyle()128 void CastUnsignedIntMatrixToFloatCStyle() {
129 // CHECK: [[U:%.*]] = load <25 x i16>, ptr {{.*}}, align 2
130 // CHECK-NEXT: [[CONV:%.*]] = uitofp <25 x i16> [[U]] to <25 x float>
131 // CHECK-NEXT: store <25 x float> [[CONV]], ptr {{.*}}, align 4
132 // CHECK-NEXT: ret void
133
134 matrix_5_5<unsigned short int> u;
135 matrix_5_5<float> f;
136 f = (matrix_5_5<float>)u;
137 }
138
139 // CHECK-LABEL: define{{.*}} void @_Z38CastUnsignedIntMatrixToFloatStaticCastv()
CastUnsignedIntMatrixToFloatStaticCast()140 void CastUnsignedIntMatrixToFloatStaticCast() {
141 // CHECK: [[U:%.*]] = load <25 x i16>, ptr {{.*}}, align 2
142 // CHECK-NEXT: [[CONV:%.*]] = uitofp <25 x i16> [[U]] to <25 x float>
143 // CHECK-NEXT: store <25 x float> [[CONV]], ptr {{.*}}, align 4
144 // CHECK-NEXT: ret void
145
146 matrix_5_5<unsigned short int> u;
147 matrix_5_5<float> f;
148 f = static_cast<matrix_5_5<float>>(u);
149 }
150
151 // CHECK-LABEL: define{{.*}} void @_Z27CastDoubleMatrixToIntCStylev()
CastDoubleMatrixToIntCStyle()152 void CastDoubleMatrixToIntCStyle() {
153 // CHECK: [[D:%.*]] = load <25 x double>, ptr {{.*}}, align 8
154 // CHECK-NEXT: [[CONV:%.*]] = fptosi <25 x double> [[D]] to <25 x i32>
155 // CHECK-NEXT: store <25 x i32> [[CONV]], ptr {{.*}}, align 4
156 // CHECK-NEXT: ret void
157
158 matrix_5_5<double> d;
159 matrix_5_5<int> i;
160 i = (matrix_5_5<int>)d;
161 }
162
163 // CHECK-LABEL: define{{.*}} void @_Z31CastDoubleMatrixToIntStaticCastv()
CastDoubleMatrixToIntStaticCast()164 void CastDoubleMatrixToIntStaticCast() {
165 // CHECK: [[D:%.*]] = load <25 x double>, ptr {{.*}}, align 8
166 // CHECK-NEXT: [[CONV:%.*]] = fptosi <25 x double> [[D]] to <25 x i32>
167 // CHECK-NEXT: store <25 x i32> [[CONV]], ptr {{.*}}, align 4
168 // CHECK-NEXT: ret void
169
170 matrix_5_5<double> d;
171 matrix_5_5<int> i;
172 i = static_cast<matrix_5_5<int>>(d);
173 }
174
175 // CHECK-LABEL: define{{.*}} void @_Z39CastFloatMatrixToUnsignedShortIntCStylev()
CastFloatMatrixToUnsignedShortIntCStyle()176 void CastFloatMatrixToUnsignedShortIntCStyle() {
177 // CHECK: [[F:%.*]] = load <25 x float>, ptr {{.*}}, align 4
178 // CHECK-NEXT: [[CONV:%.*]] = fptoui <25 x float> [[F]] to <25 x i16>
179 // CHECK-NEXT: store <25 x i16> [[CONV]], ptr {{.*}}, align 2
180 // CHECK-NEXT: ret void
181
182 matrix_5_5<float> f;
183 matrix_5_5<unsigned short int> i;
184 i = (matrix_5_5<unsigned short int>)f;
185 }
186
187 // CHECK-LABEL: define{{.*}} void @_Z43CastFloatMatrixToUnsignedShortIntStaticCastv()
CastFloatMatrixToUnsignedShortIntStaticCast()188 void CastFloatMatrixToUnsignedShortIntStaticCast() {
189 // CHECK: [[F:%.*]] = load <25 x float>, ptr {{.*}}, align 4
190 // CHECK-NEXT: [[CONV:%.*]] = fptoui <25 x float> [[F]] to <25 x i16>
191 // CHECK-NEXT: store <25 x i16> [[CONV]], ptr {{.*}}, align 2
192 // CHECK-NEXT: ret void
193
194 matrix_5_5<float> f;
195 matrix_5_5<unsigned short int> i;
196 i = static_cast<matrix_5_5<unsigned short int>>(f);
197 }
198
199 // CHECK-LABEL: define{{.*}} void @_Z29CastDoubleMatrixToFloatCStylev()
CastDoubleMatrixToFloatCStyle()200 void CastDoubleMatrixToFloatCStyle() {
201 // CHECK: [[D:%.*]] = load <25 x double>, ptr {{.*}}, align 8
202 // CHECK-NEXT: [[CONV:%.*]] = fptrunc <25 x double> [[D]] to <25 x float>
203 // CHECK-NEXT: store <25 x float> [[CONV]], ptr {{.*}}, align 4
204 // CHECK-NEXT: ret void
205
206 matrix_5_5<double> d;
207 matrix_5_5<float> f;
208 f = (matrix_5_5<float>)d;
209 }
210
211 // CHECK-LABEL: define{{.*}} void @_Z33CastDoubleMatrixToFloatStaticCastv()
CastDoubleMatrixToFloatStaticCast()212 void CastDoubleMatrixToFloatStaticCast() {
213 // CHECK: [[D:%.*]] = load <25 x double>, ptr {{.*}}, align 8
214 // CHECK-NEXT: [[CONV:%.*]] = fptrunc <25 x double> [[D]] to <25 x float>
215 // CHECK-NEXT: store <25 x float> [[CONV]], ptr {{.*}}, align 4
216 // CHECK-NEXT: ret void
217
218 matrix_5_5<double> d;
219 matrix_5_5<float> f;
220 f = static_cast<matrix_5_5<float>>(d);
221 }
222
223 // CHECK-LABEL: define{{.*}} void @_Z39CastUnsignedShortIntToUnsignedIntCStylev()
CastUnsignedShortIntToUnsignedIntCStyle()224 void CastUnsignedShortIntToUnsignedIntCStyle() {
225 // CHECK: [[S:%.*]] = load <25 x i16>, ptr {{.*}}, align 2
226 // CHECK-NEXT: [[CONV:%.*]] = zext <25 x i16> [[S]] to <25 x i32>
227 // CHECK-NEXT: store <25 x i32> [[CONV]], ptr {{.*}}, align 4
228 // CHECK-NEXT: ret void
229
230 matrix_5_5<unsigned short int> s;
231 matrix_5_5<unsigned int> i;
232 i = (matrix_5_5<unsigned int>)s;
233 }
234
235 // CHECK-LABEL: define{{.*}} void @_Z43CastUnsignedShortIntToUnsignedIntStaticCastv()
CastUnsignedShortIntToUnsignedIntStaticCast()236 void CastUnsignedShortIntToUnsignedIntStaticCast() {
237 // CHECK: [[S:%.*]] = load <25 x i16>, ptr {{.*}}, align 2
238 // CHECK-NEXT: [[CONV:%.*]] = zext <25 x i16> [[S]] to <25 x i32>
239 // CHECK-NEXT: store <25 x i32> [[CONV]], ptr {{.*}}, align 4
240 // CHECK-NEXT: ret void
241
242 matrix_5_5<unsigned short int> s;
243 matrix_5_5<unsigned int> i;
244 i = static_cast<matrix_5_5<unsigned int>>(s);
245 }
246
247 // CHECK-LABEL: define{{.*}} void @_Z43CastUnsignedLongIntToUnsignedShortIntCStylev()
CastUnsignedLongIntToUnsignedShortIntCStyle()248 void CastUnsignedLongIntToUnsignedShortIntCStyle() {
249 // CHECK: [[L:%.*]] = load <25 x i64>, ptr %l, align 8
250 // CHECK-NEXT: [[CONV:%.*]] = trunc <25 x i64> [[L]] to <25 x i16>
251 // CHECK-NEXT: store <25 x i16> [[CONV]], ptr {{.*}}, align 2
252 // CHECK-NEXT: ret void
253
254 matrix_5_5<unsigned long int> l;
255 matrix_5_5<unsigned short int> s;
256 s = (matrix_5_5<unsigned short int>)l;
257 }
258
259 // CHECK-LABEL: define{{.*}} void @_Z47CastUnsignedLongIntToUnsignedShortIntStaticCastv()
CastUnsignedLongIntToUnsignedShortIntStaticCast()260 void CastUnsignedLongIntToUnsignedShortIntStaticCast() {
261 // CHECK: [[L:%.*]] = load <25 x i64>, ptr %l, align 8
262 // CHECK-NEXT: [[CONV:%.*]] = trunc <25 x i64> [[L]] to <25 x i16>
263 // CHECK-NEXT: store <25 x i16> [[CONV]], ptr {{.*}}, align 2
264 // CHECK-NEXT: ret void
265
266 matrix_5_5<unsigned long int> l;
267 matrix_5_5<unsigned short int> s;
268 s = static_cast<matrix_5_5<unsigned short int>>(l);
269 }
270
271 // CHECK-LABEL: define{{.*}} void @_Z31CastUnsignedShortIntToIntCStylev()
CastUnsignedShortIntToIntCStyle()272 void CastUnsignedShortIntToIntCStyle() {
273 // CHECK: [[U:%.*]] = load <25 x i16>, ptr %u, align 2
274 // CHECK-NEXT: [[CONV:%.*]] = zext <25 x i16> [[U]] to <25 x i32>
275 // CHECK-NEXT: store <25 x i32> [[CONV]], ptr {{.*}}, align 4
276 // CHECK-NEXT: ret void
277
278 matrix_5_5<unsigned short int> u;
279 matrix_5_5<int> i;
280 i = (matrix_5_5<int>)u;
281 }
282
283 // CHECK-LABEL: define{{.*}} void @_Z35CastUnsignedShortIntToIntStaticCastv()
CastUnsignedShortIntToIntStaticCast()284 void CastUnsignedShortIntToIntStaticCast() {
285 // CHECK: [[U:%.*]] = load <25 x i16>, ptr %u, align 2
286 // CHECK-NEXT: [[CONV:%.*]] = zext <25 x i16> [[U]] to <25 x i32>
287 // CHECK-NEXT: store <25 x i32> [[CONV]], ptr {{.*}}, align 4
288 // CHECK-NEXT: ret void
289
290 matrix_5_5<unsigned short int> u;
291 matrix_5_5<int> i;
292 i = static_cast<matrix_5_5<int>>(u);
293 }
294
295 // CHECK-LABEL: define{{.*}} void @_Z30CastIntToUnsignedLongIntCStylev()
CastIntToUnsignedLongIntCStyle()296 void CastIntToUnsignedLongIntCStyle() {
297 // CHECK: [[I:%.*]] = load <25 x i32>, ptr %i, align 4
298 // CHECK-NEXT: [[CONV:%.*]] = sext <25 x i32> [[I]] to <25 x i64>
299 // CHECK-NEXT: store <25 x i64> [[CONV]], ptr {{.*}}, align 8
300 // CHECK-NEXT: ret void
301
302 matrix_5_5<int> i;
303 matrix_5_5<unsigned long int> u;
304 u = (matrix_5_5<unsigned long int>)i;
305 }
306
307 // CHECK-LABEL: define{{.*}} void @_Z34CastIntToUnsignedLongIntStaticCastv()
CastIntToUnsignedLongIntStaticCast()308 void CastIntToUnsignedLongIntStaticCast() {
309 // CHECK: [[I:%.*]] = load <25 x i32>, ptr %i, align 4
310 // CHECK-NEXT: [[CONV:%.*]] = sext <25 x i32> [[I]] to <25 x i64>
311 // CHECK-NEXT: store <25 x i64> [[CONV]], ptr {{.*}}, align 8
312 // CHECK-NEXT: ret void
313
314 matrix_5_5<int> i;
315 matrix_5_5<unsigned long int> u;
316 u = static_cast<matrix_5_5<unsigned long int>>(i);
317 }
318
319 class Foo {
320 int x[10];
321
322 public:
323 Foo(matrix_5_5<int> x);
324 };
325
class_constructor_matrix_ty(matrix_5_5<int> m)326 Foo class_constructor_matrix_ty(matrix_5_5<int> m) {
327 // CHECK-LABEL: define void @_Z27class_constructor_matrix_tyu11matrix_typeILm5ELm5EiE(ptr dead_on_unwind noalias writable sret(%class.Foo) align 4 %agg.result, <25 x i32> noundef %m)
328 // CHECK: [[M:%.*]] = load <25 x i32>, ptr {{.*}}, align 4
329 // CHECK-NEXT: call void @_ZN3FooC1Eu11matrix_typeILm5ELm5EiE(ptr noundef nonnull align 4 dereferenceable(40) %agg.result, <25 x i32> noundef [[M]])
330 // CHECK-NEXT: ret void
331
332 return Foo(m);
333 }
334
335 struct Bar {
336 float x[10];
337 Bar(matrix_4_4<float> x);
338 };
339
struct_constructor_matrix_ty(matrix_4_4<float> m)340 Bar struct_constructor_matrix_ty(matrix_4_4<float> m) {
341 // CHECK-LABEL: define void @_Z28struct_constructor_matrix_tyu11matrix_typeILm4ELm4EfE(ptr dead_on_unwind noalias writable sret(%struct.Bar) align 4 %agg.result, <16 x float> noundef %m)
342 // CHECK: [[M:%.*]] = load <16 x float>, ptr {{.*}}, align 4
343 // CHECK-NEXT: call void @_ZN3BarC1Eu11matrix_typeILm4ELm4EfE(ptr noundef nonnull align 4 dereferenceable(40) %agg.result, <16 x float> noundef [[M]])
344 // CHECK-NEXT: ret void
345
346 return Bar(m);
347 }
348