1
1
// RUN: mlir-opt %s -test-affine-reify-value-bounds -cse -verify-diagnostics \
2
2
// RUN: -verify-diagnostics -split-input-file | FileCheck %s
3
3
4
- #fixedDim0Map = affine_map <(d0 )[s0 ] -> (-d0 + 32400 , s0 )>
5
- #fixedDim1Map = affine_map <(d0 )[s0 ] -> (-d0 + 16 , s0 )>
4
+ #map_dim_i = affine_map <(d0 )[s0 ] -> (-d0 + 32400 , s0 )>
5
+ #map_dim_j = affine_map <(d0 )[s0 ] -> (-d0 + 16 , s0 )>
6
6
7
7
// Here the upper bound for min_i is 4 x vscale, as we know 4 x vscale is
8
- // always less than 32400. The bound for min_j is 16 as at vscale > 4,
9
- // 4 x vscale will be > 16, so the value will be clamped at 16 .
8
+ // always less than 32400. The bound for min_j is 16, as 16 is always less
9
+ // 4 x vscale_max (vscale_max is the UB for vscale) .
10
10
11
11
// CHECK: #[[$SCALABLE_BOUND_MAP_0:.*]] = affine_map<()[s0] -> (s0 * 4)>
12
12
13
13
// CHECK-LABEL: @fixed_size_loop_nest
14
14
// CHECK-DAG: %[[VSCALE:.*]] = vector.vscale
15
- // CHECK-DAG: %[[SCALABLE_BOUND :.*]] = affine.apply #[[$SCALABLE_BOUND_MAP_0]]()[%[[VSCALE]]]
16
- // CHECK-DAG: %[[C16 :.*]] = arith.constant 16 : index
17
- // CHECK: "test.some_use"(%[[SCALABLE_BOUND ]], %[[C16 ]]) : (index, index) -> ()
15
+ // CHECK-DAG: %[[UB_i :.*]] = affine.apply #[[$SCALABLE_BOUND_MAP_0]]()[%[[VSCALE]]]
16
+ // CHECK-DAG: %[[UB_j :.*]] = arith.constant 16 : index
17
+ // CHECK: "test.some_use"(%[[UB_i ]], %[[UB_j ]]) : (index, index) -> ()
18
18
func.func @fixed_size_loop_nest () {
19
19
%c16 = arith.constant 16 : index
20
20
%c32400 = arith.constant 32400 : index
@@ -23,9 +23,9 @@ func.func @fixed_size_loop_nest() {
23
23
%vscale = vector.vscale
24
24
%c4_vscale = arith.muli %vscale , %c4 : index
25
25
scf.for %i = %c0 to %c32400 step %c4_vscale {
26
- %min_i = affine.min #fixedDim0Map (%i )[%c4_vscale ]
26
+ %min_i = affine.min #map_dim_i (%i )[%c4_vscale ]
27
27
scf.for %j = %c0 to %c16 step %c4_vscale {
28
- %min_j = affine.min #fixedDim1Map (%j )[%c4_vscale ]
28
+ %min_j = affine.min #map_dim_j (%j )[%c4_vscale ]
29
29
%bound_i = " test.reify_scalable_bound" (%min_i ) {type = " UB" , vscale_min = 1 , vscale_max = 16 } : (index ) -> index
30
30
%bound_j = " test.reify_scalable_bound" (%min_j ) {type = " UB" , vscale_min = 1 , vscale_max = 16 } : (index ) -> index
31
31
" test.some_use" (%bound_i , %bound_j ) : (index , index ) -> ()
@@ -36,28 +36,28 @@ func.func @fixed_size_loop_nest() {
36
36
37
37
// -----
38
38
39
- #dynamicDimMap = affine_map <(d0 )[s0 , s1 ] -> (-d0 + s1 , s0 )>
39
+ #map_dynamic_dim = affine_map <(d0 )[s0 , s1 ] -> (-d0 + s1 , s0 )>
40
40
41
- // Here upper bounds for both min_i and min_j are both 4 x vscale, as we know
42
- // that is always the largest value they could take. As if `dim < 4 x vscale`
43
- // then 4 x vscale is an overestimate, and if `dim > 4 x vscale` then the min
44
- // will be clamped to 4 x vscale.
41
+ // Here upper bounds for both min_i and min_j are both (conservatively)
42
+ // 4 x vscale, as we know that is always the largest value they could take. As
43
+ // if `dim < 4 x vscale` then 4 x vscale is an overestimate, and if
44
+ // `dim > 4 x vscale` then the min will be clamped to 4 x vscale.
45
45
46
46
// CHECK: #[[$SCALABLE_BOUND_MAP_1:.*]] = affine_map<()[s0] -> (s0 * 4)>
47
47
48
48
// CHECK-LABEL: @dynamic_size_loop_nest
49
49
// CHECK: %[[VSCALE:.*]] = vector.vscale
50
- // CHECK: %[[SCALABLE_BOUND :.*]] = affine.apply #[[$SCALABLE_BOUND_MAP_1]]()[%[[VSCALE]]]
51
- // CHECK: "test.some_use"(%[[SCALABLE_BOUND ]], %[[SCALABLE_BOUND ]]) : (index, index) -> ()
50
+ // CHECK: %[[UB_ij :.*]] = affine.apply #[[$SCALABLE_BOUND_MAP_1]]()[%[[VSCALE]]]
51
+ // CHECK: "test.some_use"(%[[UB_ij ]], %[[UB_ij ]]) : (index, index) -> ()
52
52
func.func @dynamic_size_loop_nest (%dim0: index , %dim1: index ) {
53
53
%c4 = arith.constant 4 : index
54
54
%c0 = arith.constant 0 : index
55
55
%vscale = vector.vscale
56
56
%c4_vscale = arith.muli %vscale , %c4 : index
57
57
scf.for %i = %c0 to %dim0 step %c4_vscale {
58
- %min_i = affine.min #dynamicDimMap (%i )[%c4_vscale , %dim0 ]
58
+ %min_i = affine.min #map_dynamic_dim (%i )[%c4_vscale , %dim0 ]
59
59
scf.for %j = %c0 to %dim1 step %c4_vscale {
60
- %min_j = affine.min #dynamicDimMap (%j )[%c4_vscale , %dim1 ]
60
+ %min_j = affine.min #map_dynamic_dim (%j )[%c4_vscale , %dim1 ]
61
61
%bound_i = " test.reify_scalable_bound" (%min_i ) {type = " UB" , vscale_min = 1 , vscale_max = 16 } : (index ) -> index
62
62
%bound_j = " test.reify_scalable_bound" (%min_j ) {type = " UB" , vscale_min = 1 , vscale_max = 16 } : (index ) -> index
63
63
" test.some_use" (%bound_i , %bound_j ) : (index , index ) -> ()
@@ -138,3 +138,24 @@ func.func @duplicate_vscale_values() {
138
138
" test.some_use" (%bound ) : (index ) -> ()
139
139
return
140
140
}
141
+
142
+ // -----
143
+
144
+ // Test some non-scalable code to ensure that works too:
145
+
146
+ #map_dim_i = affine_map <(d0 )[s0 ] -> (-d0 + 1024 , s0 )>
147
+
148
+ // CHECK-LABEL: @non_scalable_code
149
+ // CHECK: %[[C4:.*]] = arith.constant 4 : index
150
+ // CHECK: "test.some_use"(%[[C4]]) : (index) -> ()
151
+ func.func @non_scalable_code () {
152
+ %c1024 = arith.constant 1024 : index
153
+ %c4 = arith.constant 4 : index
154
+ %c0 = arith.constant 0 : index
155
+ scf.for %i = %c0 to %c1024 step %c4 {
156
+ %min_i = affine.min #map_dim_i (%i )[%c4 ]
157
+ %bound_i = " test.reify_scalable_bound" (%min_i ) {type = " UB" , vscale_min = 1 , vscale_max = 16 } : (index ) -> index
158
+ " test.some_use" (%bound_i ) : (index ) -> ()
159
+ }
160
+ return
161
+ }
0 commit comments