// RUN: %clang_cc1 -std=c++11 -fenable-matrix -triple x86_64-apple-darwin %s -emit-llvm -disable-llvm-passes -o - | FileCheck %s template using matrix_4_4 = X __attribute__((matrix_type(4, 4))); template 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 c; matrix_5_5 i; i = (matrix_5_5)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 c; matrix_5_5 i; i = static_cast>(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 c; matrix_5_5 u; u = (matrix_5_5)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 c; matrix_5_5 u; u = static_cast>(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 u; matrix_5_5 s; s = (matrix_5_5)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 u; matrix_5_5 s; s = static_cast>(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 i; matrix_5_5 s; s = (matrix_5_5)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 i; matrix_5_5 s; s = static_cast>(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 i; matrix_5_5 f; f = (matrix_5_5)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 i; matrix_5_5 f; f = static_cast>(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 u; matrix_5_5 f; f = (matrix_5_5)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 u; matrix_5_5 f; f = static_cast>(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 d; matrix_5_5 i; i = (matrix_5_5)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 d; matrix_5_5 i; i = static_cast>(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 f; matrix_5_5 i; i = (matrix_5_5)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 f; matrix_5_5 i; i = static_cast>(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 d; matrix_5_5 f; f = (matrix_5_5)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 d; matrix_5_5 f; f = static_cast>(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 s; matrix_5_5 i; i = (matrix_5_5)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 s; matrix_5_5 i; i = static_cast>(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 l; matrix_5_5 s; s = (matrix_5_5)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 l; matrix_5_5 s; s = static_cast>(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 u; matrix_5_5 i; i = (matrix_5_5)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 u; matrix_5_5 i; i = static_cast>(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 i; matrix_5_5 u; u = (matrix_5_5)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 i; matrix_5_5 u; u = static_cast>(i); } class Foo { int x[10]; public: Foo(matrix_5_5 x); }; Foo class_constructor_matrix_ty(matrix_5_5 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 x); }; Bar struct_constructor_matrix_ty(matrix_4_4 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); }