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