xref: /llvm-project/mlir/test/Dialect/Affine/value-bounds-op-interface-impl.mlir (revision 0aa831e0edb1c1deabb96ce2435667cc82bac79b)
1*0aa831e0SKrzysztof Drewniak// RUN: mlir-opt %s -pass-pipeline='builtin.module(func.func(test-affine-reify-value-bounds))' -verify-diagnostics \
24f8f01b7SMatthias Springer// RUN:     -split-input-file | FileCheck %s
34f8f01b7SMatthias Springer
44f8f01b7SMatthias Springer// CHECK: #[[$map:.*]] = affine_map<()[s0, s1] -> (s0 + s1)>
54f8f01b7SMatthias Springer// CHECK-LABEL: func @affine_apply(
64f8f01b7SMatthias Springer//  CHECK-SAME:     %[[a:.*]]: index, %[[b:.*]]: index
74f8f01b7SMatthias Springer//       CHECK:   %[[apply:.*]] = affine.apply #[[$map]]()[%[[a]], %[[b]]]
84f8f01b7SMatthias Springer//       CHECK:   %[[apply:.*]] = affine.apply #[[$map]]()[%[[a]], %[[b]]]
9ae6eedd2SRik Huijzer//       CHECK:   return %[[apply]]
104f8f01b7SMatthias Springerfunc.func @affine_apply(%a: index, %b: index) -> index {
114f8f01b7SMatthias Springer  %0 = affine.apply affine_map<()[s0, s1] -> (s0 + s1)>()[%a, %b]
124f8f01b7SMatthias Springer  %1 = "test.reify_bound"(%0) : (index) -> (index)
134f8f01b7SMatthias Springer  return %1 : index
144f8f01b7SMatthias Springer}
15041bc485SMatthias Springer
16041bc485SMatthias Springer// -----
17041bc485SMatthias Springer
18041bc485SMatthias Springer// CHECK-LABEL: func @affine_max_lb(
19041bc485SMatthias Springer//  CHECK-SAME:     %[[a:.*]]: index
20041bc485SMatthias Springer//       CHECK:   %[[c2:.*]] = arith.constant 2 : index
21041bc485SMatthias Springer//       CHECK:   return %[[c2]]
22041bc485SMatthias Springerfunc.func @affine_max_lb(%a: index) -> (index) {
23041bc485SMatthias Springer  // Note: There are two LBs: s0 and 2. FlatAffineValueConstraints always
24041bc485SMatthias Springer  // returns the constant one at the moment.
25041bc485SMatthias Springer  %1 = affine.max affine_map<()[s0] -> (s0, 2)>()[%a]
26041bc485SMatthias Springer  %2 = "test.reify_bound"(%1) {type = "LB"}: (index) -> (index)
27041bc485SMatthias Springer  return %2 : index
28041bc485SMatthias Springer}
29041bc485SMatthias Springer
30041bc485SMatthias Springer// -----
31041bc485SMatthias Springer
32041bc485SMatthias Springerfunc.func @affine_max_ub(%a: index) -> (index) {
33041bc485SMatthias Springer  %1 = affine.max affine_map<()[s0] -> (s0, 2)>()[%a]
34041bc485SMatthias Springer  // expected-error @below{{could not reify bound}}
35041bc485SMatthias Springer  %2 = "test.reify_bound"(%1) {type = "UB"}: (index) -> (index)
36041bc485SMatthias Springer  return %2 : index
37041bc485SMatthias Springer}
38041bc485SMatthias Springer
39041bc485SMatthias Springer// -----
40041bc485SMatthias Springer
41041bc485SMatthias Springer// CHECK-LABEL: func @affine_min_ub(
42041bc485SMatthias Springer//  CHECK-SAME:     %[[a:.*]]: index
43041bc485SMatthias Springer//       CHECK:   %[[c3:.*]] = arith.constant 3 : index
44041bc485SMatthias Springer//       CHECK:   return %[[c3]]
45041bc485SMatthias Springerfunc.func @affine_min_ub(%a: index) -> (index) {
46041bc485SMatthias Springer  // Note: There are two UBs: s0 + 1 and 3. FlatAffineValueConstraints always
47041bc485SMatthias Springer  // returns the constant one at the moment.
48041bc485SMatthias Springer  %1 = affine.min affine_map<()[s0] -> (s0, 2)>()[%a]
49041bc485SMatthias Springer  %2 = "test.reify_bound"(%1) {type = "UB"}: (index) -> (index)
50041bc485SMatthias Springer  return %2 : index
51041bc485SMatthias Springer}
52041bc485SMatthias Springer
53041bc485SMatthias Springer// -----
54041bc485SMatthias Springer
55041bc485SMatthias Springerfunc.func @affine_min_lb(%a: index) -> (index) {
56041bc485SMatthias Springer  %1 = affine.min affine_map<()[s0] -> (s0, 2)>()[%a]
57041bc485SMatthias Springer  // expected-error @below{{could not reify bound}}
58041bc485SMatthias Springer  %2 = "test.reify_bound"(%1) {type = "LB"}: (index) -> (index)
59041bc485SMatthias Springer  return %2 : index
60041bc485SMatthias Springer}
61ebaf8d49SMatthias Springer
62ebaf8d49SMatthias Springer// -----
63ebaf8d49SMatthias Springer
64ebaf8d49SMatthias Springer// CHECK-LABEL: func @composed_affine_apply(
65ebaf8d49SMatthias Springer//       CHECK:   %[[cst:.*]] = arith.constant -8 : index
66ebaf8d49SMatthias Springer//       CHECK:   return %[[cst]]
67ebaf8d49SMatthias Springerfunc.func @composed_affine_apply(%i1 : index) -> (index) {
68ebaf8d49SMatthias Springer  // The ValueBoundsOpInterface implementation of affine.apply fully composes
69ebaf8d49SMatthias Springer  // the affine map (and its operands) with other affine.apply ops drawn from
70ebaf8d49SMatthias Springer  // its operands before adding it to the constraint set. This is to work
71ebaf8d49SMatthias Springer  // around a limitation in `FlatLinearConstraints`, which can currently not
72ebaf8d49SMatthias Springer  // compute a constant bound for %s. (The affine map simplification logic can
73ebaf8d49SMatthias Springer  // simplify %s to -8.)
74ebaf8d49SMatthias Springer  %i2 = affine.apply affine_map<(d0) -> ((d0 floordiv 32) * 16)>(%i1)
75ebaf8d49SMatthias Springer  %i3 = affine.apply affine_map<(d0) -> ((d0 floordiv 32) * 16 + 8)>(%i1)
76ebaf8d49SMatthias Springer  %s = affine.apply affine_map<()[s0, s1] -> (s0 - s1)>()[%i2, %i3]
77f8d314f0SMatthias Springer  %reified = "test.reify_bound"(%s) {type = "EQ", constant} : (index) -> (index)
78ebaf8d49SMatthias Springer  return %reified : index
79ebaf8d49SMatthias Springer}
80ebaf8d49SMatthias Springer
81ebaf8d49SMatthias Springer
82ebaf8d49SMatthias Springer// -----
83ebaf8d49SMatthias Springer
84297eca98SMatthias Springerfunc.func @are_equal(%i1 : index) {
85297eca98SMatthias Springer  %i2 = affine.apply affine_map<(d0) -> ((d0 floordiv 32) * 16)>(%i1)
86297eca98SMatthias Springer  %i3 = affine.apply affine_map<(d0) -> ((d0 floordiv 32) * 16 + 8)>(%i1)
87297eca98SMatthias Springer  %s = affine.apply affine_map<()[s0, s1] -> (s0 - s1)>()[%i2, %i3]
88297eca98SMatthias Springer  // expected-remark @below{{false}}
89297eca98SMatthias Springer   "test.compare"(%i2, %i3) : (index, index) -> ()
90297eca98SMatthias Springer  return
91297eca98SMatthias Springer}
92297eca98SMatthias Springer
93297eca98SMatthias Springer// -----
94297eca98SMatthias Springer
95ebaf8d49SMatthias Springer// Test for affine::fullyComposeAndCheckIfEqual
96ebaf8d49SMatthias Springerfunc.func @composed_are_equal(%i1 : index) {
97ebaf8d49SMatthias Springer  %i2 = affine.apply affine_map<(d0) -> ((d0 floordiv 32) * 16)>(%i1)
98ebaf8d49SMatthias Springer  %i3 = affine.apply affine_map<(d0) -> ((d0 floordiv 32) * 16 + 8)>(%i1)
99ebaf8d49SMatthias Springer  %s = affine.apply affine_map<()[s0, s1] -> (s0 - s1)>()[%i2, %i3]
100ebaf8d49SMatthias Springer  // expected-remark @below{{different}}
101297eca98SMatthias Springer   "test.compare"(%i2, %i3) {compose} : (index, index) -> ()
102297eca98SMatthias Springer  return
103297eca98SMatthias Springer}
104297eca98SMatthias Springer
105297eca98SMatthias Springer// -----
106297eca98SMatthias Springer
107297eca98SMatthias Springerfunc.func @compare_affine_max(%a: index, %b: index) {
108297eca98SMatthias Springer  %0 = affine.max affine_map<()[s0, s1] -> (s0, s1)>()[%a, %b]
109297eca98SMatthias Springer  // expected-remark @below{{true}}
110297eca98SMatthias Springer  "test.compare"(%0, %a) {cmp = "GE"} : (index, index) -> ()
111297eca98SMatthias Springer  // expected-error @below{{unknown}}
112297eca98SMatthias Springer  "test.compare"(%0, %a) {cmp = "GT"} : (index, index) -> ()
113297eca98SMatthias Springer  // expected-remark @below{{false}}
114297eca98SMatthias Springer  "test.compare"(%0, %a) {cmp = "LT"} : (index, index) -> ()
115297eca98SMatthias Springer  // expected-error @below{{unknown}}
116297eca98SMatthias Springer  "test.compare"(%0, %a) {cmp = "LE"} : (index, index) -> ()
117297eca98SMatthias Springer  return
118297eca98SMatthias Springer}
119297eca98SMatthias Springer
120297eca98SMatthias Springer// -----
121297eca98SMatthias Springer
122297eca98SMatthias Springerfunc.func @compare_affine_min(%a: index, %b: index) {
123297eca98SMatthias Springer  %0 = affine.min affine_map<()[s0, s1] -> (s0, s1)>()[%a, %b]
124297eca98SMatthias Springer  // expected-error @below{{unknown}}
125297eca98SMatthias Springer  "test.compare"(%0, %a) {cmp = "GE"} : (index, index) -> ()
126297eca98SMatthias Springer  // expected-remark @below{{false}}
127297eca98SMatthias Springer  "test.compare"(%0, %a) {cmp = "GT"} : (index, index) -> ()
128297eca98SMatthias Springer  // expected-error @below{{unknown}}
129297eca98SMatthias Springer  "test.compare"(%0, %a) {cmp = "LT"} : (index, index) -> ()
130297eca98SMatthias Springer  // expected-remark @below{{true}}
131297eca98SMatthias Springer  "test.compare"(%0, %a) {cmp = "LE"} : (index, index) -> ()
132ebaf8d49SMatthias Springer  return
133ebaf8d49SMatthias Springer}
13440dd3aa9SMatthias Springer
13540dd3aa9SMatthias Springer// -----
13640dd3aa9SMatthias Springer
13740dd3aa9SMatthias Springerfunc.func @compare_const_map() {
13840dd3aa9SMatthias Springer  %c5 = arith.constant 5 : index
13940dd3aa9SMatthias Springer  // expected-remark @below{{true}}
14040dd3aa9SMatthias Springer  "test.compare"(%c5) {cmp = "GT", rhs_map = affine_map<() -> (4)>}
14140dd3aa9SMatthias Springer      : (index) -> ()
14240dd3aa9SMatthias Springer  // expected-remark @below{{true}}
14340dd3aa9SMatthias Springer  "test.compare"(%c5) {cmp = "LT", lhs_map = affine_map<() -> (4)>}
14440dd3aa9SMatthias Springer      : (index) -> ()
14540dd3aa9SMatthias Springer  return
14640dd3aa9SMatthias Springer}
14740dd3aa9SMatthias Springer
14840dd3aa9SMatthias Springer// -----
14940dd3aa9SMatthias Springer
15040dd3aa9SMatthias Springerfunc.func @compare_maps(%a: index, %b: index) {
15140dd3aa9SMatthias Springer  // expected-remark @below{{true}}
15240dd3aa9SMatthias Springer  "test.compare"(%a, %b, %b, %a)
15340dd3aa9SMatthias Springer      {cmp = "GT", lhs_map = affine_map<(d0, d1) -> (1 + d0 + d1)>,
15440dd3aa9SMatthias Springer       rhs_map = affine_map<(d0, d1) -> (d0 + d1)>}
15540dd3aa9SMatthias Springer      : (index, index, index, index) -> ()
15640dd3aa9SMatthias Springer  return
15740dd3aa9SMatthias Springer}
158c6f67b8eSKrzysztof Drewniak
159c6f67b8eSKrzysztof Drewniak// -----
160c6f67b8eSKrzysztof Drewniak
161c6f67b8eSKrzysztof Drewniak// CHECK-DAG: #[[$map1:.+]] = affine_map<()[s0] -> (s0 floordiv 15)>
162c6f67b8eSKrzysztof Drewniak// CHECK-DAG: #[[$map2:.+]] = affine_map<()[s0] -> ((s0 mod 15) floordiv 5)>
163c6f67b8eSKrzysztof Drewniak// CHECK-DAG: #[[$map3:.+]] = affine_map<()[s0] -> (s0 mod 5)>
164c6f67b8eSKrzysztof Drewniak// CHECK-LABEL: func.func @delinearize_static
165c6f67b8eSKrzysztof Drewniak// CHECK-SAME: (%[[arg0:.+]]: index)
166c6f67b8eSKrzysztof Drewniak// CHECK-DAG: %[[v1:.+]] = affine.apply #[[$map1]]()[%[[arg0]]]
167c6f67b8eSKrzysztof Drewniak// CHECK-DAG: %[[v2:.+]] = affine.apply #[[$map2]]()[%[[arg0]]]
168c6f67b8eSKrzysztof Drewniak// CHECK-DAG: %[[v3:.+]] = affine.apply #[[$map3]]()[%[[arg0]]]
169c6f67b8eSKrzysztof Drewniak// CHECK: return %[[v1]], %[[v2]], %[[v3]]
170c6f67b8eSKrzysztof Drewniakfunc.func @delinearize_static(%arg0: index) -> (index, index, index) {
171c6f67b8eSKrzysztof Drewniak  %c2 = arith.constant 2 : index
172c6f67b8eSKrzysztof Drewniak  %c3 = arith.constant 3 : index
173c6f67b8eSKrzysztof Drewniak  %0:3 = affine.delinearize_index %arg0 into (2, 3, 5) : index, index, index
174c6f67b8eSKrzysztof Drewniak  %1 = "test.reify_bound"(%0#0) {type = "EQ"} : (index) -> (index)
175c6f67b8eSKrzysztof Drewniak  %2 = "test.reify_bound"(%0#1) {type = "EQ"} : (index) -> (index)
176c6f67b8eSKrzysztof Drewniak  %3 = "test.reify_bound"(%0#2) {type = "EQ"} : (index) -> (index)
177c6f67b8eSKrzysztof Drewniak  // expected-remark @below{{true}}
178c6f67b8eSKrzysztof Drewniak  "test.compare"(%0#0, %c2) {cmp = "LT"} : (index, index) -> ()
179c6f67b8eSKrzysztof Drewniak  // expected-remark @below{{true}}
180c6f67b8eSKrzysztof Drewniak  "test.compare"(%0#1, %c3) {cmp = "LT"} : (index, index) -> ()
181c6f67b8eSKrzysztof Drewniak  return %1, %2, %3 : index, index, index
182c6f67b8eSKrzysztof Drewniak}
183c6f67b8eSKrzysztof Drewniak
184c6f67b8eSKrzysztof Drewniak// -----
185c6f67b8eSKrzysztof Drewniak
186c6f67b8eSKrzysztof Drewniak// CHECK-DAG: #[[$map1:.+]] = affine_map<()[s0] -> (s0 floordiv 15)>
187c6f67b8eSKrzysztof Drewniak// CHECK-DAG: #[[$map2:.+]] = affine_map<()[s0] -> ((s0 mod 15) floordiv 5)>
188c6f67b8eSKrzysztof Drewniak// CHECK-DAG: #[[$map3:.+]] = affine_map<()[s0] -> (s0 mod 5)>
189c6f67b8eSKrzysztof Drewniak// CHECK-LABEL: func.func @delinearize_static_no_outer_bound
190c6f67b8eSKrzysztof Drewniak// CHECK-SAME: (%[[arg0:.+]]: index)
191c6f67b8eSKrzysztof Drewniak// CHECK-DAG: %[[v1:.+]] = affine.apply #[[$map1]]()[%[[arg0]]]
192c6f67b8eSKrzysztof Drewniak// CHECK-DAG: %[[v2:.+]] = affine.apply #[[$map2]]()[%[[arg0]]]
193c6f67b8eSKrzysztof Drewniak// CHECK-DAG: %[[v3:.+]] = affine.apply #[[$map3]]()[%[[arg0]]]
194c6f67b8eSKrzysztof Drewniak// CHECK: return %[[v1]], %[[v2]], %[[v3]]
195c6f67b8eSKrzysztof Drewniakfunc.func @delinearize_static_no_outer_bound(%arg0: index) -> (index, index, index) {
196c6f67b8eSKrzysztof Drewniak  %c2 = arith.constant 2 : index
197c6f67b8eSKrzysztof Drewniak  %c3 = arith.constant 3 : index
198c6f67b8eSKrzysztof Drewniak  %0:3 = affine.delinearize_index %arg0 into (3, 5) : index, index, index
199c6f67b8eSKrzysztof Drewniak  %1 = "test.reify_bound"(%0#0) {type = "EQ"} : (index) -> (index)
200c6f67b8eSKrzysztof Drewniak  %2 = "test.reify_bound"(%0#1) {type = "EQ"} : (index) -> (index)
201c6f67b8eSKrzysztof Drewniak  %3 = "test.reify_bound"(%0#2) {type = "EQ"} : (index) -> (index)
202c6f67b8eSKrzysztof Drewniak  "test.compaare"(%0#0, %c2) {cmp = "LT"} : (index, index) -> ()
203c6f67b8eSKrzysztof Drewniak  // expected-remark @below{{true}}
204c6f67b8eSKrzysztof Drewniak  "test.compare"(%0#1, %c3) {cmp = "LT"} : (index, index) -> ()
205c6f67b8eSKrzysztof Drewniak  return %1, %2, %3 : index, index, index
206c6f67b8eSKrzysztof Drewniak}
207c6f67b8eSKrzysztof Drewniak
208c6f67b8eSKrzysztof Drewniak// -----
209c6f67b8eSKrzysztof Drewniak
210c6f67b8eSKrzysztof Drewniak// CHECK: #[[$map:.+]] = affine_map<()[s0, s1] -> (s0 + s1 * 3)>
211c6f67b8eSKrzysztof Drewniak// CHECK-LABEL: func.func @linearize_static
212c6f67b8eSKrzysztof Drewniak// CHECK-SAME: (%[[arg0:.+]]: index, %[[arg1:.+]]: index)
213c6f67b8eSKrzysztof Drewniak// CHECK: %[[v1:.+]] = affine.apply #[[$map]]()[%[[arg1]], %[[arg0]]]
214c6f67b8eSKrzysztof Drewniak// CHECK: return %[[v1]]
215c6f67b8eSKrzysztof Drewniakfunc.func @linearize_static(%arg0: index, %arg1: index)  -> index {
216c6f67b8eSKrzysztof Drewniak  %c6 = arith.constant 6 : index
217c6f67b8eSKrzysztof Drewniak  %0 = affine.linearize_index disjoint [%arg0, %arg1] by (2, 3) : index
218c6f67b8eSKrzysztof Drewniak  %1 = "test.reify_bound"(%0) {type = "EQ"} : (index) -> (index)
219c6f67b8eSKrzysztof Drewniak  // expected-remark @below{{true}}
220c6f67b8eSKrzysztof Drewniak  "test.compare"(%0, %c6) {cmp = "LT"} : (index, index) -> ()
221c6f67b8eSKrzysztof Drewniak  return %1 : index
222c6f67b8eSKrzysztof Drewniak}
223c6f67b8eSKrzysztof Drewniak
224c6f67b8eSKrzysztof Drewniak// -----
225c6f67b8eSKrzysztof Drewniak
226c6f67b8eSKrzysztof Drewniak// CHECK: #[[$map:.+]] = affine_map<()[s0, s1] -> (s0 + s1 * 3)>
227c6f67b8eSKrzysztof Drewniak// CHECK-LABEL: func.func @linearize_static_no_outer_bound
228c6f67b8eSKrzysztof Drewniak// CHECK-SAME: (%[[arg0:.+]]: index, %[[arg1:.+]]: index)
229c6f67b8eSKrzysztof Drewniak// CHECK: %[[v1:.+]] = affine.apply #[[$map]]()[%[[arg1]], %[[arg0]]]
230c6f67b8eSKrzysztof Drewniak// CHECK: return %[[v1]]
231c6f67b8eSKrzysztof Drewniakfunc.func @linearize_static_no_outer_bound(%arg0: index, %arg1: index)  -> index {
232c6f67b8eSKrzysztof Drewniak  %c6 = arith.constant 6 : index
233c6f67b8eSKrzysztof Drewniak  %0 = affine.linearize_index disjoint [%arg0, %arg1] by (3) : index
234c6f67b8eSKrzysztof Drewniak  %1 = "test.reify_bound"(%0) {type = "EQ"} : (index) -> (index)
235c6f67b8eSKrzysztof Drewniak  // expected-error @below{{unknown}}
236c6f67b8eSKrzysztof Drewniak  "test.compare"(%0, %c6) {cmp = "LT"} : (index, index) -> ()
237c6f67b8eSKrzysztof Drewniak  return %1 : index
238c6f67b8eSKrzysztof Drewniak}
239