| // RUN: %clang_cc1 -std=c++11 -fenable-matrix -triple x86_64-apple-darwin %s -emit-llvm -disable-llvm-passes -o - | FileCheck %s | |
| template <typename X> | |
| using matrix_4_4 = X __attribute__((matrix_type(4, 4))); | |
| template <typename Y> | |
| using matrix_5_5 = Y __attribute__((matrix_type(5, 5))); | |
| // CHECK-LABEL: define{{.*}} void @_Z25CastCharMatrixToIntCStylev() | |
| void CastCharMatrixToIntCStyle() { | |
| // CHECK: [[C:%.*]] = load <25 x i8>, ptr {{.*}}, align 1 | |
| // CHECK-NEXT: [[CONV:%.*]] = sext <25 x i8> [[C]] to <25 x i32> | |
| // CHECK-NEXT: store <25 x i32> [[CONV]], ptr {{.*}}, align 4 | |
| matrix_5_5<char> c; | |
| matrix_5_5<int> i; | |
| i = (matrix_5_5<int>)c; | |
| } | |
| // CHECK-LABEL: define{{.*}} void @_Z29CastCharMatrixToIntStaticCastv() | |
| void CastCharMatrixToIntStaticCast() { | |
| // CHECK: [[C:%.*]] = load <25 x i8>, ptr {{.*}}, align 1 | |
| // CHECK-NEXT: [[CONV:%.*]] = sext <25 x i8> [[C]] to <25 x i32> | |
| // CHECK-NEXT: store <25 x i32> [[CONV]], ptr {{.*}}, align 4 | |
| matrix_5_5<char> c; | |
| matrix_5_5<int> i; | |
| i = static_cast<matrix_5_5<int>>(c); | |
| } | |
| // CHECK-LABEL: define{{.*}} void @_Z33CastCharMatrixToUnsignedIntCStylev | |
| void CastCharMatrixToUnsignedIntCStyle() { | |
| // CHECK: [[C:%.*]] = load <25 x i8>, ptr {{.*}}, align 1 | |
| // CHECK-NEXT: [[CONV:%.*]] = sext <25 x i8> [[C]] to <25 x i32> | |
| // CHECK-NEXT: store <25 x i32> [[CONV]], ptr {{.*}}, align 4 | |
| // CHECK-NEXT: ret void | |
| matrix_5_5<char> c; | |
| matrix_5_5<unsigned int> u; | |
| u = (matrix_5_5<unsigned int>)c; | |
| } | |
| // CHECK-LABEL: define{{.*}} void @_Z37CastCharMatrixToUnsignedIntStaticCastv | |
| void CastCharMatrixToUnsignedIntStaticCast() { | |
| // CHECK: [[C:%.*]] = load <25 x i8>, ptr {{.*}}, align 1 | |
| // CHECK-NEXT: [[CONV:%.*]] = sext <25 x i8> [[C]] to <25 x i32> | |
| // CHECK-NEXT: store <25 x i32> [[CONV]], ptr {{.*}}, align 4 | |
| // CHECK-NEXT: ret void | |
| matrix_5_5<char> c; | |
| matrix_5_5<unsigned int> u; | |
| u = static_cast<matrix_5_5<unsigned int>>(c); | |
| } | |
| // CHECK-LABEL: define{{.*}} void @_Z38CastUnsignedLongIntMatrixToShortCStylev | |
| void CastUnsignedLongIntMatrixToShortCStyle() { | |
| // CHECK: [[U:%.*]] = load <25 x i64>, ptr {{.*}}, align 8 | |
| // CHECK-NEXT: [[CONV:%.*]] = trunc <25 x i64> {{.*}} to <25 x i16> | |
| // CHECK-NEXT: store <25 x i16> [[CONV]], ptr {{.*}}, align 2 | |
| // CHECK-NEXT: ret void | |
| matrix_5_5<unsigned long int> u; | |
| matrix_5_5<short int> s; | |
| s = (matrix_5_5<short int>)u; | |
| } | |
| // CHECK-LABEL: define{{.*}} void @_Z42CastUnsignedLongIntMatrixToShortStaticCastv | |
| void CastUnsignedLongIntMatrixToShortStaticCast() { | |
| // CHECK: [[U:%.*]] = load <25 x i64>, ptr {{.*}}, align 8 | |
| // CHECK-NEXT: [[CONV:%.*]] = trunc <25 x i64> {{.*}} to <25 x i16> | |
| // CHECK-NEXT: store <25 x i16> [[CONV]], ptr {{.*}}, align 2 | |
| // CHECK-NEXT: ret void | |
| matrix_5_5<unsigned long int> u; | |
| matrix_5_5<short int> s; | |
| s = static_cast<matrix_5_5<short int>>(u); | |
| } | |
| // CHECK-LABEL: define{{.*}} void @_Z26CastIntMatrixToShortCStylev() | |
| void CastIntMatrixToShortCStyle() { | |
| // CHECK: [[I:%.*]] = load <25 x i32>, ptr {{.*}}, align 4 | |
| // CHECK-NEXT: [[CONV:%.*]] = trunc <25 x i32> [[I]] to <25 x i16> | |
| // CHECK-NEXT: store <25 x i16> [[CONV]], ptr {{.*}}, align 2 | |
| // CHECK-NEXT: ret void | |
| matrix_5_5<int> i; | |
| matrix_5_5<short int> s; | |
| s = (matrix_5_5<short int>)i; | |
| } | |
| // CHECK-LABEL: define{{.*}} void @_Z30CastIntMatrixToShortStaticCastv() | |
| void CastIntMatrixToShortStaticCast() { | |
| // CHECK: [[I:%.*]] = load <25 x i32>, ptr {{.*}}, align 4 | |
| // CHECK-NEXT: [[CONV:%.*]] = trunc <25 x i32> [[I]] to <25 x i16> | |
| // CHECK-NEXT: store <25 x i16> [[CONV]], ptr {{.*}}, align 2 | |
| // CHECK-NEXT: ret void | |
| matrix_5_5<int> i; | |
| matrix_5_5<short int> s; | |
| s = static_cast<matrix_5_5<short int>>(i); | |
| } | |
| // CHECK-LABEL: define{{.*}} void @_Z26CastIntMatrixToFloatCStylev() | |
| void CastIntMatrixToFloatCStyle() { | |
| // CHECK: [[I:%.*]] = load <25 x i32>, ptr {{.*}}, align 4 | |
| // CHECK-NEXT: [[CONV]] = sitofp <25 x i32> {{.*}} to <25 x float> | |
| // CHECK-NEXT: store <25 x float> [[CONV]], ptr {{.*}}, align 4 | |
| // CHECK-NEXT: ret void | |
| matrix_5_5<int> i; | |
| matrix_5_5<float> f; | |
| f = (matrix_5_5<float>)i; | |
| } | |
| // CHECK-LABEL: define{{.*}} void @_Z30CastIntMatrixToFloatStaticCastv() | |
| void CastIntMatrixToFloatStaticCast() { | |
| // CHECK: [[I:%.*]] = load <25 x i32>, ptr {{.*}}, align 4 | |
| // CHECK-NEXT: [[CONV]] = sitofp <25 x i32> {{.*}} to <25 x float> | |
| // CHECK-NEXT: store <25 x float> [[CONV]], ptr {{.*}}, align 4 | |
| // CHECK-NEXT: ret void | |
| matrix_5_5<int> i; | |
| matrix_5_5<float> f; | |
| f = static_cast<matrix_5_5<float>>(i); | |
| } | |
| // CHECK-LABEL: define{{.*}} void @_Z34CastUnsignedIntMatrixToFloatCStylev() | |
| void CastUnsignedIntMatrixToFloatCStyle() { | |
| // CHECK: [[U:%.*]] = load <25 x i16>, ptr {{.*}}, align 2 | |
| // CHECK-NEXT: [[CONV:%.*]] = uitofp <25 x i16> [[U]] to <25 x float> | |
| // CHECK-NEXT: store <25 x float> [[CONV]], ptr {{.*}}, align 4 | |
| // CHECK-NEXT: ret void | |
| matrix_5_5<unsigned short int> u; | |
| matrix_5_5<float> f; | |
| f = (matrix_5_5<float>)u; | |
| } | |
| // CHECK-LABEL: define{{.*}} void @_Z38CastUnsignedIntMatrixToFloatStaticCastv() | |
| void CastUnsignedIntMatrixToFloatStaticCast() { | |
| // CHECK: [[U:%.*]] = load <25 x i16>, ptr {{.*}}, align 2 | |
| // CHECK-NEXT: [[CONV:%.*]] = uitofp <25 x i16> [[U]] to <25 x float> | |
| // CHECK-NEXT: store <25 x float> [[CONV]], ptr {{.*}}, align 4 | |
| // CHECK-NEXT: ret void | |
| matrix_5_5<unsigned short int> u; | |
| matrix_5_5<float> f; | |
| f = static_cast<matrix_5_5<float>>(u); | |
| } | |
| // CHECK-LABEL: define{{.*}} void @_Z27CastDoubleMatrixToIntCStylev() | |
| void CastDoubleMatrixToIntCStyle() { | |
| // CHECK: [[D:%.*]] = load <25 x double>, ptr {{.*}}, align 8 | |
| // CHECK-NEXT: [[CONV:%.*]] = fptosi <25 x double> [[D]] to <25 x i32> | |
| // CHECK-NEXT: store <25 x i32> [[CONV]], ptr {{.*}}, align 4 | |
| // CHECK-NEXT: ret void | |
| matrix_5_5<double> d; | |
| matrix_5_5<int> i; | |
| i = (matrix_5_5<int>)d; | |
| } | |
| // CHECK-LABEL: define{{.*}} void @_Z31CastDoubleMatrixToIntStaticCastv() | |
| void CastDoubleMatrixToIntStaticCast() { | |
| // CHECK: [[D:%.*]] = load <25 x double>, ptr {{.*}}, align 8 | |
| // CHECK-NEXT: [[CONV:%.*]] = fptosi <25 x double> [[D]] to <25 x i32> | |
| // CHECK-NEXT: store <25 x i32> [[CONV]], ptr {{.*}}, align 4 | |
| // CHECK-NEXT: ret void | |
| matrix_5_5<double> d; | |
| matrix_5_5<int> i; | |
| i = static_cast<matrix_5_5<int>>(d); | |
| } | |
| // CHECK-LABEL: define{{.*}} void @_Z39CastFloatMatrixToUnsignedShortIntCStylev() | |
| void CastFloatMatrixToUnsignedShortIntCStyle() { | |
| // CHECK: [[F:%.*]] = load <25 x float>, ptr {{.*}}, align 4 | |
| // CHECK-NEXT: [[CONV:%.*]] = fptoui <25 x float> [[F]] to <25 x i16> | |
| // CHECK-NEXT: store <25 x i16> [[CONV]], ptr {{.*}}, align 2 | |
| // CHECK-NEXT: ret void | |
| matrix_5_5<float> f; | |
| matrix_5_5<unsigned short int> i; | |
| i = (matrix_5_5<unsigned short int>)f; | |
| } | |
| // CHECK-LABEL: define{{.*}} void @_Z43CastFloatMatrixToUnsignedShortIntStaticCastv() | |
| void CastFloatMatrixToUnsignedShortIntStaticCast() { | |
| // CHECK: [[F:%.*]] = load <25 x float>, ptr {{.*}}, align 4 | |
| // CHECK-NEXT: [[CONV:%.*]] = fptoui <25 x float> [[F]] to <25 x i16> | |
| // CHECK-NEXT: store <25 x i16> [[CONV]], ptr {{.*}}, align 2 | |
| // CHECK-NEXT: ret void | |
| matrix_5_5<float> f; | |
| matrix_5_5<unsigned short int> i; | |
| i = static_cast<matrix_5_5<unsigned short int>>(f); | |
| } | |
| // CHECK-LABEL: define{{.*}} void @_Z29CastDoubleMatrixToFloatCStylev() | |
| void CastDoubleMatrixToFloatCStyle() { | |
| // CHECK: [[D:%.*]] = load <25 x double>, ptr {{.*}}, align 8 | |
| // CHECK-NEXT: [[CONV:%.*]] = fptrunc <25 x double> [[D]] to <25 x float> | |
| // CHECK-NEXT: store <25 x float> [[CONV]], ptr {{.*}}, align 4 | |
| // CHECK-NEXT: ret void | |
| matrix_5_5<double> d; | |
| matrix_5_5<float> f; | |
| f = (matrix_5_5<float>)d; | |
| } | |
| // CHECK-LABEL: define{{.*}} void @_Z33CastDoubleMatrixToFloatStaticCastv() | |
| void CastDoubleMatrixToFloatStaticCast() { | |
| // CHECK: [[D:%.*]] = load <25 x double>, ptr {{.*}}, align 8 | |
| // CHECK-NEXT: [[CONV:%.*]] = fptrunc <25 x double> [[D]] to <25 x float> | |
| // CHECK-NEXT: store <25 x float> [[CONV]], ptr {{.*}}, align 4 | |
| // CHECK-NEXT: ret void | |
| matrix_5_5<double> d; | |
| matrix_5_5<float> f; | |
| f = static_cast<matrix_5_5<float>>(d); | |
| } | |
| // CHECK-LABEL: define{{.*}} void @_Z39CastUnsignedShortIntToUnsignedIntCStylev() | |
| void CastUnsignedShortIntToUnsignedIntCStyle() { | |
| // CHECK: [[S:%.*]] = load <25 x i16>, ptr {{.*}}, align 2 | |
| // CHECK-NEXT: [[CONV:%.*]] = zext <25 x i16> [[S]] to <25 x i32> | |
| // CHECK-NEXT: store <25 x i32> [[CONV]], ptr {{.*}}, align 4 | |
| // CHECK-NEXT: ret void | |
| matrix_5_5<unsigned short int> s; | |
| matrix_5_5<unsigned int> i; | |
| i = (matrix_5_5<unsigned int>)s; | |
| } | |
| // CHECK-LABEL: define{{.*}} void @_Z43CastUnsignedShortIntToUnsignedIntStaticCastv() | |
| void CastUnsignedShortIntToUnsignedIntStaticCast() { | |
| // CHECK: [[S:%.*]] = load <25 x i16>, ptr {{.*}}, align 2 | |
| // CHECK-NEXT: [[CONV:%.*]] = zext <25 x i16> [[S]] to <25 x i32> | |
| // CHECK-NEXT: store <25 x i32> [[CONV]], ptr {{.*}}, align 4 | |
| // CHECK-NEXT: ret void | |
| matrix_5_5<unsigned short int> s; | |
| matrix_5_5<unsigned int> i; | |
| i = static_cast<matrix_5_5<unsigned int>>(s); | |
| } | |
| // CHECK-LABEL: define{{.*}} void @_Z43CastUnsignedLongIntToUnsignedShortIntCStylev() | |
| void CastUnsignedLongIntToUnsignedShortIntCStyle() { | |
| // CHECK: [[L:%.*]] = load <25 x i64>, ptr %l, align 8 | |
| // CHECK-NEXT: [[CONV:%.*]] = trunc <25 x i64> [[L]] to <25 x i16> | |
| // CHECK-NEXT: store <25 x i16> [[CONV]], ptr {{.*}}, align 2 | |
| // CHECK-NEXT: ret void | |
| matrix_5_5<unsigned long int> l; | |
| matrix_5_5<unsigned short int> s; | |
| s = (matrix_5_5<unsigned short int>)l; | |
| } | |
| // CHECK-LABEL: define{{.*}} void @_Z47CastUnsignedLongIntToUnsignedShortIntStaticCastv() | |
| void CastUnsignedLongIntToUnsignedShortIntStaticCast() { | |
| // CHECK: [[L:%.*]] = load <25 x i64>, ptr %l, align 8 | |
| // CHECK-NEXT: [[CONV:%.*]] = trunc <25 x i64> [[L]] to <25 x i16> | |
| // CHECK-NEXT: store <25 x i16> [[CONV]], ptr {{.*}}, align 2 | |
| // CHECK-NEXT: ret void | |
| matrix_5_5<unsigned long int> l; | |
| matrix_5_5<unsigned short int> s; | |
| s = static_cast<matrix_5_5<unsigned short int>>(l); | |
| } | |
| // CHECK-LABEL: define{{.*}} void @_Z31CastUnsignedShortIntToIntCStylev() | |
| void CastUnsignedShortIntToIntCStyle() { | |
| // CHECK: [[U:%.*]] = load <25 x i16>, ptr %u, align 2 | |
| // CHECK-NEXT: [[CONV:%.*]] = zext <25 x i16> [[U]] to <25 x i32> | |
| // CHECK-NEXT: store <25 x i32> [[CONV]], ptr {{.*}}, align 4 | |
| // CHECK-NEXT: ret void | |
| matrix_5_5<unsigned short int> u; | |
| matrix_5_5<int> i; | |
| i = (matrix_5_5<int>)u; | |
| } | |
| // CHECK-LABEL: define{{.*}} void @_Z35CastUnsignedShortIntToIntStaticCastv() | |
| void CastUnsignedShortIntToIntStaticCast() { | |
| // CHECK: [[U:%.*]] = load <25 x i16>, ptr %u, align 2 | |
| // CHECK-NEXT: [[CONV:%.*]] = zext <25 x i16> [[U]] to <25 x i32> | |
| // CHECK-NEXT: store <25 x i32> [[CONV]], ptr {{.*}}, align 4 | |
| // CHECK-NEXT: ret void | |
| matrix_5_5<unsigned short int> u; | |
| matrix_5_5<int> i; | |
| i = static_cast<matrix_5_5<int>>(u); | |
| } | |
| // CHECK-LABEL: define{{.*}} void @_Z30CastIntToUnsignedLongIntCStylev() | |
| void CastIntToUnsignedLongIntCStyle() { | |
| // CHECK: [[I:%.*]] = load <25 x i32>, ptr %i, align 4 | |
| // CHECK-NEXT: [[CONV:%.*]] = sext <25 x i32> [[I]] to <25 x i64> | |
| // CHECK-NEXT: store <25 x i64> [[CONV]], ptr {{.*}}, align 8 | |
| // CHECK-NEXT: ret void | |
| matrix_5_5<int> i; | |
| matrix_5_5<unsigned long int> u; | |
| u = (matrix_5_5<unsigned long int>)i; | |
| } | |
| // CHECK-LABEL: define{{.*}} void @_Z34CastIntToUnsignedLongIntStaticCastv() | |
| void CastIntToUnsignedLongIntStaticCast() { | |
| // CHECK: [[I:%.*]] = load <25 x i32>, ptr %i, align 4 | |
| // CHECK-NEXT: [[CONV:%.*]] = sext <25 x i32> [[I]] to <25 x i64> | |
| // CHECK-NEXT: store <25 x i64> [[CONV]], ptr {{.*}}, align 8 | |
| // CHECK-NEXT: ret void | |
| matrix_5_5<int> i; | |
| matrix_5_5<unsigned long int> u; | |
| u = static_cast<matrix_5_5<unsigned long int>>(i); | |
| } | |
| class Foo { | |
| int x[10]; | |
| public: | |
| Foo(matrix_5_5<int> x); | |
| }; | |
| Foo class_constructor_matrix_ty(matrix_5_5<int> m) { | |
| // 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) | |
| // CHECK: [[M:%.*]] = load <25 x i32>, ptr {{.*}}, align 4 | |
| // CHECK-NEXT: call void @_ZN3FooC1Eu11matrix_typeILm5ELm5EiE(ptr noundef nonnull align 4 dereferenceable(40) %agg.result, <25 x i32> noundef [[M]]) | |
| // CHECK-NEXT: ret void | |
| return Foo(m); | |
| } | |
| struct Bar { | |
| float x[10]; | |
| Bar(matrix_4_4<float> x); | |
| }; | |
| Bar struct_constructor_matrix_ty(matrix_4_4<float> m) { | |
| // 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) | |
| // CHECK: [[M:%.*]] = load <16 x float>, ptr {{.*}}, align 4 | |
| // CHECK-NEXT: call void @_ZN3BarC1Eu11matrix_typeILm4ELm4EfE(ptr noundef nonnull align 4 dereferenceable(40) %agg.result, <16 x float> noundef [[M]]) | |
| // CHECK-NEXT: ret void | |
| return Bar(m); | |
| } |