brintos

brintos / llvm-project-archived public Read only

0
0
Text · 18.5 KiB · de28dcd Raw
404 lines · cpp
1// RUN: %clang_cc1 -Wno-error=return-type -no-enable-noundef-analysis -fenable-matrix -fclang-abi-compat=latest -triple x86_64-apple-darwin %s -emit-llvm -disable-llvm-passes -o - -std=c++17 | FileCheck %s2 3typedef double dx5x5_t __attribute__((matrix_type(5, 5)));4typedef float fx3x4_t __attribute__((matrix_type(3, 4)));5 6// CHECK: %struct.Matrix = type { i8, [12 x float], float }7 8void load_store(dx5x5_t *a, dx5x5_t *b) {9  // CHECK-LABEL:  define{{.*}} void @_Z10load_storePu11matrix_typeILm5ELm5EdES0_(10  // CHECK-NEXT:  entry:11  // CHECK-NEXT:    %a.addr = alloca ptr, align 812  // CHECK-NEXT:    %b.addr = alloca ptr, align 813  // CHECK-NEXT:    store ptr %a, ptr %a.addr, align 814  // CHECK-NEXT:    store ptr %b, ptr %b.addr, align 815  // CHECK-NEXT:    %0 = load ptr, ptr %b.addr, align 816  // CHECK-NEXT:    %1 = load <25 x double>, ptr %0, align 817  // CHECK-NEXT:    %2 = load ptr, ptr %a.addr, align 818  // CHECK-NEXT:    store <25 x double> %1, ptr %2, align 819  // CHECK-NEXT:   ret void20 21  *a = *b;22}23 24typedef float fx3x3_t __attribute__((matrix_type(3, 3)));25 26void parameter_passing(fx3x3_t a, fx3x3_t *b) {27  // CHECK-LABEL: define{{.*}} void @_Z17parameter_passingu11matrix_typeILm3ELm3EfEPS_(28  // CHECK-NEXT:  entry:29  // CHECK-NEXT:    %a.addr = alloca [9 x float], align 430  // CHECK-NEXT:    %b.addr = alloca ptr, align 831  // CHECK-NEXT:    store <9 x float> %a, ptr %a.addr, align 432  // CHECK-NEXT:    store ptr %b, ptr %b.addr, align 833  // CHECK-NEXT:    %0 = load <9 x float>, ptr %a.addr, align 434  // CHECK-NEXT:    %1 = load ptr, ptr %b.addr, align 835  // CHECK-NEXT:    store <9 x float> %0, ptr %1, align 436  // CHECK-NEXT:    ret void37  *b = a;38}39 40fx3x3_t return_matrix(fx3x3_t *a) {41  // CHECK-LABEL: define{{.*}} <9 x float> @_Z13return_matrixPu11matrix_typeILm3ELm3EfE(42  // CHECK-NEXT:  entry:43  // CHECK-NEXT:    %a.addr = alloca ptr, align 844  // CHECK-NEXT:    store ptr %a, ptr %a.addr, align 845  // CHECK-NEXT:    %0 = load ptr, ptr %a.addr, align 846  // CHECK-NEXT:    %1 = load <9 x float>, ptr %0, align 447  // CHECK-NEXT:    ret <9 x float> %148  return *a;49}50 51struct Matrix {52  char Tmp1;53  fx3x4_t Data;54  float Tmp2;55};56 57void matrix_struct_pointers(Matrix *a, Matrix *b) {58  // CHECK-LABEL: define{{.*}} void @_Z22matrix_struct_pointersP6MatrixS0_(59  // CHECK-NEXT:  entry:60  // CHECK-NEXT:    %a.addr = alloca ptr, align 861  // CHECK-NEXT:    %b.addr = alloca ptr, align 862  // CHECK-NEXT:    store ptr %a, ptr %a.addr, align 863  // CHECK-NEXT:    store ptr %b, ptr %b.addr, align 864  // CHECK-NEXT:    %0 = load ptr, ptr %a.addr, align 865  // CHECK-NEXT:    %Data = getelementptr inbounds nuw %struct.Matrix, ptr %0, i32 0, i32 166  // CHECK-NEXT:    %1 = load <12 x float>, ptr %Data, align 467  // CHECK-NEXT:    %2 = load ptr, ptr %b.addr, align 868  // CHECK-NEXT:    %Data1 = getelementptr inbounds nuw %struct.Matrix, ptr %2, i32 0, i32 169  // CHECK-NEXT:    store <12 x float> %1, ptr %Data1, align 470  // CHECK-NEXT:    ret void71  b->Data = a->Data;72}73 74void matrix_struct_reference(Matrix &a, Matrix &b) {75  // CHECK-LABEL: define{{.*}} void @_Z23matrix_struct_referenceR6MatrixS0_(76  // CHECK-NEXT:  entry:77  // CHECK-NEXT:    %a.addr = alloca ptr, align 878  // CHECK-NEXT:    %b.addr = alloca ptr, align 879  // CHECK-NEXT:    store ptr %a, ptr %a.addr, align 880  // CHECK-NEXT:    store ptr %b, ptr %b.addr, align 881  // CHECK-NEXT:    %0 = load ptr, ptr %a.addr, align 882  // CHECK-NEXT:    %Data = getelementptr inbounds nuw %struct.Matrix, ptr %0, i32 0, i32 183  // CHECK-NEXT:    %1 = load <12 x float>, ptr %Data, align 484  // CHECK-NEXT:    %2 = load ptr, ptr %b.addr, align 885  // CHECK-NEXT:    %Data1 = getelementptr inbounds nuw %struct.Matrix, ptr %2, i32 0, i32 186  // CHECK-NEXT:    store <12 x float> %1, ptr %Data1, align 487  // CHECK-NEXT:    ret void88  b.Data = a.Data;89}90 91class MatrixClass {92public:93  int Tmp1;94  fx3x4_t Data;95  long Tmp2;96};97 98void matrix_class_reference(MatrixClass &a, MatrixClass &b) {99  // CHECK-LABEL: define{{.*}} void @_Z22matrix_class_referenceR11MatrixClassS0_(100  // CHECK-NEXT:  entry:101  // CHECK-NEXT:    %a.addr = alloca ptr, align 8102  // CHECK-NEXT:    %b.addr = alloca ptr, align 8103  // CHECK-NEXT:    store ptr %a, ptr %a.addr, align 8104  // CHECK-NEXT:    store ptr %b, ptr %b.addr, align 8105  // CHECK-NEXT:    %0 = load ptr, ptr %a.addr, align 8106  // CHECK-NEXT:    %Data = getelementptr inbounds nuw %class.MatrixClass, ptr %0, i32 0, i32 1107  // CHECK-NEXT:    %1 = load <12 x float>, ptr %Data, align 4108  // CHECK-NEXT:    %2 = load ptr, ptr %b.addr, align 8109  // CHECK-NEXT:    %Data1 = getelementptr inbounds nuw %class.MatrixClass, ptr %2, i32 0, i32 1110  // CHECK-NEXT:    store <12 x float> %1, ptr %Data1, align 4111  // CHECK-NEXT:    ret void112  b.Data = a.Data;113}114 115template <typename Ty, unsigned Rows, unsigned Cols>116class MatrixClassTemplate {117public:118  using MatrixTy = Ty __attribute__((matrix_type(Rows, Cols)));119  int Tmp1;120  MatrixTy Data;121  long Tmp2;122};123 124template <typename Ty, unsigned Rows, unsigned Cols>125void matrix_template_reference(MatrixClassTemplate<Ty, Rows, Cols> &a, MatrixClassTemplate<Ty, Rows, Cols> &b) {126  b.Data = a.Data;127}128 129MatrixClassTemplate<float, 10, 15> matrix_template_reference_caller(float *Data) {130  // CHECK-LABEL: define{{.*}} void @_Z32matrix_template_reference_callerPf(ptr dead_on_unwind noalias writable sret(%class.MatrixClassTemplate) align 8 %agg.result, ptr %Data131  // CHECK-NEXT:  entry:132  // CHECK-NEXT:    %Data.addr = alloca ptr, align 8133  // CHECK-NEXT:    %Arg = alloca %class.MatrixClassTemplate, align 8134  // CHECK-NEXT:    store ptr %Data, ptr %Data.addr, align 8135  // CHECK-NEXT:    %0 = load ptr, ptr %Data.addr, align 8136  // CHECK-NEXT:    %1 = load <150 x float>, ptr %0, align 4137  // CHECK-NEXT:    %Data1 = getelementptr inbounds nuw %class.MatrixClassTemplate, ptr %Arg, i32 0, i32 1138  // CHECK-NEXT:    store <150 x float> %1, ptr %Data1, align 4139  // CHECK-NEXT:    call void @_Z25matrix_template_referenceIfLj10ELj15EEvR19MatrixClassTemplateIT_XT0_EXT1_EES3_(ptr nonnull align 8 dereferenceable(616) %Arg, ptr nonnull align 8 dereferenceable(616) %agg.result)140  // CHECK-NEXT:    ret void141 142  // CHECK-LABEL: define linkonce_odr void @_Z25matrix_template_referenceIfLj10ELj15EEvR19MatrixClassTemplateIT_XT0_EXT1_EES3_(ptr nonnull align 8 dereferenceable(616) %a, ptr nonnull align 8 dereferenceable(616) %b)143  // CHECK-NEXT:  entry:144  // CHECK-NEXT:    %a.addr = alloca ptr, align 8145  // CHECK-NEXT:    %b.addr = alloca ptr, align 8146  // CHECK-NEXT:    store ptr %a, ptr %a.addr, align 8147  // CHECK-NEXT:    store ptr %b, ptr %b.addr, align 8148  // CHECK-NEXT:    %0 = load ptr, ptr %a.addr, align 8149  // CHECK-NEXT:    %Data = getelementptr inbounds nuw %class.MatrixClassTemplate, ptr %0, i32 0, i32 1150  // CHECK-NEXT:    %1 = load <150 x float>, ptr %Data, align 4151  // CHECK-NEXT:    %2 = load ptr, ptr %b.addr, align 8152  // CHECK-NEXT:    %Data1 = getelementptr inbounds nuw %class.MatrixClassTemplate, ptr %2, i32 0, i32 1153  // CHECK-NEXT:    store <150 x float> %1, ptr %Data1, align 4154  // CHECK-NEXT:    ret void155 156  MatrixClassTemplate<float, 10, 15> Result, Arg;157  Arg.Data = *((MatrixClassTemplate<float, 10, 15>::MatrixTy *)Data);158  matrix_template_reference(Arg, Result);159  return Result;160}161 162template <class T, unsigned long R, unsigned long C>163using matrix = T __attribute__((matrix_type(R, C)));164 165template <int N>166struct selector {};167 168template <class T, unsigned long R, unsigned long C>169selector<0> use_matrix(matrix<T, R, C> &m) {}170 171template <class T, unsigned long R>172selector<1> use_matrix(matrix<T, R, 10> &m) {}173 174template <class T>175selector<2> use_matrix(matrix<T, 10, 10> &m) {}176 177template <class T, unsigned long C>178selector<3> use_matrix(matrix<T, 10, C> &m) {}179 180template <unsigned long R, unsigned long C>181selector<4> use_matrix(matrix<float, R, C> &m) {}182 183void test_template_deduction() {184 185  // CHECK-LABEL: define{{.*}} void @_Z23test_template_deductionv()186  // CHECK-NEXT:  entry:187  // CHECK-NEXT:    %m0 = alloca [120 x i32], align 4188  // CHECK-NEXT:    %w = alloca %struct.selector, align 1189  // CHECK-NEXT:    %undef.agg.tmp = alloca %struct.selector, align 1190  // CHECK-NEXT:    %m1 = alloca [100 x i32], align 4191  // CHECK-NEXT:    %x = alloca %struct.selector.0, align 1192  // CHECK-NEXT:    %undef.agg.tmp1 = alloca %struct.selector.0, align 1193  // CHECK-NEXT:    %m2 = alloca [120 x i32], align 4194  // CHECK-NEXT:    %y = alloca %struct.selector.1, align 1195  // CHECK-NEXT:    %undef.agg.tmp2 = alloca %struct.selector.1, align 1196  // CHECK-NEXT:    %m3 = alloca [144 x i32], align 4197  // CHECK-NEXT:    %z = alloca %struct.selector.2, align 1198  // CHECK-NEXT:    %undef.agg.tmp3 = alloca %struct.selector.2, align 1199  // CHECK-NEXT:    %m4 = alloca [144 x float], align 4200  // CHECK-NEXT:    %v = alloca %struct.selector.3, align 1201  // CHECK-NEXT:    %undef.agg.tmp4 = alloca %struct.selector.3, align 1202  // CHECK-NEXT:    call void @_Z10use_matrixIiLm12EE8selectorILi3EERu11matrix_typeILm10EXT0_ET_E(ptr nonnull align 4 dereferenceable(480) %m0)203  // CHECK-NEXT:    call void @_Z10use_matrixIiE8selectorILi2EERu11matrix_typeILm10ELm10ET_E(ptr nonnull align 4 dereferenceable(400) %m1)204  // CHECK-NEXT:    call void @_Z10use_matrixIiLm12EE8selectorILi1EERu11matrix_typeIXT0_ELm10ET_E(ptr nonnull align 4 dereferenceable(480) %m2)205  // CHECK-NEXT:    call void @_Z10use_matrixIiLm12ELm12EE8selectorILi0EERu11matrix_typeIXT0_EXT1_ET_E(ptr nonnull align 4 dereferenceable(576) %m3)206  // CHECK-NEXT:    call void @_Z10use_matrixILm12ELm12EE8selectorILi4EERu11matrix_typeIXT_EXT0_EfE(ptr nonnull align 4 dereferenceable(576) %m4)207  // CHECK-NEXT:    ret void208 209  // CHECK-LABEL: define linkonce_odr void @_Z10use_matrixIiLm12EE8selectorILi3EERu11matrix_typeILm10EXT0_ET_E(ptr nonnull align 4 dereferenceable(480) %m)210  // CHECK-NEXT:  entry:211  // CHECK-NEXT:    %m.addr = alloca ptr, align 8212  // CHECK-NEXT:    store ptr %m, ptr %m.addr, align 8213  // CHECK-NEXT:    call void @llvm.trap()214  // CHECK-NEXT:    unreachable215 216  // CHECK-LABEL: define linkonce_odr void @_Z10use_matrixIiE8selectorILi2EERu11matrix_typeILm10ELm10ET_E(ptr nonnull align 4 dereferenceable(400) %m)217  // CHECK-NEXT:  entry:218  // CHECK-NEXT:    %m.addr = alloca ptr, align 8219  // CHECK-NEXT:    store ptr %m, ptr %m.addr, align 8220  // CHECK-NEXT:    call void @llvm.trap()221  // CHECK-NEXT:    unreachable222 223  // CHECK-LABEL: define linkonce_odr void @_Z10use_matrixIiLm12EE8selectorILi1EERu11matrix_typeIXT0_ELm10ET_E(ptr nonnull align 4 dereferenceable(480) %m)224  // CHECK-NEXT:  entry:225  // CHECK-NEXT:    %m.addr = alloca ptr, align 8226  // CHECK-NEXT:    store ptr %m, ptr %m.addr, align 8227  // CHECK-NEXT:    call void @llvm.trap()228  // CHECK-NEXT:    unreachable229 230  // CHECK-LABEL: define linkonce_odr void @_Z10use_matrixIiLm12ELm12EE8selectorILi0EERu11matrix_typeIXT0_EXT1_ET_E(ptr nonnull align 4 dereferenceable(576) %m)231  // CHECK-NEXT:  entry:232  // CHECK-NEXT:    %m.addr = alloca ptr, align 8233  // CHECK-NEXT:    store ptr %m, ptr %m.addr, align 8234  // CHECK-NEXT:    call void @llvm.trap()235  // CHECK-NEXT:    unreachable236 237  // CHECK-LABEL: define linkonce_odr void @_Z10use_matrixILm12ELm12EE8selectorILi4EERu11matrix_typeIXT_EXT0_EfE(ptr nonnull align 4 dereferenceable(576)238  // CHECK-NEXT:  entry:239  // CHECK-NEXT:    %m.addr = alloca ptr, align 8240  // CHECK-NEXT:    store ptr %m, ptr %m.addr, align 8241  // CHECK-NEXT:    call void @llvm.trap()242  // CHECK-NEXT:    unreachable243 244  matrix<int, 10, 12> m0;245  selector<3> w = use_matrix(m0);246  matrix<int, 10, 10> m1;247  selector<2> x = use_matrix(m1);248  matrix<int, 12, 10> m2;249  selector<1> y = use_matrix(m2);250  matrix<int, 12, 12> m3;251  selector<0> z = use_matrix(m3);252  matrix<float, 12, 12> m4;253  selector<4> v = use_matrix(m4);254}255 256template <auto R>257void foo(matrix<int, R, 10> &m) {258}259 260void test_auto_t() {261  // CHECK-LABEL: define{{.*}} void @_Z11test_auto_tv()262  // CHECK-NEXT:  entry:263  // CHECK-NEXT:    %m = alloca [130 x i32], align 4264  // CHECK-NEXT:    call void @_Z3fooITnDaLm13EEvRu11matrix_typeIXT_ELm10EiE(ptr nonnull align 4 dereferenceable(520) %m)265  // CHECK-NEXT:    ret void266 267  // CHECK-LABEL: define linkonce_odr void @_Z3fooITnDaLm13EEvRu11matrix_typeIXT_ELm10EiE(ptr nonnull align 4 dereferenceable(520) %m)268  // CHECK-NEXT:  entry:269  // CHECK-NEXT:    %m.addr = alloca ptr, align 8270  // CHECK-NEXT:    store ptr %m, ptr %m.addr, align 8271  // CHECK-NEXT:    ret void272 273  matrix<int, 13, 10> m;274  foo(m);275}276 277template <unsigned long R, unsigned long C>278matrix<float, R + 1, C + 2> use_matrix_2(matrix<int, R, C> &m) {}279 280template <unsigned long R, unsigned long C>281selector<0> use_matrix_2(matrix<int, R + 2, C / 2> &m1, matrix<float, R, C> &m2) {}282 283template <unsigned long R, unsigned long C>284selector<1> use_matrix_2(matrix<int, R + C, C> &m1, matrix<float, R, C - R> &m2) {}285 286template <unsigned long R>287matrix<float, R + R, R - 3> use_matrix_2(matrix<int, R, 10> &m1) {}288 289template <unsigned long R>290selector<2> use_matrix_3(matrix<int, R - 2, R> &m) {}291 292void test_use_matrix_2() {293  // CHECK-LABEL: define{{.*}} void @_Z17test_use_matrix_2v()294  // CHECK-NEXT:  entry:295  // CHECK-NEXT:    %m1 = alloca [24 x i32], align 4296  // CHECK-NEXT:    %r1 = alloca [40 x float], align 4297  // CHECK-NEXT:    %m2 = alloca [24 x float], align 4298  // CHECK-NEXT:    %r2 = alloca %struct.selector.2, align 1299  // CHECK-NEXT:    %undef.agg.tmp = alloca %struct.selector.2, align 1300  // CHECK-NEXT:    %m3 = alloca [104 x i32], align 4301  // CHECK-NEXT:    %m4 = alloca [15 x float], align 4302  // CHECK-NEXT:    %r3 = alloca %struct.selector.1, align 1303  // CHECK-NEXT:    %undef.agg.tmp1 = alloca %struct.selector.1, align 1304  // CHECK-NEXT:    %m5 = alloca [50 x i32], align 4305  // CHECK-NEXT:    %r4 = alloca [20 x float], align 4306  // CHECK-NEXT:    %r5 = alloca %struct.selector.0, align 1307  // CHECK-NEXT:    %undef.agg.tmp3 = alloca %struct.selector.0, align 1308  // CHECK-NEXT:    %call = call <40 x float> @_Z12use_matrix_2ILm4ELm6EEu11matrix_typeIXplT_Li1EEXplT0_Li2EEfERu11matrix_typeIXT_EXT0_EiE(ptr nonnull align 4 dereferenceable(96) %m1)309  // CHECK-NEXT:    store <40 x float> %call, ptr %r1, align 4310  // CHECK-NEXT:    call void @_Z12use_matrix_2ILm2ELm12EE8selectorILi0EERu11matrix_typeIXplT_Li2EEXdvT0_Li2EEiERu11matrix_typeIXT_EXT0_EfE(ptr nonnull align 4 dereferenceable(96) %m1, ptr nonnull align 4 dereferenceable(96) %m2)311  // CHECK-NEXT:    call void @_Z12use_matrix_2ILm5ELm8EE8selectorILi1EERu11matrix_typeIXplT_T0_EXT0_EiERu11matrix_typeIXT_EXmiT0_T_EfE(ptr nonnull align 4 dereferenceable(416) %m3, ptr nonnull align 4 dereferenceable(60) %m4)312  // CHECK-NEXT:    %call2 = call <20 x float> @_Z12use_matrix_2ILm5EEu11matrix_typeIXplT_T_EXmiT_Li3EEfERu11matrix_typeIXT_ELm10EiE(ptr nonnull align 4 dereferenceable(200) %m5)313  // CHECK-NEXT:    store <20 x float> %call2, ptr %r4, align 4314  // CHECK-NEXT:    call void @_Z12use_matrix_3ILm6EE8selectorILi2EERu11matrix_typeIXmiT_Li2EEXT_EiE(ptr nonnull align 4 dereferenceable(96) %m1)315  // CHECK-NEXT:    ret void316 317  // CHECK-LABEL: define linkonce_odr <40 x float> @_Z12use_matrix_2ILm4ELm6EEu11matrix_typeIXplT_Li1EEXplT0_Li2EEfERu11matrix_typeIXT_EXT0_EiE(ptr nonnull align 4 dereferenceable(96) %m)318  // CHECK-NEXT:  entry:319  // CHECK-NEXT:    %m.addr = alloca ptr, align 8320  // CHECK-NEXT:    store ptr %m, ptr %m.addr, align 8321  // CHECK-NEXT:    call void @llvm.trap()322  // CHECK-NEXT:    unreachable323 324  // CHECK-LABEL: define linkonce_odr void @_Z12use_matrix_2ILm2ELm12EE8selectorILi0EERu11matrix_typeIXplT_Li2EEXdvT0_Li2EEiERu11matrix_typeIXT_EXT0_EfE(ptr nonnull align 4 dereferenceable(96) %m1, ptr nonnull align 4 dereferenceable(96) %m2)325  // CHECK-NEXT:  entry:326  // CHECK-NEXT:    %m1.addr = alloca ptr, align 8327  // CHECK-NEXT:    %m2.addr = alloca ptr, align 8328  // CHECK-NEXT:    store ptr %m1, ptr %m1.addr, align 8329  // CHECK-NEXT:    store ptr %m2, ptr %m2.addr, align 8330  // CHECK-NEXT:    call void @llvm.trap()331  // CHECK-NEXT:    unreachable332 333  // CHECK-LABEL: define linkonce_odr void @_Z12use_matrix_2ILm5ELm8EE8selectorILi1EERu11matrix_typeIXplT_T0_EXT0_EiERu11matrix_typeIXT_EXmiT0_T_EfE(ptr nonnull align 4 dereferenceable(416) %m1, ptr nonnull align 4 dereferenceable(60) %m2)334  // CHECK-NEXT:  entry:335  // CHECK-NEXT:    %m1.addr = alloca ptr, align 8336  // CHECK-NEXT:    %m2.addr = alloca ptr, align 8337  // CHECK-NEXT:    store ptr %m1, ptr %m1.addr, align 8338  // CHECK-NEXT:    store ptr %m2, ptr %m2.addr, align 8339  // CHECK-NEXT:    call void @llvm.trap()340  // CHECK-NEXT:    unreachable341 342  // CHECK-LABEL: define linkonce_odr <20 x float> @_Z12use_matrix_2ILm5EEu11matrix_typeIXplT_T_EXmiT_Li3EEfERu11matrix_typeIXT_ELm10EiE(ptr nonnull align 4 dereferenceable(200) %m1)343  // CHECK-NEXT:  entry:344  // CHECK-NEXT:    %m1.addr = alloca ptr, align 8345  // CHECK-NEXT:    store ptr %m1, ptr %m1.addr, align 8346  // CHECK-NEXT:    call void @llvm.trap()347  // CHECK-NEXT:    unreachable348 349  // CHECK-LABEL: define linkonce_odr void @_Z12use_matrix_3ILm6EE8selectorILi2EERu11matrix_typeIXmiT_Li2EEXT_EiE(ptr nonnull align 4 dereferenceable(96) %m)350  // CHECK-NEXT:  entry:351  // CHECK-NEXT:    %m.addr = alloca ptr, align 8352  // CHECK-NEXT:    store ptr %m, ptr %m.addr, align 8353  // CHECK-NEXT:    call void @llvm.trap()354  // CHECK-NEXT:    unreachable355 356  matrix<int, 4, 6> m1;357  matrix<float, 5, 8> r1 = use_matrix_2(m1);358 359  matrix<float, 2, 12> m2;360  selector<0> r2 = use_matrix_2(m1, m2);361 362  matrix<int, 13, 8> m3;363  matrix<float, 5, 3> m4;364  selector<1> r3 = use_matrix_2(m3, m4);365 366  matrix<int, 5, 10> m5;367  matrix<float, 10, 2> r4 = use_matrix_2(m5);368 369  selector<2> r5 = use_matrix_3(m1);370}371 372// CHECK-LABEL: define void @_Z22test_pseudo_destructorv()373// CHECK-NEXT: entry:374// CHECK-NEXT:   %a = alloca [25 x double], align 8375// CHECK-NEXT:   %b = alloca [12 x float], align 4376// CHECK-NEXT:   %0 = load <25 x double>, ptr %a, align 8377// CHECK-NEXT:   call void @_Z17pseudo_destructorIu11matrix_typeILm5ELm5EdEEvT_(<25 x double> %0)378// CHECK-NEXT:   %1 = load <12 x float>, ptr %b, align 4379// CHECK-NEXT:   call void @_Z17pseudo_destructorIu11matrix_typeILm3ELm4EfEEvT_(<12 x float> %1)380// CHECK-NEXT:   ret void381 382// CHECK-LABEL: define linkonce_odr void @_Z17pseudo_destructorIu11matrix_typeILm5ELm5EdEEvT_(<25 x double> %t)383// CHECK-NEXT: entry:384// CHECK-NEXT:   %t.addr = alloca [25 x double], align 8385// CHECK-NEXT:   store <25 x double> %t, ptr %t.addr, align 8386// CHECK-NEXT:   ret void387 388// CHECK-LABEL: define linkonce_odr void @_Z17pseudo_destructorIu11matrix_typeILm3ELm4EfEEvT_(<12 x float> %t)389// CHECK-NEXT: entry:390// CHECK-NEXT:   %t.addr = alloca [12 x float], align 4391// CHECK-NEXT:   store <12 x float> %t, ptr %t.addr, align 4392// CHECK-NEXT:   ret void393template <typename T>394void pseudo_destructor(T t) {395  t.~T();396}397 398void test_pseudo_destructor() {399  dx5x5_t a;400  fx3x4_t b;401  pseudo_destructor(a);402  pseudo_destructor(b);403}404