164 lines · c
1// RUN: %clang_cc1 -fenable-matrix -triple x86_64-apple-darwin %s -emit-llvm -disable-llvm-passes -o - | FileCheck %s2 3#if !__has_extension(matrix_types)4#error Expected extension 'matrix_types' to be enabled5#endif6 7#if !__has_extension(matrix_types_scalar_division)8#error Expected extension 'matrix_types_scalar_division' to be enabled9#endif10 11typedef double dx5x5_t __attribute__((matrix_type(5, 5)));12 13// CHECK: %struct.Matrix = type { i8, [12 x float], float }14 15void load_store_double(dx5x5_t *a, dx5x5_t *b) {16 // CHECK-LABEL: define{{.*}} void @load_store_double(17 // CHECK-NEXT: entry:18 // CHECK-NEXT: %a.addr = alloca ptr, align 819 // CHECK-NEXT: %b.addr = alloca ptr, align 820 // CHECK-NEXT: store ptr %a, ptr %a.addr, align 821 // CHECK-NEXT: store ptr %b, ptr %b.addr, align 822 // CHECK-NEXT: %0 = load ptr, ptr %b.addr, align 823 // CHECK-NEXT: %1 = load <25 x double>, ptr %0, align 824 // CHECK-NEXT: %2 = load ptr, ptr %a.addr, align 825 // CHECK-NEXT: store <25 x double> %1, ptr %2, align 826 // CHECK-NEXT: ret void27 28 *a = *b;29}30 31typedef float fx3x4_t __attribute__((matrix_type(3, 4)));32void load_store_float(fx3x4_t *a, fx3x4_t *b) {33 // CHECK-LABEL: define{{.*}} void @load_store_float(34 // CHECK-NEXT: entry:35 // CHECK-NEXT: %a.addr = alloca ptr, align 836 // CHECK-NEXT: %b.addr = alloca ptr, align 837 // CHECK-NEXT: store ptr %a, ptr %a.addr, align 838 // CHECK-NEXT: store ptr %b, ptr %b.addr, align 839 // CHECK-NEXT: %0 = load ptr, ptr %b.addr, align 840 // CHECK-NEXT: %1 = load <12 x float>, ptr %0, align 441 // CHECK-NEXT: %2 = load ptr, ptr %a.addr, align 842 // CHECK-NEXT: store <12 x float> %1, ptr %2, align 443 // CHECK-NEXT: ret void44 45 *a = *b;46}47 48typedef int ix3x4_t __attribute__((matrix_type(4, 3)));49void load_store_int(ix3x4_t *a, ix3x4_t *b) {50 // CHECK-LABEL: define{{.*}} void @load_store_int(51 // CHECK-NEXT: entry:52 // CHECK-NEXT: %a.addr = alloca ptr, align 853 // CHECK-NEXT: %b.addr = alloca ptr, align 854 // CHECK-NEXT: store ptr %a, ptr %a.addr, align 855 // CHECK-NEXT: store ptr %b, ptr %b.addr, align 856 // CHECK-NEXT: %0 = load ptr, ptr %b.addr, align 857 // CHECK-NEXT: %1 = load <12 x i32>, ptr %0, align 458 // CHECK-NEXT: %2 = load ptr, ptr %a.addr, align 859 // CHECK-NEXT: store <12 x i32> %1, ptr %2, align 460 // CHECK-NEXT: ret void61 62 *a = *b;63}64 65typedef unsigned long long ullx3x4_t __attribute__((matrix_type(4, 3)));66void load_store_ull(ullx3x4_t *a, ullx3x4_t *b) {67 // CHECK-LABEL: define{{.*}} void @load_store_ull(68 // CHECK-NEXT: entry:69 // CHECK-NEXT: %a.addr = alloca ptr, align 870 // CHECK-NEXT: %b.addr = alloca ptr, align 871 // CHECK-NEXT: store ptr %a, ptr %a.addr, align 872 // CHECK-NEXT: store ptr %b, ptr %b.addr, align 873 // CHECK-NEXT: %0 = load ptr, ptr %b.addr, align 874 // CHECK-NEXT: %1 = load <12 x i64>, ptr %0, align 875 // CHECK-NEXT: %2 = load ptr, ptr %a.addr, align 876 // CHECK-NEXT: store <12 x i64> %1, ptr %2, align 877 // CHECK-NEXT: ret void78 79 *a = *b;80}81 82typedef __fp16 fp16x3x4_t __attribute__((matrix_type(4, 3)));83void load_store_fp16(fp16x3x4_t *a, fp16x3x4_t *b) {84 // CHECK-LABEL: define{{.*}} void @load_store_fp16(85 // CHECK-NEXT: entry:86 // CHECK-NEXT: %a.addr = alloca ptr, align 887 // CHECK-NEXT: %b.addr = alloca ptr, align 888 // CHECK-NEXT: store ptr %a, ptr %a.addr, align 889 // CHECK-NEXT: store ptr %b, ptr %b.addr, align 890 // CHECK-NEXT: %0 = load ptr, ptr %b.addr, align 891 // CHECK-NEXT: %1 = load <12 x half>, ptr %0, align 292 // CHECK-NEXT: %2 = load ptr, ptr %a.addr, align 893 // CHECK-NEXT: store <12 x half> %1, ptr %2, align 294 // CHECK-NEXT: ret void95 96 *a = *b;97}98 99typedef float fx3x3_t __attribute__((matrix_type(3, 3)));100 101void parameter_passing(fx3x3_t a, fx3x3_t *b) {102 // CHECK-LABEL: define{{.*}} void @parameter_passing(103 // CHECK-NEXT: entry:104 // CHECK-NEXT: %a.addr = alloca [9 x float], align 4105 // CHECK-NEXT: %b.addr = alloca ptr, align 8106 // CHECK-NEXT: store <9 x float> %a, ptr %a.addr, align 4107 // CHECK-NEXT: store ptr %b, ptr %b.addr, align 8108 // CHECK-NEXT: %0 = load <9 x float>, ptr %a.addr, align 4109 // CHECK-NEXT: %1 = load ptr, ptr %b.addr, align 8110 // CHECK-NEXT: store <9 x float> %0, ptr %1, align 4111 // CHECK-NEXT: ret void112 *b = a;113}114 115fx3x3_t return_matrix(fx3x3_t *a) {116 // CHECK-LABEL: define{{.*}} <9 x float> @return_matrix117 // CHECK-NEXT: entry:118 // CHECK-NEXT: %a.addr = alloca ptr, align 8119 // CHECK-NEXT: store ptr %a, ptr %a.addr, align 8120 // CHECK-NEXT: %0 = load ptr, ptr %a.addr, align 8121 // CHECK-NEXT: %1 = load <9 x float>, ptr %0, align 4122 // CHECK-NEXT: ret <9 x float> %1123 return *a;124}125 126typedef struct {127 char Tmp1;128 fx3x4_t Data;129 float Tmp2;130} Matrix;131 132void matrix_struct(Matrix *a, Matrix *b) {133 // CHECK-LABEL: define{{.*}} void @matrix_struct(134 // CHECK-NEXT: entry:135 // CHECK-NEXT: %a.addr = alloca ptr, align 8136 // CHECK-NEXT: %b.addr = alloca ptr, align 8137 // CHECK-NEXT: store ptr %a, ptr %a.addr, align 8138 // CHECK-NEXT: store ptr %b, ptr %b.addr, align 8139 // CHECK-NEXT: %0 = load ptr, ptr %a.addr, align 8140 // CHECK-NEXT: %Data = getelementptr inbounds nuw %struct.Matrix, ptr %0, i32 0, i32 1141 // CHECK-NEXT: %1 = load <12 x float>, ptr %Data, align 4142 // CHECK-NEXT: %2 = load ptr, ptr %b.addr, align 8143 // CHECK-NEXT: %Data1 = getelementptr inbounds nuw %struct.Matrix, ptr %2, i32 0, i32 1144 // CHECK-NEXT: store <12 x float> %1, ptr %Data1, align 4145 // CHECK-NEXT: ret void146 b->Data = a->Data;147}148 149typedef double dx4x4_t __attribute__((matrix_type(4, 4)));150void matrix_inline_asm_memory_readwrite(void) {151 // CHECK-LABEL: define{{.*}} void @matrix_inline_asm_memory_readwrite()152 // CHECK-NEXT: entry:153 // CHECK-NEXT: [[ALLOCA:%.+]] = alloca [16 x double], align 8154 // CHECK-NEXT: [[VAL:%.+]] = load <16 x double>, ptr [[ALLOCA]], align 8155 // CHECK-NEXT: call void asm sideeffect "", "=*r|m,0,~{memory},~{dirflag},~{fpsr},~{flags}"(ptr elementtype(<16 x double>) [[ALLOCA]], <16 x double> [[VAL]])156 // CHECK-NEXT: ret void157 158 dx4x4_t m;159 asm volatile(""160 : "+r,m"(m)161 :162 : "memory");163}164