Skip to content

Commit fde6523

Browse files
committed
Add CHECK-BAD tests for the current tile allocator
1 parent 3298946 commit fde6523

File tree

1 file changed

+64
-8
lines changed

1 file changed

+64
-8
lines changed

mlir/test/Dialect/ArmSME/tile-allocation-liveness.mlir

Lines changed: 64 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
1-
// RUN: mlir-opt %s -allocate-arm-sme-tiles -split-input-file -verify-diagnostics | FileCheck %s
1+
// RUN: mlir-opt %s -allocate-arm-sme-tiles -split-input-file -verify-diagnostics | FileCheck %s --check-prefix=CHECK-BAD
22

3-
// This file tests some simple aspects of using liveness in the SME tile allocator.
4-
5-
// Note: This is an XFAIL the new allocator is not yet upstream, and the current
6-
// allocator gives incorrect results for these tests.
7-
// XFAIL: *
3+
// This file tests some aspects of liveness issues in the SME tile allocator.
4+
// These tests were designed with a new liveness-based tile allocator in mind,
5+
// with the current tile allocator these tests all give incorrect results (which
6+
// is documented by `CHECK-BAD`).
7+
//
8+
// Currently only the `CHECK-BAD` tests are run (as the new liveness based
9+
// allocator is not yet available -- so all other tests fail).
810

911
// CHECK-LIVE-RANGE: ========== Coalesced Live Ranges:
1012
// CHECK-LIVE-RANGE-NEXT: @constant_with_multiple_users
@@ -15,6 +17,14 @@
1517
// CHECK-LIVE-RANGE-NEXT: |E test.some_use
1618
// CHECK-LIVE-RANGE-NEXT: E test.some_use
1719

20+
// Incorrect result! The second `move_vector_to_tile_slice` overwrites the first (which is still live).
21+
//
22+
// CHECK-BAD-LABEL: @constant_with_multiple_users(
23+
// CHECK-BAD-SAME: %[[VECTOR_A:.*]]: vector<[4]xf32>, %[[VECTOR_B:.*]]: vector<[4]xf32>
24+
// CHECK-BAD: %[[ZERO_TILE:.*]] = arm_sme.zero {tile_id = 0 : i32} : vector<[4]x[4]xf32>
25+
// CHECK-BAD: %[[INSERT_TILE_1:.*]] = arm_sme.move_vector_to_tile_slice %[[VECTOR_A]], %[[ZERO_TILE]], %{{.*}} {tile_id = 0 : i32} : vector<[4]xf32> into vector<[4]x[4]xf32>
26+
// CHECK-BAD: %[[INSERT_TILE_0:.*]] = arm_sme.move_vector_to_tile_slice %[[VECTOR_B]], %[[ZERO_TILE]], %{{.*}} {tile_id = 0 : i32} : vector<[4]xf32> into vector<[4]x[4]xf32>
27+
1828
// CHECK-LABEL: @constant_with_multiple_users(
1929
// CHECK-SAME: %[[VECTOR_A:.*]]: vector<[4]xf32>, %[[VECTOR_B:.*]]: vector<[4]xf32>
2030
func.func @constant_with_multiple_users(%a: vector<[4]xf32>, %b: vector<[4]xf32>, %index: index) {
@@ -40,8 +50,10 @@ func.func @constant_with_multiple_users(%a: vector<[4]xf32>, %b: vector<[4]xf32>
4050
// CHECK-LIVE-RANGE-NEXT: |E test.some_use
4151
// CHECK-LIVE-RANGE-NEXT: E test.some_use
4252

53+
// (No CHECK-BAD -- the current tile allocator ignores this case)
54+
4355
func.func @value_with_multiple_users(%tile: vector<[4]x[4]xf32>, %a: vector<[4]xf32>, %b: vector<[4]xf32>, %index: index) {
44-
// expected-error@below {{op failed to rectify tile operand with tile result (move required)}}
56+
// A future allocator should error here (as `%`tile would need to be copied).
4557
%tile_a = arm_sme.move_vector_to_tile_slice %a, %tile, %index : vector<[4]xf32> into vector<[4]x[4]xf32>
4658
%tile_b = arm_sme.move_vector_to_tile_slice %b, %tile, %index : vector<[4]xf32> into vector<[4]x[4]xf32>
4759
"test.some_use"(%tile_a) : (vector<[4]x[4]xf32>) -> ()
@@ -77,6 +89,19 @@ func.func @value_with_multiple_users(%tile: vector<[4]x[4]xf32>, %a: vector<[4]x
7789
// CHECK-LIVE-RANGE-NEXT: E| test.some_use
7890
// CHECK-LIVE-RANGE-NEXT: E test.some_use
7991

92+
// CHECK-BAD-LABEL: @reuse_tiles_after_initial_use
93+
// CHECK-BAD: arm_sme.get_tile {tile_id = 0 : i32}
94+
// CHECK-BAD: arm_sme.get_tile {tile_id = 1 : i32}
95+
// CHECK-BAD: arm_sme.get_tile {tile_id = 2 : i32}
96+
// CHECK-BAD: arm_sme.get_tile {tile_id = 3 : i32}
97+
//
98+
// -> Spills after the fourth tile (unnecessary):
99+
//
100+
// CHECK-BAD: arm_sme.zero {tile_id = 16 : i32}
101+
// CHECK-BAD: arm_sme.zero {tile_id = 17 : i32}
102+
// CHECK-BAD: arm_sme.zero {tile_id = 18 : i32}
103+
// CHECK-BAD: arm_sme.zero {tile_id = 19 : i32}
104+
80105
// CHECK-LABEL: @reuse_tiles_after_initial_use
81106
func.func @reuse_tiles_after_initial_use() {
82107
// CHECK: arm_sme.get_tile {tile_id = 0 : i32}
@@ -98,9 +123,14 @@ func.func @reuse_tiles_after_initial_use() {
98123
// CHECK: arm_sme.zero {tile_id = 1 : i32}
99124
// CHECK: arm_sme.zero {tile_id = 2 : i32}
100125
// CHECK: arm_sme.zero {tile_id = 3 : i32}
126+
// Unnecessary spills:
127+
// expected-warning @below {{failed to allocate SME virtual tile to operation, all tile operations will go through memory, expect degraded performance}}
101128
%tile_1 = arm_sme.zero : vector<[4]x[4]xf32>
129+
// expected-warning @below {{failed to allocate SME virtual tile to operation, all tile operations will go through memory, expect degraded performance}}
102130
%tile_2 = arm_sme.zero : vector<[4]x[4]xf32>
131+
// expected-warning @below {{failed to allocate SME virtual tile to operation, all tile operations will go through memory, expect degraded performance}}
103132
%tile_3 = arm_sme.zero : vector<[4]x[4]xf32>
133+
// expected-warning @below {{failed to allocate SME virtual tile to operation, all tile operations will go through memory, expect degraded performance}}
104134
%tile_4 = arm_sme.zero : vector<[4]x[4]xf32>
105135
"test.dummy"(): () -> ()
106136
"test.dummy"(): () -> ()
@@ -125,6 +155,12 @@ func.func @reuse_tiles_after_initial_use() {
125155
// CHECK-LIVE-RANGE-NEXT: | arm_sme.copy_tile
126156
// CHECK-LIVE-RANGE-NEXT: E cf.br
127157

158+
// Incorrect result! Both branches should yield the result via the same tile.
159+
//
160+
// CHECK-BAD-LABEL: @non_overlapping_branches
161+
// CHECK-BAD: arm_sme.zero {tile_id = 0 : i32} : vector<[4]x[4]xf32>
162+
// CHECK-BAD: arm_sme.get_tile {tile_id = 1 : i32} : vector<[4]x[4]xf32>
163+
128164
// CHECK-LABEL: @non_overlapping_branches
129165
func.func @non_overlapping_branches(%cond: i1) {
130166
// CHECK: arm_sme.zero {tile_id = 0 : i32} : vector<[4]x[4]xf32>
@@ -147,6 +183,13 @@ func.func @non_overlapping_branches(%cond: i1) {
147183
// CHECK-LIVE-RANGE: ========== Coalesced Live Ranges:
148184
// <deliberately omitted>
149185

186+
// Incorrect result! Everything assigned to tile 0 (which means values that are still live are overwritten).
187+
//
188+
// CHECK-BAD-LABEL: @constant_loop_init_with_multiple_users
189+
// CHECK-BAD: arm_sme.zero {tile_id = 0 : i32} : vector<[4]x[4]xf32>
190+
// CHECK-BAD: arm_sme.move_vector_to_tile_slice {{.*}} {tile_id = 0 : i32} : vector<[4]xf32> into vector<[4]x[4]xf32>
191+
// CHECK-BAD: arm_sme.move_vector_to_tile_slice {{.*}} {tile_id = 0 : i32} : vector<[4]xf32> into vector<[4]x[4]xf32>
192+
150193
// CHECK-LABEL: @constant_loop_init_with_multiple_users
151194
func.func @constant_loop_init_with_multiple_users(%a: vector<[4]xf32>, %b: vector<[4]xf32>) {
152195
// CHECK: arm_sme.zero {tile_id = 0 : i32} : vector<[4]x[4]xf32>
@@ -183,6 +226,12 @@ func.func @constant_loop_init_with_multiple_users(%a: vector<[4]xf32>, %b: vecto
183226

184227
// Note in the live ranges (above) there is five tile values, but we only have four tiles.
185228

229+
// Incorrect result! Everything assigned to tile 0 (which means values that are still live are overwritten).
230+
//
231+
// CHECK-BAD-LABEL: @run_out_of_tiles_but_avoid_spill
232+
// CHECK-BAD: arm_sme.zero {tile_id = 0 : i32}
233+
// CHECK-BAD-COUNT-4: arm_sme.move_vector_to_tile_slice {{.*}} {tile_id = 0 : i32} : vector<[4]xf32> into vector<[4]x[4]xf32>
234+
186235
// CHECK-LABEL: @run_out_of_tiles_but_avoid_spill
187236
func.func @run_out_of_tiles_but_avoid_spill(%a: vector<[4]xf32>, %b: vector<[4]xf32>, %c: vector<[4]xf32>, %d: vector<[4]xf32>) {
188237
%init = arm_sme.zero : vector<[4]x[4]xf32>
@@ -239,13 +288,20 @@ func.func @run_out_of_tiles_but_avoid_spill(%a: vector<[4]xf32>, %b: vector<[4]x
239288
// CHECK-LIVE-RANGE-NEXT: || E test.some_use
240289
// CHECK-LIVE-RANGE-NEXT: || arith.addi
241290
// CHECK-LIVE-RANGE-NEXT: EE cf.br
242-
291+
//
243292
// Note in the live ranges (above) there is two constant live-ins (first two ranges),
244293
// which gives six overlapping live ranges. The allocator currently will spill the
245294
// first constant (which results in a real spill at it's use), however, this could
246295
// be avoided by using the knowledge that at the first "test.some_use" there's
247296
// actually only two live ranges (so we can fix this be duplicating the constant).
248297

298+
// Incorrect result! Everything other than zero assigned to tile 1 (which means values that are still live are overwritten).
299+
//
300+
// CHECK-BAD-LABEL: @avoidable_spill
301+
// CHECK-BAD: arm_sme.zero {tile_id = 0 : i32}
302+
// CHECK-BAD: arm_sme.get_tile {tile_id = 1 : i32}
303+
// CHECK-BAD-COUNT-4: arm_sme.move_vector_to_tile_slice {{.*}} {tile_id = 1 : i32}
304+
249305
// CHECK-LABEL: @avoidable_spill
250306
func.func @avoidable_spill(%a: vector<[4]xf32>, %b: vector<[4]xf32>, %c: vector<[4]xf32>, %d: vector<[4]xf32>) {
251307
// CHECK: arm_sme.zero {tile_id = 16 : i32} : vector<[4]x[4]xf32>

0 commit comments

Comments
 (0)