brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.1 KiB · 2327f74 Raw
160 lines · plain
1// RUN: mlir-opt %s -test-arm-sme-tile-allocation=preprocess-only -split-input-file | FileCheck %s2 3// This file tests the inserting copies for the SME tile allocation. Copies are4// inserted at `cf.br` ops (the predecessors to block arguments). Conditional5// branches are split to prevent conflicts (see cond_br_with_backedge).6 7// CHECK-LABEL: func.func @simple_branch(8//  CHECK-SAME:   %[[TILE:.*]]: vector<[4]x[4]xf32>)9//   %[[COPY:.*]] = arm_sme.copy_tile %[[TILE]] : vector<[4]x[4]xf32>10//   cf.br ^bb1(%[[COPY]] : vector<[4]x[4]xf32>)11// ^bb1(%[[BLOCK_ARG:.*]]: vector<[4]x[4]xf32>):12 13func.func @simple_branch(%tile : vector<[4]x[4]xf32>) {14  cf.br ^bb1(%tile: vector<[4]x[4]xf32>)15^bb1(%blockArg: vector<[4]x[4]xf32>):16  return17}18 19// -----20 21// Note: The ^POINTLESS_SHIM_FOR_BB2 block is added as the cond_br splitting does22// not check if it needs to insert a copy or not (there is no harm in the empty23// block though -- it will fold away later).24 25// CHECK-LABEL: func.func @cond_branch(26//  CHECK-SAME:   %[[COND:.*]]: i1, %[[TILE:.*]]: vector<[4]x[4]xf32>27//       CHECK:   cf.cond_br %[[COND]], ^[[BB1_COPIES:[[:alnum:]]+]], ^[[POINTLESS_SHIM_FOR_BB2:[[:alnum:]]+]]28//       CHECK: ^[[POINTLESS_SHIM_FOR_BB2]]:29//       CHECK:   cf.br ^[[BB2:.*]]30//       CHECK: ^[[BB1_COPIES]]:31//       CHECK:   arm_sme.copy_tile %[[TILE]] : vector<[4]x[4]xf32>32//       CHECK:   cf.br ^[[BB1:.*]]33func.func @cond_branch(%cond: i1, %tile: vector<[4]x[4]xf32>) {34  cf.cond_br %cond, ^bb1(%tile: vector<[4]x[4]xf32>), ^bb235^bb1(%blockArg: vector<[4]x[4]xf32>):36  return37^bb2:38  return39}40 41// -----42 43// Reduction of a real world example that shows why we must split conditional branches.44 45// CHECK-LABEL: @cond_branch_with_backedge(46//  CHECK-SAME:    %[[TILEA:[[:alnum:]]+]]: vector<[4]x[4]xf32>, %[[TILEB:[[:alnum:]]+]]: vector<[4]x[4]xf32>,47//  CHECK-SAME:    %[[TILEC:[[:alnum:]]+]]: vector<[4]x[4]xf32>, %[[TILED:[[:alnum:]]+]]: vector<[4]x[4]xf32>,48//       CHECK:   %[[BB1_COPY_0:.*]] = arm_sme.copy_tile %[[TILEA]] : vector<[4]x[4]xf32>49//       CHECK:   cf.br ^bb1(%{{[[:alnum:]]+}}, %[[BB1_COPY_0]]50//       CHECK: ^bb1(%[[CURRENT_INDEX:.*]]: index, %[[ITER_TILE:.*]]: vector<[4]x[4]xf32>):51//       CHECK:   %[[CONTINUE_LOOP:.*]] = arith.cmpi52//       CHECK:   cf.cond_br %[[CONTINUE_LOOP]], ^[[BB2_COPIES:[[:alnum:]]+]], ^[[BB3_COPIES:[[:alnum:]]+]]53//       CHECK: ^[[BB3_COPIES]]:54//  CHECK-NEXT:   %[[BB3_COPY_0:.*]] = arm_sme.copy_tile %[[ITER_TILE]] : vector<[4]x[4]xf32>55//  CHECK-NEXT:   %[[BB3_COPY_1:.*]] = arm_sme.copy_tile %[[TILEB]] : vector<[4]x[4]xf32>56//  CHECK-NEXT:   %[[BB3_COPY_2:.*]] = arm_sme.copy_tile %[[TILEC]] : vector<[4]x[4]xf32>57//  CHECK-NEXT:   %[[BB3_COPY_3:.*]] = arm_sme.copy_tile %[[TILED]] : vector<[4]x[4]xf32>58//  CHECK-NEXT:   cf.br ^[[BB3:[[:alnum:]]+]](%[[BB3_COPY_0]], %[[BB3_COPY_1]], %[[BB3_COPY_2]], %[[BB3_COPY_3]]59//       CHECK: ^[[BB2_COPIES]]:60//  CHECK-NEXT:   cf.br ^[[BB2:[[:alnum:]]+]]61//       CHECK: ^[[BB2]]:62//  CHECK-NEXT:   %[[NEXT_TILE:.*]] = arm_sme.insert_tile_slice %{{.*}}, %[[ITER_TILE]]63//       CHECK:   %[[BB1_COPY_1:.*]] = arm_sme.copy_tile %[[NEXT_TILE]] : vector<[4]x[4]xf32>64//       CHECK:   cf.br ^bb1(%{{[[:alnum:]]+}}, %[[BB1_COPY_1]]65//       CHECK: ^[[BB3]](%{{.*}}: vector<[4]x[4]xf32>):66//  CHECK-NEXT:   return67func.func @cond_branch_with_backedge(%tileA: vector<[4]x[4]xf32>, %tileB: vector<[4]x[4]xf32>, %tileC: vector<[4]x[4]xf32>, %tileD: vector<[4]x[4]xf32>, %slice: vector<[4]xf32>) {68  %c0 = arith.constant 0 : index69  %c1 = arith.constant 1 : index70  %c10 = arith.constant 10 : index71  // Live here: %tileA, %tileB, %tileC, %tileD72  cf.br ^bb1(%c0, %tileA : index, vector<[4]x[4]xf32>)73^bb1(%currentIndex: index, %iterTile: vector<[4]x[4]xf32>):74  %continueLoop = arith.cmpi slt, %currentIndex, %c10 : index75  // Live here: %iterTile, %tileB, %tileC, %tileD76  // %iterTile, %tileB, %tileC, %tileD are live out (in the ^bb2 case). If we77  // inserted the (four) `arm_sme.copy_tile` operations here we would run out of tiles.78  // However, note that the copies are only needed if we take the ^bb3 path. So, if we add79  // a new block along that path we can insert the copies without any conflicts.80  cf.cond_br %continueLoop, ^bb2, ^bb3(%iterTile, %tileB, %tileC, %tileD : vector<[4]x[4]xf32>, vector<[4]x[4]xf32>, vector<[4]x[4]xf32>, vector<[4]x[4]xf32>)81^bb2:82  // Live here: %iterTile, %tileB, %tileC, %tileD83  %nextTile = arm_sme.insert_tile_slice %slice, %iterTile[%currentIndex] : vector<[4]xf32> into vector<[4]x[4]xf32>84  %nextIndex = arith.addi %currentIndex, %c1 : index85  cf.br ^bb1(%nextIndex, %nextTile : index, vector<[4]x[4]xf32>)86^bb3(%finalTileA: vector<[4]x[4]xf32>, %finalTileB: vector<[4]x[4]xf32>, %finalTileC: vector<[4]x[4]xf32>, %finalTileD: vector<[4]x[4]xf32>):87  // Live here: %finalTileA, %finalTileB, %finalTileC, %finalTileD88  return89}90 91// -----92 93// CHECK-LABEL: @tile_dominance94// CHECK-NOT: arm_sme.copy_tile95func.func @tile_dominance(%arg0: vector<[4]x[4]xf32>) {96  cf.br ^bb197^bb1:  // 2 preds: ^bb0, ^bb498  "test.some_use"(%arg0) : (vector<[4]x[4]xf32>) -> ()99  return100^bb2:  // no predecessors101  %0 = arm_sme.get_tile : vector<[4]x[4]xf32>102  cf.br ^bb3103^bb3:  // pred: ^bb2104  "test.some_use"(%0) : (vector<[4]x[4]xf32>) -> ()105  return106^bb4:  // no predecessors107  cf.br ^bb1108^bb5:  // no predecessors109  return110}111 112// -----113 114// CHECK-LABEL: func.func @cond_branch_true_and_false_tile_args(115//  CHECK-SAME:   %[[COND:.*]]: i1, %[[TILE:.*]]: vector<[4]x[4]xf32>116//  CHECK-NEXT:   cf.cond_br %[[COND]], ^[[BB1_COPIES:[[:alnum:]]+]], ^[[BB2_COPIES:[[:alnum:]]+]]117//       CHECK: ^[[BB2_COPIES]]:118//  CHECK-NEXT:   %[[COPY_0:.*]] = arm_sme.copy_tile %[[TILE]] :  vector<[4]x[4]xf32>119//  CHECK-NEXT:   cf.br ^[[BB2:[[:alnum:]]+]](%[[COPY_0]]120//       CHECK: ^[[BB1_COPIES]]:121//  CHECK-NEXT:   %[[COPY_1:.*]] = arm_sme.copy_tile %[[TILE]] :  vector<[4]x[4]xf32>122//  CHECK-NEXT:   cf.br ^[[BB1:[[:alnum:]]+]](%[[COPY_1]]123//       CHECK: ^[[BB1]]{{.*}}:124//  CHECK-NEXT:   return125//       CHECK: ^[[BB2]]{{.*}}:126//  CHECK-NEXT:   return127func.func @cond_branch_true_and_false_tile_args(%cond: i1, %tile: vector<[4]x[4]xf32>) {128  cf.cond_br %cond, ^bb1(%tile: vector<[4]x[4]xf32>), ^bb2(%tile: vector<[4]x[4]xf32>)129^bb1(%blockArg0: vector<[4]x[4]xf32>):130  return131^bb2(%blockArg1: vector<[4]x[4]xf32>):132  return133}134 135// -----136 137// CHECK-LABEL: @multiple_predecessors138//      CHECK: ^bb1:139// CHECK-NEXT:   %[[TILE:.*]] = arm_sme.get_tile : vector<[4]x[4]xf32>140// CHECK-NEXT:   %[[COPY_0:.*]] = arm_sme.copy_tile %[[TILE]] : vector<[4]x[4]xf32>141// CHECK-NEXT:    cf.br ^bb3(%[[COPY_0]] : vector<[4]x[4]xf32>)142//      CHECK: ^bb2:143// CHECK-NEXT:   %[[ZERO:.*]] = arm_sme.zero : vector<[4]x[4]xf32>144// CHECK-NEXT:   %[[COPY_1:.*]] = arm_sme.copy_tile %[[ZERO]] : vector<[4]x[4]xf32>145// CHECK-NEXT:    cf.br ^bb3(%[[COPY_1]] : vector<[4]x[4]xf32>)146//      CHECK: ^bb3({{.*}}):147// CHECK-NEXT:  return148func.func @multiple_predecessors(%cond: i1)149{150  cf.cond_br %cond, ^bb1, ^bb2151^bb1:152  %tile = arm_sme.get_tile : vector<[4]x[4]xf32>153  cf.br ^bb3(%tile : vector<[4]x[4]xf32>)154^bb2:155  %zero = arm_sme.zero : vector<[4]x[4]xf32>156  cf.br ^bb3(%zero : vector<[4]x[4]xf32>)157^bb3(%blockArg: vector<[4]x[4]xf32>): // pred: ^bb1, ^bb2158  return159}160