1 // RUN: %clang_cc1 -no-opaque-pointers -no-enable-noundef-analysis -fenable-matrix -triple x86_64-apple-darwin %s -emit-llvm -disable-llvm-passes -o - | FileCheck --check-prefixes=COMMON,CHECK64 %s
2 // RUN: %clang_cc1 -no-opaque-pointers -no-enable-noundef-analysis -fenable-matrix -triple i386-apple-darwin %s -emit-llvm -disable-llvm-passes -o - | FileCheck --check-prefixes=COMMON,CHECK32 %s
3
4 // Also check we do not crash when running some middle-end passes. Most
5 // importantly this includes the IR verifier, to ensure we emit valid IR.
6 // RUN: %clang_cc1 -no-opaque-pointers -fenable-matrix -emit-llvm -triple x86_64-apple-darwin %s -o %t
7
8 // Tests for the matrix type builtins.
9
10 typedef double dx5x5_t __attribute__((matrix_type(5, 5)));
11 typedef float fx2x3_t __attribute__((matrix_type(2, 3)));
12 typedef float fx3x2_t __attribute__((matrix_type(3, 2)));
13 typedef int ix20x4_t __attribute__((matrix_type(20, 4)));
14 typedef int ix4x20_t __attribute__((matrix_type(4, 20)));
15 typedef unsigned ux1x6_t __attribute__((matrix_type(1, 6)));
16 typedef unsigned ux6x1_t __attribute__((matrix_type(6, 1)));
17
transpose_double_5x5(dx5x5_t * a)18 void transpose_double_5x5(dx5x5_t *a) {
19 // COMMON-LABEL: define{{.*}} void @transpose_double_5x5(
20 // CHECK32: [[A:%.*]] = load <25 x double>, <25 x double>* {{.*}}, align 4
21 // CHECK64: [[A:%.*]] = load <25 x double>, <25 x double>* {{.*}}, align 8
22 // COMMON-NEXT: [[TRANS:%.*]] = call <25 x double> @llvm.matrix.transpose.v25f64(<25 x double> [[A]], i32 5, i32 5)
23 // COMMON-NEXT: [[AT_ADDR:%.*]] = bitcast [25 x double]* %a_t to <25 x double>*
24 // CHECK32-NEXT: store <25 x double> [[TRANS]], <25 x double>* [[AT_ADDR]], align 4
25 // CHECK64-NEXT: store <25 x double> [[TRANS]], <25 x double>* [[AT_ADDR]], align 8
26
27 dx5x5_t a_t = __builtin_matrix_transpose(*a);
28 }
29
transpose_float_3x2(fx3x2_t * a)30 void transpose_float_3x2(fx3x2_t *a) {
31 // COMMON-LABEL: define{{.*}} void @transpose_float_3x2(
32 // COMMON: [[A:%.*]] = load <6 x float>, <6 x float>* {{.*}}, align 4
33 // COMMON-NEXT: [[TRANS:%.*]] = call <6 x float> @llvm.matrix.transpose.v6f32(<6 x float> [[A]], i32 3, i32 2)
34 // COMMON-NEXT: [[AT_ADDR:%.*]] = bitcast [6 x float]* %a_t to <6 x float>*
35 // COMMON-NEXT: store <6 x float> [[TRANS]], <6 x float>* [[AT_ADDR]], align 4
36
37 fx2x3_t a_t = __builtin_matrix_transpose(*a);
38 }
39
transpose_int_20x4(ix20x4_t * a)40 void transpose_int_20x4(ix20x4_t *a) {
41 // COMMON-LABEL: define{{.*}} void @transpose_int_20x4(
42 // COMMON: [[A:%.*]] = load <80 x i32>, <80 x i32>* {{.*}}, align 4
43 // COMMON-NEXT: [[TRANS:%.*]] = call <80 x i32> @llvm.matrix.transpose.v80i32(<80 x i32> [[A]], i32 20, i32 4)
44 // COMMON-NEXT: [[AT_ADDR:%.*]] = bitcast [80 x i32]* %a_t to <80 x i32>*
45 // COMMON-NEXT: store <80 x i32> [[TRANS]], <80 x i32>* [[AT_ADDR]], align 4
46
47 ix4x20_t a_t = __builtin_matrix_transpose(*a);
48 }
49
50 struct Foo {
51 ux1x6_t in;
52 ux6x1_t out;
53 };
54
transpose_struct_member(struct Foo * F)55 void transpose_struct_member(struct Foo *F) {
56 // COMMON-LABEL: define{{.*}} void @transpose_struct_member(
57 // COMMON: [[M:%.*]] = load <6 x i32>, <6 x i32>* {{.*}}, align 4
58 // COMMON-NEXT: [[M_T:%.*]] = call <6 x i32> @llvm.matrix.transpose.v6i32(<6 x i32> [[M]], i32 1, i32 6)
59 // CHECK32-NEXT: [[F_ADDR:%.*]] = load %struct.Foo*, %struct.Foo** %F.addr, align 4
60 // CHECK64-NEXT: [[F_ADDR:%.*]] = load %struct.Foo*, %struct.Foo** %F.addr, align 8
61 // COMMON-NEXT: [[OUT_PTR:%.*]] = getelementptr inbounds %struct.Foo, %struct.Foo* [[F_ADDR]], i32 0, i32 1
62 // COMMON-NEXT: [[OUT_PTR_C:%.*]] = bitcast [6 x i32]* [[OUT_PTR]] to <6 x i32>*
63 // COMMON-NEXT: store <6 x i32> [[M_T]], <6 x i32>* [[OUT_PTR_C]], align 4
64
65 F->out = __builtin_matrix_transpose(F->in);
66 }
67
transpose_transpose_struct_member(struct Foo * F)68 void transpose_transpose_struct_member(struct Foo *F) {
69 // COMMON-LABEL: define{{.*}} void @transpose_transpose_struct_member(
70 // COMMON: [[M:%.*]] = load <6 x i32>, <6 x i32>* {{.*}}, align 4
71 // COMMON-NEXT: [[M_T:%.*]] = call <6 x i32> @llvm.matrix.transpose.v6i32(<6 x i32> [[M]], i32 1, i32 6)
72 // COMMON-NEXT: [[M_T2:%.*]] = call <6 x i32> @llvm.matrix.transpose.v6i32(<6 x i32> [[M_T]], i32 6, i32 1)
73 // CHECK32-NEXT: [[F_ADDR:%.*]] = load %struct.Foo*, %struct.Foo** %F.addr, align 4
74 // CHECK64-NEXT: [[F_ADDR:%.*]] = load %struct.Foo*, %struct.Foo** %F.addr, align 8
75 // COMMON-NEXT: [[IN_PTR:%.*]] = getelementptr inbounds %struct.Foo, %struct.Foo* [[F_ADDR]], i32 0, i32 0
76 // COMMON-NEXT: [[IN_PTR_C:%.*]] = bitcast [6 x i32]* [[IN_PTR]] to <6 x i32>*
77 // COMMON-NEXT: store <6 x i32> [[M_T2]], <6 x i32>* [[IN_PTR_C]], align 4
78
79 F->in = __builtin_matrix_transpose(__builtin_matrix_transpose(F->in));
80 }
81
82 dx5x5_t get_matrix(void);
83
transpose_rvalue(void)84 void transpose_rvalue(void) {
85 // COMMON-LABEL: define{{.*}} void @transpose_rvalue()
86 // COMMON-NEXT: entry:
87 // CHECK32-NEXT: [[M_T_ADDR:%.*]] = alloca [25 x double], align 4
88 // CHECK64-NEXT: [[M_T_ADDR:%.*]] = alloca [25 x double], align 8
89 // COMMON-NEXT: [[CALL:%.*]] = call <25 x double> @get_matrix()
90 // COMMON-NEXT: [[M_T:%.*]] = call <25 x double> @llvm.matrix.transpose.v25f64(<25 x double> [[CALL]], i32 5, i32 5)
91 // COMMON-NEXT: [[M_T_ADDR_C:%.*]] = bitcast [25 x double]* [[M_T_ADDR]] to <25 x double>*
92 // CHECK32-NEXT: store <25 x double> [[M_T]], <25 x double>* [[M_T_ADDR_C]], align 4
93 // CHECK64-NEXT: store <25 x double> [[M_T]], <25 x double>* [[M_T_ADDR_C]], align 8
94
95 dx5x5_t m_t = __builtin_matrix_transpose(get_matrix());
96 }
97
98 const dx5x5_t global_matrix;
99
transpose_global(void)100 void transpose_global(void) {
101 // COMMON-LABEL: define{{.*}} void @transpose_global()
102 // COMMON-NEXT: entry:
103 // CHECK32-NEXT: [[M_T_ADDR:%.*]] = alloca [25 x double], align 4
104 // CHECK32-NEXT: [[GLOBAL_MATRIX:%.*]] = load <25 x double>, <25 x double>* bitcast ([25 x double]* @global_matrix to <25 x double>*), align 4
105 // CHECK64-NEXT: [[M_T_ADDR:%.*]] = alloca [25 x double], align 8
106 // CHECK64-NEXT: [[GLOBAL_MATRIX:%.*]] = load <25 x double>, <25 x double>* bitcast ([25 x double]* @global_matrix to <25 x double>*), align 8
107 // COMMON-NEXT: [[M_T:%.*]] = call <25 x double> @llvm.matrix.transpose.v25f64(<25 x double> [[GLOBAL_MATRIX]], i32 5, i32 5)
108 // COMMON-NEXT: [[M_T_ADDR_C:%.*]] = bitcast [25 x double]* [[M_T_ADDR]] to <25 x double>*
109 // CHECK32-NEXT: store <25 x double> [[M_T]], <25 x double>* [[M_T_ADDR_C]], align 4
110 // CHECK64-NEXT: store <25 x double> [[M_T]], <25 x double>* [[M_T_ADDR_C]], align 8
111
112 dx5x5_t m_t = __builtin_matrix_transpose(global_matrix);
113 }
114
column_major_load_with_const_stride_double(double * Ptr)115 void column_major_load_with_const_stride_double(double *Ptr) {
116 // COMMON-LABEL: define{{.*}} void @column_major_load_with_const_stride_double(double* %Ptr)
117 // CHECK32: [[PTR:%.*]] = load double*, double** %Ptr.addr, align 4
118 // CHECK32-NEXT: call <25 x double> @llvm.matrix.column.major.load.v25f64.i32(double* align 4 [[PTR]], i32 5, i1 false, i32 5, i32 5)
119 // CHECK64: [[PTR:%.*]] = load double*, double** %Ptr.addr, align 8
120 // CHECK64-NEXT: call <25 x double> @llvm.matrix.column.major.load.v25f64.i64(double* align 8 [[PTR]], i64 5, i1 false, i32 5, i32 5)
121
122 dx5x5_t m_a1 = __builtin_matrix_column_major_load(Ptr, 5, 5, 5);
123 }
124
column_major_load_with_const_stride2_double(double * Ptr)125 void column_major_load_with_const_stride2_double(double *Ptr) {
126 // COMMON-LABEL: define{{.*}} void @column_major_load_with_const_stride2_double(double* %Ptr)
127 // CHECK32: [[PTR:%.*]] = load double*, double** %Ptr.addr, align 4
128 // CHECK32-NEXT: call <25 x double> @llvm.matrix.column.major.load.v25f64.i32(double* align 4 [[PTR]], i32 15, i1 false, i32 5, i32 5)
129 // CHECK64: [[PTR:%.*]] = load double*, double** %Ptr.addr, align 8
130 // CHECK64-NEXT: call <25 x double> @llvm.matrix.column.major.load.v25f64.i64(double* align 8 [[PTR]], i64 15, i1 false, i32 5, i32 5)
131
132 dx5x5_t m_a2 = __builtin_matrix_column_major_load(Ptr, 5, 5, 2 * 3 + 9);
133 }
134
column_major_load_with_variable_stride_ull_float(float * Ptr,unsigned long long S)135 void column_major_load_with_variable_stride_ull_float(float *Ptr, unsigned long long S) {
136 // COMMON-LABEL: define{{.*}} void @column_major_load_with_variable_stride_ull_float(float* %Ptr, i64 %S)
137 // CHECK32: [[S:%.*]] = load i64, i64* %S.addr, align 8
138 // CHECK32-NEXT: [[STRIDE_TRUNC:%.*]] = trunc i64 [[S]] to i32
139 // CHECK32-NEXT: [[PTR:%.*]] = load float*, float** %Ptr.addr, align 4
140 // CHECK32-NEXT: call <6 x float> @llvm.matrix.column.major.load.v6f32.i32(float* align 4 [[PTR]], i32 [[STRIDE_TRUNC]], i1 false, i32 2, i32 3)
141
142 // CHECK64: [[S:%.*]] = load i64, i64* %S.addr, align 8
143 // CHECK64-NEXT: [[PTR:%.*]] = load float*, float** %Ptr.addr, align 8
144 // CHECK64-NEXT: call <6 x float> @llvm.matrix.column.major.load.v6f32.i64(float* align 4 [[PTR]], i64 [[S]], i1 false, i32 2, i32 3)
145
146 fx2x3_t m_b = __builtin_matrix_column_major_load(Ptr, 2, 3, S);
147 }
148
column_major_load_with_stride_math_int(int * Ptr,int S)149 void column_major_load_with_stride_math_int(int *Ptr, int S) {
150 // COMMON-LABEL: define{{.*}} void @column_major_load_with_stride_math_int(i32* %Ptr, i32 %S)
151 // COMMON: [[S:%.*]] = load i32, i32* %S.addr, align 4
152 // COMMON-NEXT: [[STRIDE:%.*]] = add nsw i32 [[S]], 32
153 // CHECK32-NEXT: [[PTR:%.*]] = load i32*, i32** %Ptr.addr, align 4
154 // CHECK32-NEXT: call <80 x i32> @llvm.matrix.column.major.load.v80i32.i32(i32* align 4 [[PTR]], i32 [[STRIDE]], i1 false, i32 4, i32 20)
155 //
156 // CHECK64-NEXT: [[STRIDE_EXT:%.*]] = sext i32 [[STRIDE]] to i64
157 // CHECK64-NEXT: [[PTR:%.*]] = load i32*, i32** %Ptr.addr, align 8
158 // CHECK64-NEXT: call <80 x i32> @llvm.matrix.column.major.load.v80i32.i64(i32* align 4 [[PTR]], i64 [[STRIDE_EXT]], i1 false, i32 4, i32 20)
159
160 ix4x20_t m_c = __builtin_matrix_column_major_load(Ptr, 4, 20, S + 32);
161 }
162
column_major_load_with_stride_math_s_int(int * Ptr,short S)163 void column_major_load_with_stride_math_s_int(int *Ptr, short S) {
164 // COMMON-LABEL: define{{.*}} void @column_major_load_with_stride_math_s_int(i32* %Ptr, i16 signext %S)
165 // COMMON: [[S:%.*]] = load i16, i16* %S.addr, align 2
166 // COMMON-NEXT: [[S_EXT:%.*]] = sext i16 [[S]] to i32
167 // COMMON-NEXT: [[STRIDE:%.*]] = add nsw i32 [[S_EXT]], 32
168 // CHECK32-NEXT: [[PTR:%.*]] = load i32*, i32** %Ptr.addr, align 4
169 // CHECK32-NEXT: %matrix = call <80 x i32> @llvm.matrix.column.major.load.v80i32.i32(i32* align 4 [[PTR]], i32 [[STRIDE]], i1 false, i32 4, i32 20)
170 //
171 // CHECK64-NEXT: [[STRIDE_EXT:%.*]] = sext i32 [[STRIDE]] to i64
172 // CHECK64-NEXT: [[PTR:%.*]] = load i32*, i32** %Ptr.addr, align 8
173 // CHECK64-NEXT: %matrix = call <80 x i32> @llvm.matrix.column.major.load.v80i32.i64(i32* align 4 [[PTR]], i64 [[STRIDE_EXT]], i1 false, i32 4, i32 20)
174
175 ix4x20_t m_c = __builtin_matrix_column_major_load(Ptr, 4, 20, S + 32);
176 }
177
column_major_load_array1(double Ptr[25])178 void column_major_load_array1(double Ptr[25]) {
179 // COMMON-LABEL: define{{.*}} void @column_major_load_array1(double* %Ptr)
180 // CHECK32: [[ADDR:%.*]] = load double*, double** %Ptr.addr, align 4
181 // CHECK32-NEXT: call <25 x double> @llvm.matrix.column.major.load.v25f64.i32(double* align 4 [[ADDR]], i32 5, i1 false, i32 5, i32 5)
182
183 // CHECK64: [[ADDR:%.*]] = load double*, double** %Ptr.addr, align 8
184 // CHECK64-NEXT: call <25 x double> @llvm.matrix.column.major.load.v25f64.i64(double* align 8 [[ADDR]], i64 5, i1 false, i32 5, i32 5)
185
186 dx5x5_t m = __builtin_matrix_column_major_load(Ptr, 5, 5, 5);
187 }
188
column_major_load_array2(void)189 void column_major_load_array2(void) {
190 // COMMON-LABEL: define{{.*}} void @column_major_load_array2() #0 {
191 // COMMON-NEXT: entry:
192 // CHECK32-NEXT: [[PTR:%.*]] = alloca [25 x double], align 8
193 // CHECK32: [[ARRAY_DEC:%.*]] = getelementptr inbounds [25 x double], [25 x double]* [[PTR]], i32 0, i32 0
194 // CHECK32-NEXT: call <25 x double> @llvm.matrix.column.major.load.v25f64.i32(double* align 8 [[ARRAY_DEC]], i32 5, i1 false, i32 5, i32 5)
195
196 // CHECK64-NEXT: [[PTR:%.*]] = alloca [25 x double], align 16
197 // CHECK64: [[ARRAY_DEC:%.*]] = getelementptr inbounds [25 x double], [25 x double]* [[PTR]], i64 0, i64 0
198 // CHECK64-NEXT: call <25 x double> @llvm.matrix.column.major.load.v25f64.i64(double* align 16 [[ARRAY_DEC]], i64 5, i1 false, i32 5, i32 5)
199
200 double Ptr[25];
201 dx5x5_t m = __builtin_matrix_column_major_load(Ptr, 5, 5, 5);
202 }
203
column_major_load_const(const double * Ptr)204 void column_major_load_const(const double *Ptr) {
205 // COMMON-LABEL: define{{.*}} void @column_major_load_const(double* %Ptr)
206 // CHECK32: [[PTR:%.*]] = load double*, double** %Ptr.addr, align 4
207 // CHECK32-NEXT: call <25 x double> @llvm.matrix.column.major.load.v25f64.i32(double* align 4 [[PTR]], i32 5, i1 false, i32 5, i32 5)
208 //
209 // CHECK64: [[PTR:%.*]] = load double*, double** %Ptr.addr, align 8
210 // CHECK64-NEXT: call <25 x double> @llvm.matrix.column.major.load.v25f64.i64(double* align 8 [[PTR]], i64 5, i1 false, i32 5, i32 5)
211
212 dx5x5_t m_a1 = __builtin_matrix_column_major_load(Ptr, 5, 5, 5);
213 }
214
column_major_load_volatile(volatile double * Ptr)215 void column_major_load_volatile(volatile double *Ptr) {
216 // COMMON-LABEL: define{{.*}} void @column_major_load_volatile(double* %Ptr)
217 // CHECK32: [[PTR:%.*]] = load double*, double** %Ptr.addr, align 4
218 // CHECK32-NEXT: call <25 x double> @llvm.matrix.column.major.load.v25f64.i32(double* align 4 [[PTR]], i32 5, i1 true, i32 5, i32 5)
219 //
220 // CHECK64: [[PTR:%.*]] = load double*, double** %Ptr.addr, align 8
221 // CHECK64-NEXT: call <25 x double> @llvm.matrix.column.major.load.v25f64.i64(double* align 8 [[PTR]], i64 5, i1 true, i32 5, i32 5)
222
223 dx5x5_t m_a1 = __builtin_matrix_column_major_load(Ptr, 5, 5, 5);
224 }
225
column_major_store_with_const_stride_double(double * Ptr)226 void column_major_store_with_const_stride_double(double *Ptr) {
227 // COMMON-LABEL: define{{.*}} void @column_major_store_with_const_stride_double(double* %Ptr)
228 // CHECK32: [[M:%.*]] = load <25 x double>, <25 x double>* {{.*}}, align 4
229 // CHECK32-NEXT: [[PTR:%.*]] = load double*, double** %Ptr.addr, align 4
230 // CHECK32-NEXT: call void @llvm.matrix.column.major.store.v25f64.i32(<25 x double> [[M]], double* align 4 [[PTR]], i32 5, i1 false, i32 5, i32 5)
231 //
232 // CHECK64: [[M:%.*]] = load <25 x double>, <25 x double>* {{.*}}, align 8
233 // CHECK64-NEXT: [[PTR:%.*]] = load double*, double** %Ptr.addr, align 8
234 // CHECK64-NEXT: call void @llvm.matrix.column.major.store.v25f64.i64(<25 x double> [[M]], double* align 8 [[PTR]], i64 5, i1 false, i32 5, i32 5)
235
236 dx5x5_t m;
237 __builtin_matrix_column_major_store(m, Ptr, 5);
238 }
239
column_major_store_with_const_stride2_double(double * Ptr)240 void column_major_store_with_const_stride2_double(double *Ptr) {
241 // COMMON-LABEL: define{{.*}} void @column_major_store_with_const_stride2_double(double* %Ptr)
242 // CHECK32: [[M:%.*]] = load <25 x double>, <25 x double>* {{.*}}, align 4
243 // CHECK32-NEXT: [[PTR:%.*]] = load double*, double** %Ptr.addr, align 4
244 // CHECK32-NEXT: call void @llvm.matrix.column.major.store.v25f64.i32(<25 x double> [[M]], double* align 4 [[PTR]], i32 15, i1 false, i32 5, i32 5)
245 //
246 // CHECK64: [[M:%.*]] = load <25 x double>, <25 x double>* {{.*}}, align 8
247 // CHECK64-NEXT: [[PTR:%.*]] = load double*, double** %Ptr.addr, align 8
248 // CHECK64-NEXT: call void @llvm.matrix.column.major.store.v25f64.i64(<25 x double> [[M]], double* align 8 [[PTR]], i64 15, i1 false, i32 5, i32 5)
249 //
250 dx5x5_t m;
251 __builtin_matrix_column_major_store(m, Ptr, 2 * 3 + 9);
252 }
253
column_major_store_with_stride_math_int(int * Ptr,int S)254 void column_major_store_with_stride_math_int(int *Ptr, int S) {
255 // COMMON-LABEL: define{{.*}} void @column_major_store_with_stride_math_int(i32* %Ptr, i32 %S)
256 // COMMON: [[M:%.*]] = load <80 x i32>, <80 x i32>* {{.*}}, align 4
257 // CHECK32-NEXT: [[PTR:%.*]] = load i32*, i32** %Ptr.addr, align 4
258 // CHECK64-NEXT: [[PTR:%.*]] = load i32*, i32** %Ptr.addr, align 8
259 // COMMON-NEXT: [[S:%.*]] = load i32, i32* %S.addr, align 4
260 // COMMON-NEXT: [[ADD:%.*]] = add nsw i32 [[S]], 32
261 // CHECK32-NEXT: call void @llvm.matrix.column.major.store.v80i32.i32(<80 x i32> [[M]], i32* align 4 [[PTR]], i32 [[ADD]], i1 false, i32 4, i32 20)
262 //
263 // CHECK64-NEXT: [[IDX:%.*]] = sext i32 [[ADD]] to i64
264 // CHECK64-NEXT: call void @llvm.matrix.column.major.store.v80i32.i64(<80 x i32> [[M]], i32* align 4 [[PTR]], i64 [[IDX]], i1 false, i32 4, i32 20)
265
266 ix4x20_t m;
267 __builtin_matrix_column_major_store(m, Ptr, S + 32);
268 }
269
column_major_store_with_stride_math_s_int(int * Ptr,short S)270 void column_major_store_with_stride_math_s_int(int *Ptr, short S) {
271 // COMMON-LABEL: define{{.*}} void @column_major_store_with_stride_math_s_int(i32* %Ptr, i16 signext %S)
272 // COMMON: [[M:%.*]] = load <80 x i32>, <80 x i32>* {{.*}}, align 4
273 // CHECK32-NEXT: [[PTR:%.*]] = load i32*, i32** %Ptr.addr, align 4
274 // CHECK64-NEXT: [[PTR:%.*]] = load i32*, i32** %Ptr.addr, align 8
275 // COMMON-NEXT: [[S:%.*]] = load i16, i16* %S.addr, align 2
276 // COMMON-NEXT: [[EXT:%.*]] = sext i16 [[S]] to i32
277 // COMMON-NEXT: [[ADD:%.*]] = add nsw i32 [[EXT]], 2
278 // CHECK32-NEXT: call void @llvm.matrix.column.major.store.v80i32.i32(<80 x i32> [[M]], i32* align 4 [[PTR]], i32 [[ADD]], i1 false, i32 4, i32 20)
279 //
280 // CHECK64-NEXT: [[IDX:%.*]] = sext i32 [[ADD]] to i64
281 // CHECK64-NEXT: call void @llvm.matrix.column.major.store.v80i32.i64(<80 x i32> [[M]], i32* align 4 [[PTR]], i64 [[IDX]], i1 false, i32 4, i32 20)
282
283 ix4x20_t m;
284 __builtin_matrix_column_major_store(m, Ptr, S + 2);
285 }
286
column_major_store_array1(double Ptr[25])287 void column_major_store_array1(double Ptr[25]) {
288 // COMMON-LABEL: define{{.*}} void @column_major_store_array1(double* %Ptr)
289 // CHECK32: [[M:%.*]] = load <25 x double>, <25 x double>* {{.*}}, align 4
290 // CHECK32-NEXT: [[PTR:%.*]] = load double*, double** %Ptr.addr, align 4
291 // CHECK32-NEXT: call void @llvm.matrix.column.major.store.v25f64.i32(<25 x double> [[M]], double* align 4 [[PTR]], i32 5, i1 false, i32 5, i32 5)
292 //
293 // CHECK64: [[M:%.*]] = load <25 x double>, <25 x double>* {{.*}}, align 8
294 // CHECK64-NEXT: [[PTR:%.*]] = load double*, double** %Ptr.addr, align 8
295 // CHECK64-NEXT: call void @llvm.matrix.column.major.store.v25f64.i64(<25 x double> [[M]], double* align 8 [[PTR]], i64 5, i1 false, i32 5, i32 5)
296
297 dx5x5_t m;
298 __builtin_matrix_column_major_store(m, Ptr, 5);
299 }
300
column_major_store_array2(void)301 void column_major_store_array2(void) {
302 // COMMON-LABEL: define{{.*}} void @column_major_store_array2()
303 // CHECK32: [[M:%.*]] = load <25 x double>, <25 x double>* {{.*}}, align 4
304 // CHECK32-NEXT: [[PTR:%.*]] = getelementptr inbounds [25 x double], [25 x double]* %Ptr, i32 0, i32 0
305 // CHECK32-NEXT: call void @llvm.matrix.column.major.store.v25f64.i32(<25 x double> [[M]], double* align 8 [[PTR]], i32 5, i1 false, i32 5, i32 5)
306 //
307 // CHECK64: [[M:%.*]] = load <25 x double>, <25 x double>* {{.*}}, align 8
308 // CHECK64-NEXT: [[PTR:%.*]] = getelementptr inbounds [25 x double], [25 x double]* %Ptr, i64 0, i64 0
309 // CHECK64-NEXT: call void @llvm.matrix.column.major.store.v25f64.i64(<25 x double> [[M]], double* align 16 [[PTR]], i64 5, i1 false, i32 5, i32 5)
310
311 double Ptr[25];
312 dx5x5_t m;
313 __builtin_matrix_column_major_store(m, Ptr, 5);
314 }
315
column_major_store_volatile(volatile double * Ptr)316 void column_major_store_volatile(volatile double *Ptr) {
317 // COMMON-LABEL: define{{.*}} void @column_major_store_volatile(double* %Ptr) #0 {
318 // CHECK32: [[M:%.*]] = load <25 x double>, <25 x double>* {{.*}}, align 4
319 // CHECK32-NEXT: [[PTR:%.*]] = load double*, double** %Ptr.addr, align 4
320 // CHECK32-NEXT: call void @llvm.matrix.column.major.store.v25f64.i32(<25 x double> [[M]], double* align 4 [[PTR]], i32 5, i1 true, i32 5, i32 5)
321 //
322 // CHECK64: [[M:%.*]] = load <25 x double>, <25 x double>* {{.*}}, align 8
323 // CHECK64-NEXT: [[PTR:%.*]] = load double*, double** %Ptr.addr, align 8
324 // CHECK64-NEXT: call void @llvm.matrix.column.major.store.v25f64.i64(<25 x double> [[M]], double* align 8 [[PTR]], i64 5, i1 true, i32 5, i32 5)
325
326 dx5x5_t m;
327 __builtin_matrix_column_major_store(m, Ptr, 5);
328 }
329