1 // RUN: %clang_cc1 -fenable-matrix -triple x86_64-apple-darwin %s -emit-llvm -disable-llvm-passes -o - | FileCheck %s
2 
3 typedef char cx5x5 __attribute__((matrix_type(5, 5)));
4 typedef int ix5x5 __attribute__((matrix_type(5, 5)));
5 typedef short sx5x5 __attribute__((matrix_type(5, 5)));
6 typedef float fx5x5 __attribute__((matrix_type(5, 5)));
7 typedef double dx5x5 __attribute__((matrix_type(5, 5)));
8 typedef unsigned short unsigned_short_int_5x5 __attribute__((matrix_type(5, 5)));
9 typedef unsigned int unsigned_int_5x5 __attribute__((matrix_type(5, 5)));
10 typedef unsigned long unsigned_long_int_5x5 __attribute__((matrix_type(5, 5)));
11 
12 void cast_char_matrix_to_int(cx5x5 c, ix5x5 i) {
13   // CHECK-LABEL: define{{.*}} void @cast_char_matrix_to_int(<25 x i8> %c, <25 x i32> %i)
14   // CHECK:       [[C:%.*]] = load <25 x i8>, <25 x i8>* {{.*}}, align 1
15   // CHECK-NEXT:  [[CONV:%.*]] = sext <25 x i8> [[C]] to <25 x i32>
16   // CHECK-NEXT:  store <25 x i32> [[CONV]], <25 x i32>* {{.*}}, align 4
17   // CHECK-NEXT:  ret void
18 
19   i = (ix5x5)c;
20 }
21 
22 void cast_char_matrix_to_unsigned_int(cx5x5 c, unsigned_int_5x5 u) {
23   // CHECK-LABEL: define{{.*}} void @cast_char_matrix_to_unsigned_int(<25 x i8> %c, <25 x i32> %u)
24   // CHECK:       [[C:%.*]] = load <25 x i8>, <25 x i8>* {{.*}}, align 1
25   // CHECK-NEXT:  [[CONV:%.*]] = sext <25 x i8> [[C]] to <25 x i32>
26   // CHECK-NEXT:  store <25 x i32> [[CONV]], <25 x i32>* {{.*}}, align 4
27   // CHECK-NEXT:  ret void
28 
29   u = (unsigned_int_5x5)c;
30 }
31 
32 void cast_unsigned_long_int_matrix_to_short(unsigned_long_int_5x5 u, sx5x5 s) {
33   // CHECK-LABEL: define{{.*}} void @cast_unsigned_long_int_matrix_to_short(<25 x i64> %u, <25 x i16> %s)
34   // CHECK:       [[U:%.*]] = load <25 x i64>, <25 x i64>* {{.*}}, align 8
35   // CHECK-NEXT:  [[CONV:%.*]] = trunc <25 x i64> [[U]] to <25 x i16>
36   // CHECK-NEXT:  store <25 x i16> [[CONV]], <25 x i16>* {{.*}}, align 2
37   // CHECK-NEXT:  ret void
38 
39   s = (sx5x5)u;
40 }
41 
42 void cast_int_matrix_to_short(ix5x5 i, sx5x5 s) {
43   // CHECK-LABEL: define{{.*}} void @cast_int_matrix_to_short(<25 x i32> %i, <25 x i16> %s)
44   // CHECK:       [[I:%.*]] = load <25 x i32>, <25 x i32>* {{.*}}, align 4
45   // CHECK-NEXT:  [[CONV:%.*]] = trunc <25 x i32> [[I]] to <25 x i16>
46   // CHECK-NEXT:  store <25 x i16> [[CONV]], <25 x i16>* {{.*}}, align 2
47   // CHECK-NEXT:  ret void
48 
49   s = (sx5x5)i;
50 }
51 
52 void cast_int_matrix_to_float(ix5x5 i, fx5x5 f) {
53   // CHECK-LABEL: define{{.*}} void @cast_int_matrix_to_float(<25 x i32> %i, <25 x float> %f)
54   // CHECK:       [[I:%.*]] = load <25 x i32>, <25 x i32>* {{.*}}, align 4
55   // CHECK-NEXT:  [[CONV:%.*]] = bitcast <25 x i32> [[I]] to <25 x float>
56   // CHECK-NEXT:  store <25 x float> [[CONV]], <25 x float>* {{.*}}, align 4
57   // CHECK-NEXT:  ret void
58 
59   f = (fx5x5)i;
60 }
61 
62 void cast_double_matrix_to_int(dx5x5 d, ix5x5 i) {
63   // CHECK-LABEL: define{{.*}} void @cast_double_matrix_to_int(<25 x double> %d, <25 x i32> %i)
64   // CHECK:       [[D:%.*]] = load <25 x double>, <25 x double>* {{.*}}, align 8
65   // CHECK-NEXT:  [[CONV:%.*]] = fptosi <25 x double> [[D]] to <25 x i32>
66   // CHECK-NEXT:  store <25 x i32> [[CONV]], <25 x i32>* {{.*}}, align 4
67   // CHECK-NEXT:  ret void
68 
69   i = (ix5x5)d;
70 }
71 
72 void cast_float_matrix_to_unsigned_short_int(fx5x5 f, unsigned_short_int_5x5 i) {
73   // CHECK-LABEL: define{{.*}} void @cast_float_matrix_to_unsigned_short_int(<25 x float> %f, <25 x i16> %i)
74   // CHECK:       [[F:%.*]] = load <25 x float>, <25 x float>* {{.*}}, align 4
75   // CHECK-NEXT:  [[CONV:%.*]] = fptoui <25 x float> [[F]] to <25 x i16>
76   // CHECK-NEXT:  store <25 x i16> [[CONV]], <25 x i16>* %1, align 2
77   // CHECK-NEXT:  ret void
78 
79   i = (unsigned_short_int_5x5)f;
80 }
81 
82 void cast_double_matrix_to_float(dx5x5 d, fx5x5 f) {
83   // CHECK-LABEL: define{{.*}} void @cast_double_matrix_to_float(<25 x double> %d, <25 x float> %f)
84   // CHECK:       [[D:%.*]] = load <25 x double>, <25 x double>* {{.*}}, align 8
85   // CHECK-NEXT:  [[CONV:%.*]] = fptrunc <25 x double> [[D]] to <25 x float>
86   // CHECK-NEXT:  store <25 x float> [[CONV]], <25 x float>* {{.*}}, align 4
87   // CHECK-NEXT:  ret void
88 
89   f = (fx5x5)d;
90 }
91 
92 void cast_unsigned_short_int_to_unsigned_int(unsigned_short_int_5x5 s, unsigned_int_5x5 i) {
93   // CHECK-LABEL: define{{.*}} void @cast_unsigned_short_int_to_unsigned_int(<25 x i16> %s, <25 x i32> %i)
94   // CHECK:       [[S:%.*]] = load <25 x i16>, <25 x i16>* {{.*}}, align 2
95   // CHECK-NEXT:  [[CONV:%.*]] = zext <25 x i16> [[S]] to <25 x i32>
96   // CHECK-NEXT:  store <25 x i32> [[CONV]], <25 x i32>* {{.*}}, align 4
97   // CHECK-NEXT:  ret void
98 
99   i = (unsigned_int_5x5)s;
100 }
101 
102 void cast_unsigned_long_int_to_unsigned_short_int(unsigned_long_int_5x5 l, unsigned_short_int_5x5 s) {
103   // CHECK-LABEL: define{{.*}} void @cast_unsigned_long_int_to_unsigned_short_int(<25 x i64> %l, <25 x i16> %s)
104   // CHECK:       [[L:%.*]] = load <25 x i64>, <25 x i64>* %0, align 8
105   // CHECK-NEXT:  [[CONV:%.*]] = trunc <25 x i64> [[L]] to <25 x i16>
106   // CHECK-NEXT:  store <25 x i16> [[CONV]], <25 x i16>* {{.*}}, align 2
107   // CHECK-NEXT:  ret void
108 
109   s = (unsigned_short_int_5x5)l;
110 }
111