xref: /llvm-project/clang/test/CodeGenCXX/matrix-casts.cpp (revision 158d72d728261c1e54dc77931372b2322c52849f)
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