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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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