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 @_Z19CastCharMatrixToIntv
10 void CastCharMatrixToInt() {
11   // CHECK: [[C:%.*]] = load <25 x i8>, <25 x i8>* {{.*}}, align 1
12   // CHECK-NEXT: [[CONV:%.*]] = sext <25 x i8> [[C]] to <25 x i32>
13   // CHECK-NEXT: [[CONV1:%.*]] = bitcast [25 x i32]* {{.*}} to <25 x i32>*
14   // CHECK-NEXT: store <25 x i32> [[CONV]], <25 x i32>* [[CONV1]], align 4
15 
16   matrix_5_5<char> c;
17   matrix_5_5<int> i;
18   i = (matrix_5_5<int>)c;
19 }
20 
21 // CHECK-LABEL: define{{.*}} void @_Z27CastCharMatrixToUnsignedIntv
22 void CastCharMatrixToUnsignedInt() {
23   // CHECK:       [[C:%.*]] = load <25 x i8>, <25 x i8>* {{.*}}, align 1
24   // CHECK-NEXT:  [[CONV:%.*]] = sext <25 x i8> [[C]] to <25 x i32>
25   // CHECK-NEXT:  [[CONV1:%.*]] = bitcast [25 x i32]* {{.*}} to <25 x i32>*
26   // CHECK-NEXT:  store <25 x i32> [[CONV]], <25 x i32>* [[CONV1]], align 4
27   // CHECK-NEXT:  ret void
28 
29   matrix_5_5<char> c;
30   matrix_5_5<unsigned int> u;
31   u = (matrix_5_5<unsigned int>)c;
32 }
33 
34 // CHECK-LABEL: define{{.*}} void @_Z32CastUnsignedLongIntMatrixToShortv
35 void CastUnsignedLongIntMatrixToShort() {
36   // CHECK:      [[U:%.*]] = load <25 x i64>, <25 x i64>* {{.*}}, align 8
37   // CHECK-NEXT: [[CONV:%.*]] = trunc <25 x i64> {{.*}} to <25 x i16>
38   // CHECK-NEXT: [[CONV1:%.*]] = bitcast [25 x i16]* {{.*}} to <25 x i16>*
39   // CHECK-NEXT: store <25 x i16> [[CONV]], <25 x i16>* [[CONV1]], align 2
40   // CHECK-NEXT: ret void
41 
42   matrix_5_5<unsigned long int> u;
43   matrix_5_5<short int> s;
44   s = (matrix_5_5<short int>)u;
45 }
46 
47 // CHECK-LABEL: define{{.*}} void @_Z20CastIntMatrixToShortv()
48 void CastIntMatrixToShort() {
49   // CHECK:       [[I:%.*]] = load <25 x i32>, <25 x i32>* {{.*}}, align 4
50   // CHECK-NEXT:  [[CONV:%.*]] = trunc <25 x i32> [[I]] to <25 x i16>
51   // CHECK-NEXT:  [[CONV1:%.*]] = bitcast [25 x i16]* {{.*}} to <25 x i16>*
52   // CHECK-NEXT:  store <25 x i16> [[CONV]], <25 x i16>* [[CONV1]], align 2
53   // CHECK-NEXT:  ret void
54 
55   matrix_5_5<int> i;
56   matrix_5_5<short int> s;
57   s = (matrix_5_5<short int>)i;
58 }
59 
60 // CHECK-LABEL: define{{.*}} void @_Z20CastIntMatrixToFloatv()
61 void CastIntMatrixToFloat() {
62   // CHECK:       [[I:%.*]] = load <25 x i32>, <25 x i32>* {{.*}}, align 4
63   // CHECK-NEXT:  [[CONV]] = sitofp <25 x i32> {{.*}} to <25 x float>
64   // CHECK-NEXT:  [[CONV1]] = bitcast [25 x float]* {{.*}} to <25 x float>*
65   // CHECK-NEXT:  store <25 x float> [[CONV]], <25 x float>* [[CONV1]], align 4
66   // CHECK-NEXT:  ret void
67 
68   matrix_5_5<int> i;
69   matrix_5_5<float> f;
70   f = (matrix_5_5<float>)i;
71 }
72 
73 // CHECK-LABEL: define{{.*}} void @_Z28CastUnsignedIntMatrixToFloatv()
74 void CastUnsignedIntMatrixToFloat() {
75   // CHECK:       [[U:%.*]] = load <25 x i16>, <25 x i16>* {{.*}}, align 2
76   // CHECK-NEXT:  [[CONV:%.*]] = uitofp <25 x i16> [[U]] to <25 x float>
77   // CHECK-NEXT:  [[CONV1:%.*]] = bitcast [25 x float]* {{.*}} to <25 x float>*
78   // CHECK-NEXT:  store <25 x float> [[CONV]], <25 x float>* {{.*}}, align 4
79   // CHECK-NEXT:  ret void
80 
81   matrix_5_5<unsigned short int> u;
82   matrix_5_5<float> f;
83   f = (matrix_5_5<float>)u;
84 }
85 
86 // CHECK-LABEL: define{{.*}} void @_Z21CastDoubleMatrixToIntv()
87 void CastDoubleMatrixToInt() {
88   // CHECK:       [[D:%.*]] = load <25 x double>, <25 x double>* {{.*}}, align 8
89   // CHECK-NEXT:  [[CONV:%.*]] = fptosi <25 x double> [[D]] to <25 x i32>
90   // CHECK-NEXT:  [[CONV1:%.*]] = bitcast [25 x i32]* %i to <25 x i32>*
91   // CHECK-NEXT:  store <25 x i32> [[CONV]], <25 x i32>* {{.*}}, align 4
92   // CHECK-NEXT:  ret void
93 
94   matrix_5_5<double> d;
95   matrix_5_5<int> i;
96   i = (matrix_5_5<int>)d;
97 }
98 
99 // CHECK-LABEL: define{{.*}} void @_Z33CastFloatMatrixToUnsignedShortIntv()
100 void CastFloatMatrixToUnsignedShortInt() {
101   // CHECK:       [[F:%.*]] = load <25 x float>, <25 x float>* {{.*}}, align 4
102   // CHECK-NEXT:  [[CONV:%.*]] = fptoui <25 x float> [[F]] to <25 x i16>
103   // CHECK-NEXT:  [[CONV1:%.*]] = bitcast [25 x i16]* {{.*}} to <25 x i16>*
104   // CHECK-NEXT:  store <25 x i16> [[CONV]], <25 x i16>* [[CONV1]], align 2
105   // CHECK-NEXT:  ret void
106 
107   matrix_5_5<float> f;
108   matrix_5_5<unsigned short int> i;
109   i = (matrix_5_5<unsigned short int>)f;
110 }
111 
112 // CHECK-LABEL: define{{.*}} void @_Z23CastDoubleMatrixToFloatv()
113 void CastDoubleMatrixToFloat() {
114   // CHECK:       [[D:%.*]] = load <25 x double>, <25 x double>* {{.*}}, align 8
115   // CHECK-NEXT:  [[CONV:%.*]] = fptrunc <25 x double> [[D]] to <25 x float>
116   // CHECK-NEXT:  [[CONV1:%.*]] = bitcast [25 x float]* {{.*}} to <25 x float>*
117   // CHECK-NEXT:  store <25 x float> [[CONV]], <25 x float>* [[CONV1]], align 4
118   // CHECK-NEXT:  ret void
119 
120   matrix_5_5<double> d;
121   matrix_5_5<float> f;
122   f = (matrix_5_5<float>)d;
123 }
124 
125 // CHECK-LABEL: define{{.*}} void @_Z33CastUnsignedShortIntToUnsignedIntv()
126 void CastUnsignedShortIntToUnsignedInt() {
127   // CHECK:       [[S:%.*]] = load <25 x i16>, <25 x i16>* {{.*}}, align 2
128   // CHECK-NEXT:  [[CONV:%.*]] = zext <25 x i16> [[S]] to <25 x i32>
129   // CHECK-NEXT:  [[CONV1:%.*]] = bitcast [25 x i32]* {{.*}} to <25 x i32>*
130   // CHECK-NEXT:  store <25 x i32> [[CONV]], <25 x i32>* [[CONV1]], align 4
131   // CHECK-NEXT:  ret void
132 
133   matrix_5_5<unsigned short int> s;
134   matrix_5_5<unsigned int> i;
135   i = (matrix_5_5<unsigned int>)s;
136 }
137 
138 // CHECK-LABEL: define{{.*}} void @_Z37CastUnsignedLongIntToUnsignedShortIntv()
139 void CastUnsignedLongIntToUnsignedShortInt() {
140   // CHECK:       [[L:%.*]] = load <25 x i64>, <25 x i64>* %0, align 8
141   // CHECK-NEXT:  [[CONV:%.*]] = trunc <25 x i64> [[L]] to <25 x i16>
142   // CHECK-NEXT:  [[CONV1:%.*]] = bitcast [25 x i16]* {{.*}} to <25 x i16>*
143   // CHECK-NEXT:  store <25 x i16> [[CONV]], <25 x i16>* [[CONV1]], align 2
144   // CHECK-NEXT:  ret void
145 
146   matrix_5_5<unsigned long int> l;
147   matrix_5_5<unsigned short int> s;
148   s = (matrix_5_5<unsigned short int>)l;
149 }
150 
151 // CHECK-LABEL: define{{.*}} void @_Z25CastUnsignedShortIntToIntv()
152 void CastUnsignedShortIntToInt() {
153   // CHECK:       [[U:%.*]] = load <25 x i16>, <25 x i16>* %0, align 2
154   // CHECK-NEXT:  [[CONV:%.*]] = zext <25 x i16> [[U]] to <25 x i32>
155   // CHECK-NEXT:  [[CONV1:%.*]] = bitcast [25 x i32]* {{.*}} to <25 x i32>*
156   // CHECK-NEXT:  store <25 x i32> [[CONV]], <25 x i32>* {{.*}}, align 4
157   // CHECK-NEXT:  ret void
158 
159   matrix_5_5<unsigned short int> u;
160   matrix_5_5<int> i;
161   i = (matrix_5_5<int>)u;
162 }
163 
164 // CHECK-LABEL: define{{.*}} void @_Z24CastIntToUnsignedLongIntv()
165 void CastIntToUnsignedLongInt() {
166   // CHECK:       [[I:%.*]] = load <25 x i32>, <25 x i32>* %0, align 4
167   // CHECK-NEXT:  [[CONV:%.*]] = sext <25 x i32> [[I]] to <25 x i64>
168   // CHECK-NEXT:  [[CONV1:%.*]] = bitcast [25 x i64]* {{.*}} to <25 x i64>*
169   // CHECK-NEXT:  store <25 x i64> [[CONV]], <25 x i64>* {{.*}}, align 8
170   // CHECK-NEXT:  ret void
171 
172   matrix_5_5<int> i;
173   matrix_5_5<unsigned long int> u;
174   u = (matrix_5_5<unsigned long int>)i;
175 }
176