xref: /llvm-project/mlir/test/Dialect/Tosa/constant-op-fold.mlir (revision 956c0707d9098499a2682297b71f46b0a562eed9)
1// RUN: mlir-opt --split-input-file --tosa-layerwise-constant-fold %s | FileCheck %s
2
3
4// RUN: mlir-opt --split-input-file --tosa-layerwise-constant-fold="aggressive-reduce-constant=true" %s | FileCheck %s --check-prefix=AGGRESIVE
5
6// CHECK-LABEL: @armax_fold_dim_size_1
7func.func @armax_fold_dim_size_1(%arg0: tensor<2x1x3xf32>) -> tensor<2x3xi32> {
8  // CHECK: "tosa.const"() <{value = dense<0> : tensor<2x3xi32>}> : () -> tensor<2x3xi32>
9  %0 = tosa.argmax %arg0 {axis = 1 : i32}: (tensor<2x1x3xf32>) -> tensor<2x3xi32>
10  return %0 : tensor<2x3xi32>
11}
12
13// CHECK-LABEL: @argmax_dynamic_shape_no_fold_dim_size_1
14func.func @argmax_dynamic_shape_no_fold_dim_size_1(%arg0: tensor<?x1x3xf32>) -> tensor<?x3xi32> {
15  // CHECK: tosa.argmax
16  %0 = tosa.argmax %arg0 {axis = 1 : i32}: (tensor<?x1x3xf32>) -> tensor<?x3xi32>
17  return %0 : tensor<?x3xi32>
18}
19
20// CHECK-LABEL: @transpose_fold
21func.func @transpose_fold(%arg0: tensor<3x4xf32>) -> tensor<3x4xf32> {
22  // CHECK: return %arg0
23  %0 = arith.constant dense<[0, 1]> : tensor<2xi32>
24  %1 = tosa.transpose %arg0, %0 { perms = [1, 0] }: (tensor<3x4xf32>, tensor<2xi32>) -> tensor<3x4xf32>
25  return %1 : tensor<3x4xf32>
26}
27
28// CHECK-LABEL: @transpose_nofold
29func.func @transpose_nofold(%arg0: tensor<3x3xf32>) -> tensor<3x3xf32> {
30  // CHECK: tosa.transpose
31  %0 = arith.constant dense<[1, 0]> : tensor<2xi32>
32  %1 = tosa.transpose %arg0, %0 { perms = [1, 0] }: (tensor<3x3xf32>, tensor<2xi32>) -> tensor<3x3xf32>
33  return %1 : tensor<3x3xf32>
34}
35
36// CHECK-LABEL: @transpose_nofold_shape
37func.func @transpose_nofold_shape(%arg0: tensor<3x4xf32>) -> tensor<?x?xf32> {
38  // CHECK: tosa.transpose
39  %0 = arith.constant dense<[1, 0]> : tensor<2xi32>
40  %1 = tosa.transpose %arg0, %0 { perms = [1, 0] }: (tensor<3x4xf32>, tensor<2xi32>) -> tensor<?x?xf32>
41  return %1 : tensor<?x?xf32>
42}
43
44// CHECK-LABEL: @transpose_fold_splat
45func.func @transpose_fold_splat() -> tensor<3x2xf32> {
46  %input = "tosa.const"() {value = dense<4.0> : tensor<2x3xf32>} : () -> tensor<2x3xf32>
47  %perms = "tosa.const"() {value = dense<[1, 0]> : tensor<2xi32>} : () -> tensor<2xi32>
48  //               CHECK: %[[CST:.+]] = "tosa.const"() <{
49  // CHECK-SAME{LITERAL}: value = dense<4.000000e+00> : tensor<3x2xf32>
50  %1 = tosa.transpose %input, %perms : (tensor<2x3xf32>, tensor<2xi32>) -> tensor<3x2xf32>
51  // CHECK: return %[[CST]]
52  return %1 : tensor<3x2xf32>
53}
54
55// CHECK-LABEL: @transpose_fold_2d_float
56func.func @transpose_fold_2d_float() -> tensor<3x2xf32> {
57  %input = "tosa.const"() {value = dense<[[0.0, 1.0, 2.0], [3.0, 4.0, 5.0]]> : tensor<2x3xf32>} : () -> tensor<2x3xf32>
58  %perms = "tosa.const"() {value = dense<[1, 0]> : tensor<2xi32>} : () -> tensor<2xi32>
59  //               CHECK: %[[CST:.+]] = "tosa.const"() <{
60  // CHECK-SAME{LITERAL}: value = dense<[[0.000000e+00, 3.000000e+00], [1.000000e+00, 4.000000e+00], [2.000000e+00, 5.000000e+00]]> : tensor<3x2xf32>
61  %1 = tosa.transpose %input, %perms : (tensor<2x3xf32>, tensor<2xi32>) -> tensor<3x2xf32>
62  // CHECK: return %[[CST]]
63  return %1 : tensor<3x2xf32>
64}
65
66// CHECK-LABEL: @transpose_fold_2d_bool
67func.func @transpose_fold_2d_bool() -> tensor<3x2xi1> {
68  %input = "tosa.const"() {value = dense<[[true, false, false], [false, false, true]]> : tensor<2x3xi1>} : () -> tensor<2x3xi1>
69  %perms = "tosa.const"() {value = dense<[1, 0]> : tensor<2xi32>} : () -> tensor<2xi32>
70  //               CHECK: %[[CST:.+]] = "tosa.const"() <{
71  // CHECK-SAME{LITERAL}: value = dense<[[true, false], [false, false], [false, true]]> : tensor<3x2xi1>
72  %1 = tosa.transpose %input, %perms : (tensor<2x3xi1>, tensor<2xi32>) -> tensor<3x2xi1>
73  // CHECK: return %[[CST]]
74  return %1 : tensor<3x2xi1>
75}
76
77// CHECK-LABEL: @transpose_fold_4d_int
78func.func @transpose_fold_4d_int() -> tensor<3x1x4x2xi32> {
79  %input = "tosa.const"() {value = dense<[[
80    [[ 0,  1,  2,  3], [ 4,  5,  6,  7], [ 8,  9, 10, 11]],
81    [[12, 13, 14, 15], [16, 17, 18, 19], [20, 21, 22, 23]]
82  ]]> : tensor<1x2x3x4xi32>} : () -> tensor<1x2x3x4xi32>
83  %perms = "tosa.const"() {value = dense<[2, 0, 3, 1]> : tensor<4xi32>} : () -> tensor<4xi32>
84  //               CHECK: %[[CST:.+]] = "tosa.const"() <{
85  // CHECK-SAME{LITERAL}: value = dense<[
86  // CHECK-SAME{LITERAL}:   [[[0, 12], [1, 13], [2, 14], [3, 15]]],
87  // CHECK-SAME{LITERAL}:   [[[4, 16], [5, 17], [6, 18], [7, 19]]],
88  // CHECK-SAME{LITERAL}:   [[[8, 20], [9, 21], [10, 22], [11, 23]]]
89  // CHECK-SAME{LITERAL}: ]>
90  %1 = tosa.transpose %input, %perms : (tensor<1x2x3x4xi32>, tensor<4xi32>) -> tensor<3x1x4x2xi32>
91  // CHECK: return %[[CST]]
92  return %1 : tensor<3x1x4x2xi32>
93}
94
95// CHECK-LABEL: @transpose_nofold_non_cst_input
96func.func @transpose_nofold_non_cst_input(%input: tensor<2x3xf32>) -> tensor<3x2xf32> {
97  %perms = "tosa.const"() {value = dense<[1, 0]> : tensor<2xi32>} : () -> tensor<2xi32>
98  // CHECK: tosa.transpose
99  %1 = tosa.transpose %input, %perms : (tensor<2x3xf32>, tensor<2xi32>) -> tensor<3x2xf32>
100  return %1 : tensor<3x2xf32>
101}
102
103// CHECK-LABEL: @transpose_nofold_non_cst_perms
104func.func @transpose_nofold_non_cst_perms(%perms: tensor<2xi32>) -> tensor<3x2xf32> {
105  %input = "tosa.const"() {value = dense<[[0.0, 1.0, 2.0], [3.0, 4.0, 5.0]]> : tensor<2x3xf32>} : () -> tensor<2x3xf32>
106  // CHECK: tosa.transpose
107  %1 = tosa.transpose %input, %perms : (tensor<2x3xf32>, tensor<2xi32>) -> tensor<3x2xf32>
108  return %1 : tensor<3x2xf32>
109}
110
111// CHECK-LABEL: @transpose_nofold_multi_users
112func.func @transpose_nofold_multi_users() -> (tensor<3x2xf32>, tensor<2x3xf32>) {
113  %input = "tosa.const"() {value = dense<[[0.0, 1.0, 2.0], [3.0, 4.0, 5.0]]> : tensor<2x3xf32>} : () -> tensor<2x3xf32>
114  %perms = "tosa.const"() {value = dense<[1, 0]> : tensor<2xi32>} : () -> tensor<2xi32>
115  // CHECK: tosa.transpose
116  %1 = tosa.transpose %input, %perms : (tensor<2x3xf32>, tensor<2xi32>) -> tensor<3x2xf32>
117  return %1, %input : tensor<3x2xf32>, tensor<2x3xf32>
118}
119
120// CHECK-LABEL: @transpose_nofold_dense_resource
121func.func @transpose_nofold_dense_resource() -> tensor<2x2xf32> {
122  %0 = "tosa.const"() <{value = dense_resource<resource> : tensor<2x2xf32>}> : () -> tensor<2x2xf32>
123  %1 = "tosa.const"() <{value = dense<[1, 0]> : tensor<2xi32>}> : () -> tensor<2xi32>
124
125  // CHECK: tosa.transpose
126  %2 = tosa.transpose %0, %1 : (tensor<2x2xf32>, tensor<2xi32>) -> tensor<2x2xf32>
127  return %2 : tensor<2x2xf32>
128}
129{-#
130  dialect_resources: {
131    builtin: {
132      resource: "0x08000000010000000000000002000000000000000300000000000000"
133    }
134  }
135#-}
136
137// -----
138
139// CHECK-LABEL: @fold_add_zero_rhs_f32
140func.func @fold_add_zero_rhs_f32(%arg0: tensor<f32>) -> tensor<f32> {
141  %zero = "tosa.const"() {value = dense<0.0> : tensor<f32>} : () -> tensor<f32>
142  %add = tosa.add %arg0, %zero : (tensor<f32>, tensor<f32>) -> tensor<f32>
143  // CHECK: return %arg0
144  return %add : tensor<f32>
145}
146
147// -----
148
149// CHECK-LABEL: @fold_add_zero_lhs_f32
150func.func @fold_add_zero_lhs_f32(%arg0: tensor<f32>) -> tensor<f32> {
151  %zero = "tosa.const"() {value = dense<0.0> : tensor<f32>} : () -> tensor<f32>
152  %add = tosa.add %zero, %arg0 : (tensor<f32>, tensor<f32>) -> tensor<f32>
153  // CHECK: return %arg0
154  return %add : tensor<f32>
155}
156
157// -----
158
159// CHECK-LABEL: @fold_add_zero_rhs_i32
160func.func @fold_add_zero_rhs_i32(%arg0: tensor<i32>) -> tensor<i32> {
161  %zero = "tosa.const"() {value = dense<0> : tensor<i32>} : () -> tensor<i32>
162  %add = tosa.add %arg0, %zero : (tensor<i32>, tensor<i32>) -> tensor<i32>
163  // CHECK: return %arg0
164  return %add : tensor<i32>
165}
166
167// -----
168
169// CHECK-LABEL: @fold_add_zero_lhs_i32
170func.func @fold_add_zero_lhs_i32(%arg0: tensor<i32>) -> tensor<i32> {
171  %zero = "tosa.const"() {value = dense<0> : tensor<i32>} : () -> tensor<i32>
172  %add = tosa.add %zero, %arg0 : (tensor<i32>, tensor<i32>) -> tensor<i32>
173  // CHECK: return %arg0
174  return %add : tensor<i32>
175}
176
177// -----
178
179// CHECK-LABEL: @fold_add_splat_i32
180func.func @fold_add_splat_i32() -> tensor<10xi32> {
181  %one = "tosa.const"() {value = dense<1> : tensor<10xi32>} : () -> tensor<10xi32>
182  %two = "tosa.const"() {value = dense<2> : tensor<10xi32>} : () -> tensor<10xi32>
183  %add = tosa.add %one, %two : (tensor<10xi32>, tensor<10xi32>) -> tensor<10xi32>
184  // CHECK: %[[THREE:.+]] = "tosa.const"() <{value = dense<3> : tensor<10xi32>}
185  // CHECK: return %[[THREE]]
186  return %add : tensor<10xi32>
187}
188
189// -----
190
191// CHECK-LABEL: @fold_add_splat_f32
192func.func @fold_add_splat_f32() -> tensor<10xf32> {
193  %one = "tosa.const"() {value = dense<1.0> : tensor<10xf32>} : () -> tensor<10xf32>
194  %two = "tosa.const"() {value = dense<2.0> : tensor<10xf32>} : () -> tensor<10xf32>
195  %add = tosa.add %one, %two : (tensor<10xf32>, tensor<10xf32>) -> tensor<10xf32>
196  // CHECK: %[[THREE:.+]] = "tosa.const"() <{value = dense<3.000000e+00>
197  // CHECK: return %[[THREE]]
198  return %add : tensor<10xf32>
199}
200
201// -----
202
203// CHECK-LABEL: @fold_div_zero_lhs_i32
204func.func @fold_div_zero_lhs_i32(%arg0: tensor<i32>) -> tensor<i32> {
205  %zero = "tosa.const"() {value = dense<0> : tensor<i32>} : () -> tensor<i32>
206  // CHECK: %[[ZERO:.+]] = "tosa.const"() <{value = dense<0>
207  %div = tosa.int_div %zero, %arg0 : (tensor<i32>, tensor<i32>) -> tensor<i32>
208  // CHECK: return %[[ZERO]]
209  return %div : tensor<i32>
210}
211
212// -----
213
214// CHECK-LABEL: @fold_div_one_rhs_i32
215func.func @fold_div_one_rhs_i32(%arg0: tensor<i32>) -> tensor<i32> {
216  %one = "tosa.const"() {value = dense<1> : tensor<i32>} : () -> tensor<i32>
217  %div = tosa.int_div %arg0, %one : (tensor<i32>, tensor<i32>) -> tensor<i32>
218  // CHECK: return %arg0
219  return %div : tensor<i32>
220}
221
222// -----
223
224// CHECK-LABEL: @fold_div_splat_i32
225func.func @fold_div_splat_i32() -> tensor<i32> {
226  %lhs = "tosa.const"() {value = dense<10> : tensor<i32>} : () -> tensor<i32>
227  %rhs = "tosa.const"() {value = dense<-3> : tensor<i32>} : () -> tensor<i32>
228  // CHECK: %[[SPLAT:.+]] = "tosa.const"() <{value = dense<-3>
229  %div = tosa.int_div %lhs, %rhs : (tensor<i32>, tensor<i32>) -> tensor<i32>
230  // CHECK: return %[[SPLAT]]
231  return %div : tensor<i32>
232}
233
234// -----
235
236
237// CHECK-LABEL: @fold_mul_zero_rhs_f32
238func.func @fold_mul_zero_rhs_f32(%arg0: tensor<f32>) -> tensor<f32> {
239  %zero = "tosa.const"() {value = dense<0.0> : tensor<f32>} : () -> tensor<f32>
240  // CHECK: %[[ZERO:.+]] = "tosa.const"() <{value = dense<0.000000e+00>
241  %mul = tosa.mul %arg0, %zero : (tensor<f32>, tensor<f32>) -> tensor<f32>
242  // CHECK: return %[[ZERO]]
243  return %mul : tensor<f32>
244}
245
246// -----
247
248// CHECK-LABEL: @fold_mul_zero_lhs_f32
249func.func @fold_mul_zero_lhs_f32(%arg0: tensor<f32>) -> tensor<f32> {
250  %zero = "tosa.const"() {value = dense<0.0> : tensor<f32>} : () -> tensor<f32>
251  // CHECK: %[[ZERO:.+]] = "tosa.const"() <{value = dense<0.000000e+00>
252  %mul = tosa.mul %zero, %arg0 : (tensor<f32>, tensor<f32>) -> tensor<f32>
253  // CHECK: return %[[ZERO]]
254  return %mul : tensor<f32>
255}
256
257// -----
258
259// CHECK-LABEL: @fold_mul_zero_rhs_i32
260func.func @fold_mul_zero_rhs_i32(%arg0: tensor<i32>) -> tensor<i32> {
261  %zero = "tosa.const"() {value = dense<0> : tensor<i32>} : () -> tensor<i32>
262  %shift = "tosa.const"() <{value = dense<0> : tensor<1xi8>}> : () -> tensor<1xi8>
263  // CHECK: %[[ZERO:.+]] = "tosa.const"() <{value = dense<0>
264  %mul = tosa.mul %arg0, %zero, %shift : (tensor<i32>, tensor<i32>, tensor<1xi8>) -> tensor<i32>
265  // CHECK: return %[[ZERO]]
266  return %mul : tensor<i32>
267}
268
269// -----
270
271// CHECK-LABEL: @fold_mul_zero_lhs_i32
272func.func @fold_mul_zero_lhs_i32(%arg0: tensor<i32>) -> tensor<i32> {
273  %zero = "tosa.const"() {value = dense<0> : tensor<i32>} : () -> tensor<i32>
274  %shift = "tosa.const"() <{value = dense<0> : tensor<1xi8>}> : () -> tensor<1xi8>
275  // CHECK: %[[ZERO:.+]] = "tosa.const"() <{value = dense<0>
276  %mul = tosa.mul %zero, %arg0, %shift : (tensor<i32>, tensor<i32>, tensor<1xi8>) -> tensor<i32>
277  // CHECK: return %[[ZERO]]
278  return %mul : tensor<i32>
279}
280
281// -----
282
283// CHECK-LABEL: @fold_mul_one_rhs_f32
284func.func @fold_mul_one_rhs_f32(%arg0: tensor<f32>) -> tensor<f32> {
285  %one = "tosa.const"() {value = dense<1.0> : tensor<f32>} : () -> tensor<f32>
286  %mul = tosa.mul %arg0, %one : (tensor<f32>, tensor<f32>) -> tensor<f32>
287  // CHECK: return %arg0
288  return %mul : tensor<f32>
289}
290
291// -----
292
293// CHECK-LABEL: @fold_mul_one_lhs_f32
294func.func @fold_mul_one_lhs_f32(%arg0: tensor<f32>) -> tensor<f32> {
295  %one = "tosa.const"() {value = dense<1.0> : tensor<f32>} : () -> tensor<f32>
296  %mul = tosa.mul %one, %arg0 : (tensor<f32>, tensor<f32>) -> tensor<f32>
297  // CHECK: return %arg0
298  return %mul : tensor<f32>
299}
300
301// -----
302
303// CHECK-LABEL: @fold_mul_one_rhs_i32
304func.func @fold_mul_one_rhs_i32(%arg0: tensor<i32>) -> tensor<i32> {
305  %one = "tosa.const"() {value = dense<64> : tensor<i32>} : () -> tensor<i32>
306  %shift = "tosa.const"() {value = dense<6> : tensor<1xi8>} : () -> tensor<1xi8>
307  %mul = tosa.mul %arg0, %one, %shift : (tensor<i32>, tensor<i32>, tensor<1xi8>) -> tensor<i32>
308  // CHECK: return %arg0
309  return %mul : tensor<i32>
310}
311
312// -----
313
314// CHECK-LABEL: @fold_mul_one_lhs_i32
315func.func @fold_mul_one_lhs_i32(%arg0: tensor<i32>) -> tensor<i32> {
316  %one = "tosa.const"() {value = dense<64> : tensor<i32>} : () -> tensor<i32>
317  %shift = "tosa.const"() {value = dense<6> : tensor<1xi8>} : () -> tensor<1xi8>
318  %mul = tosa.mul %one, %arg0, %shift : (tensor<i32>, tensor<i32>, tensor<1xi8>) -> tensor<i32>
319  // CHECK: return %arg0
320  return %mul : tensor<i32>
321}
322
323// -----
324
325// CHECK-LABEL: @fold_mul_splat_i8
326func.func @fold_mul_splat_i8() -> tensor<10xi32> {
327  %one = "tosa.const"() {value = dense<17> : tensor<10xi8>} : () -> tensor<10xi8>
328  %two = "tosa.const"() {value = dense<32> : tensor<10xi8>} : () -> tensor<10xi8>
329  %shift = "tosa.const"() {value = dense<3> : tensor<1xi8>} : () -> tensor<1xi8>
330  %mul = tosa.mul %one, %two, %shift : (tensor<10xi8>, tensor<10xi8>, tensor<1xi8>) -> tensor<10xi32>
331  // CHECK: %[[THREE:.+]] = "tosa.const"() <{value = dense<68> : tensor<10xi32>}
332  // CHECK: return %[[THREE]]
333  return %mul : tensor<10xi32>
334}
335
336// -----
337
338// CHECK-LABEL: @fold_mul_splat_f32
339func.func @fold_mul_splat_f32() -> tensor<10xf32> {
340  %one = "tosa.const"() {value = dense<3.0> : tensor<10xf32>} : () -> tensor<10xf32>
341  %two = "tosa.const"() {value = dense<2.0> : tensor<10xf32>} : () -> tensor<10xf32>
342  %mul = tosa.mul %one, %two : (tensor<10xf32>, tensor<10xf32>) -> tensor<10xf32>
343  // CHECK: %[[THREE:.+]] = "tosa.const"() <{value = dense<6.000000e+00> : tensor<10xf32>}
344  // CHECK: return %[[THREE]]
345  return %mul : tensor<10xf32>
346}
347
348// -----
349
350// CHECK-LABEL: @fold_sub_zero_rhs_f32
351func.func @fold_sub_zero_rhs_f32(%arg0: tensor<f32>) -> tensor<f32> {
352  %zero = "tosa.const"() {value = dense<0.0> : tensor<f32>} : () -> tensor<f32>
353  %sub = tosa.sub %arg0, %zero : (tensor<f32>, tensor<f32>) -> tensor<f32>
354  // CHECK: return %arg0
355  return %sub : tensor<f32>
356}
357
358// -----
359
360// CHECK-LABEL: @fold_sub_zero_rhs_i32
361func.func @fold_sub_zero_rhs_i32(%arg0: tensor<i32>) -> tensor<i32> {
362  %zero = "tosa.const"() {value = dense<0> : tensor<i32>} : () -> tensor<i32>
363  %sub = tosa.sub %arg0, %zero : (tensor<i32>, tensor<i32>) -> tensor<i32>
364  // CHECK: return %arg0
365  return %sub : tensor<i32>
366}
367
368// -----
369
370// CHECK-LABEL: @fold_sub_splat_i32
371func.func @fold_sub_splat_i32() -> tensor<10xi32> {
372  %one = "tosa.const"() {value = dense<1> : tensor<10xi32>} : () -> tensor<10xi32>
373  %two = "tosa.const"() {value = dense<2> : tensor<10xi32>} : () -> tensor<10xi32>
374  %sub = tosa.sub %one, %two : (tensor<10xi32>, tensor<10xi32>) -> tensor<10xi32>
375  // CHECK: %[[THREE:.+]] = "tosa.const"() <{value = dense<-1> : tensor<10xi32>}
376  // CHECK: return %[[THREE]]
377  return %sub : tensor<10xi32>
378}
379
380// -----
381
382// CHECK-LABEL: @fold_sub_splat_f32
383func.func @fold_sub_splat_f32() -> tensor<10xf32> {
384  %one = "tosa.const"() {value = dense<1.0> : tensor<10xf32>} : () -> tensor<10xf32>
385  %two = "tosa.const"() {value = dense<2.0> : tensor<10xf32>} : () -> tensor<10xf32>
386  %sub = tosa.sub %one, %two : (tensor<10xf32>, tensor<10xf32>) -> tensor<10xf32>
387  // CHECK: %[[THREE:.+]] = "tosa.const"() <{value = dense<-1.000000e+00> : tensor<10xf32>}
388  // CHECK: return %[[THREE]]
389  return %sub : tensor<10xf32>
390}
391
392// -----
393
394// CHECK-LABEL: @fold_greater_splat_f32
395func.func @fold_greater_splat_f32() -> (tensor<10xi1>, tensor<10xi1>) {
396  %0 = "tosa.const"() {value = dense<4.0> : tensor<10xf32>} : () -> tensor<10xf32>
397  %1 = "tosa.const"() {value = dense<2.0> : tensor<10xf32>} : () -> tensor<10xf32>
398  %2 = "tosa.const"() {value = dense<1.0> : tensor<10xf32>} : () -> tensor<10xf32>
399  %3 = "tosa.const"() {value = dense<2.0> : tensor<10xf32>} : () -> tensor<10xf32>
400  %true = tosa.greater %0, %1 : (tensor<10xf32>, tensor<10xf32>) -> tensor<10xi1>
401  %false = tosa.greater %2, %3 : (tensor<10xf32>, tensor<10xf32>) -> tensor<10xi1>
402  // CHECK-DAG: %[[TRUE:.+]] = "tosa.const"() <{value = dense<true> : tensor<10xi1>}
403  // CHECK-DAG: %[[FALSE:.+]] = "tosa.const"() <{value = dense<false> : tensor<10xi1>}
404  // CHECK: return %[[TRUE]], %[[FALSE]]
405  return %true, %false : tensor<10xi1>, tensor<10xi1>
406}
407
408// -----
409
410// CHECK-LABEL: @fold_greater_splat_i32
411func.func @fold_greater_splat_i32() -> (tensor<10xi1>, tensor<10xi1>) {
412  %0 = "tosa.const"() {value = dense<-10> : tensor<10xi32>} : () -> tensor<10xi32>
413  %1 = "tosa.const"() {value = dense<8> : tensor<10xi32>} : () -> tensor<10xi32>
414  %2 = "tosa.const"() {value = dense<-10> : tensor<10xi32>} : () -> tensor<10xi32>
415  %3 = "tosa.const"() {value = dense<-12> : tensor<10xi32>} : () -> tensor<10xi32>
416  %false = tosa.greater %0, %1 : (tensor<10xi32>, tensor<10xi32>) -> tensor<10xi1>
417  %true = tosa.greater %2, %3 : (tensor<10xi32>, tensor<10xi32>) -> tensor<10xi1>
418  // CHECK-DAG: %[[FALSE:.+]] = "tosa.const"() <{value = dense<false> : tensor<10xi1>}
419  // CHECK-DAG: %[[TRUE:.+]] = "tosa.const"() <{value = dense<true> : tensor<10xi1>}
420  // CHECK: return %[[FALSE]], %[[TRUE]]
421  return %false, %true : tensor<10xi1>, tensor<10xi1>
422}
423
424// -----
425
426// CHECK-LABEL: @fold_greater_eq_splat_f32
427func.func @fold_greater_eq_splat_f32() -> (tensor<10xi1>, tensor<10xi1>) {
428  %0 = "tosa.const"() {value = dense<4.0> : tensor<10xf32>} : () -> tensor<10xf32>
429  %1 = "tosa.const"() {value = dense<4.0> : tensor<10xf32>} : () -> tensor<10xf32>
430  %2 = "tosa.const"() {value = dense<1.0> : tensor<10xf32>} : () -> tensor<10xf32>
431  %3 = "tosa.const"() {value = dense<2.0> : tensor<10xf32>} : () -> tensor<10xf32>
432  %true = tosa.greater_equal %0, %1 : (tensor<10xf32>, tensor<10xf32>) -> tensor<10xi1>
433  %false = tosa.greater_equal %2, %3 : (tensor<10xf32>, tensor<10xf32>) -> tensor<10xi1>
434  // CHECK-DAG: %[[TRUE:.+]] = "tosa.const"() <{value = dense<true> : tensor<10xi1>}
435  // CHECK-DAG: %[[FALSE:.+]] = "tosa.const"() <{value = dense<false> : tensor<10xi1>}
436  // CHECK: return %[[TRUE]], %[[FALSE]]
437  return %true, %false : tensor<10xi1>, tensor<10xi1>
438}
439
440// -----
441
442// CHECK-LABEL: @fold_greater_eq_splat_i32
443func.func @fold_greater_eq_splat_i32() -> (tensor<10xi1>, tensor<10xi1>) {
444  %0 = "tosa.const"() {value = dense<-10> : tensor<10xi32>} : () -> tensor<10xi32>
445  %1 = "tosa.const"() {value = dense<8> : tensor<10xi32>} : () -> tensor<10xi32>
446  %2 = "tosa.const"() {value = dense<-10> : tensor<10xi32>} : () -> tensor<10xi32>
447  %3 = "tosa.const"() {value = dense<-10> : tensor<10xi32>} : () -> tensor<10xi32>
448  %true = tosa.greater_equal %2, %3 : (tensor<10xi32>, tensor<10xi32>) -> tensor<10xi1>
449  %false = tosa.greater_equal %0, %1 : (tensor<10xi32>, tensor<10xi32>) -> tensor<10xi1>
450  // CHECK-DAG: %[[TRUE:.+]] = "tosa.const"() <{value = dense<true> : tensor<10xi1>}
451  // CHECK-DAG: %[[FALSE:.+]] = "tosa.const"() <{value = dense<false> : tensor<10xi1>}
452  // CHECK: return %[[TRUE]], %[[FALSE]]
453  return %true, %false : tensor<10xi1>, tensor<10xi1>
454}
455
456// -----
457
458// CHECK-LABEL: @fold_eq_splat_f32
459func.func @fold_eq_splat_f32() -> (tensor<10xi1>, tensor<10xi1>) {
460  %0 = "tosa.const"() {value = dense<4.0> : tensor<10xf32>} : () -> tensor<10xf32>
461  %1 = "tosa.const"() {value = dense<4.0> : tensor<10xf32>} : () -> tensor<10xf32>
462  %2 = "tosa.const"() {value = dense<1.0> : tensor<10xf32>} : () -> tensor<10xf32>
463  %3 = "tosa.const"() {value = dense<2.0> : tensor<10xf32>} : () -> tensor<10xf32>
464  %true = tosa.equal %0, %1 : (tensor<10xf32>, tensor<10xf32>) -> tensor<10xi1>
465  %false = tosa.equal %2, %3 : (tensor<10xf32>, tensor<10xf32>) -> tensor<10xi1>
466  // CHECK-DAG: %[[TRUE:.+]] = "tosa.const"() <{value = dense<true> : tensor<10xi1>}
467  // CHECK-DAG: %[[FALSE:.+]] = "tosa.const"() <{value = dense<false> : tensor<10xi1>}
468  // CHECK: return %[[TRUE]], %[[FALSE]]
469  return %true, %false : tensor<10xi1>, tensor<10xi1>
470}
471
472// -----
473
474// CHECK-LABEL: @fold_eq_splat_i32
475func.func @fold_eq_splat_i32() -> (tensor<10xi1>, tensor<10xi1>) {
476  %0 = "tosa.const"() {value = dense<-10> : tensor<10xi32>} : () -> tensor<10xi32>
477  %1 = "tosa.const"() {value = dense<8> : tensor<10xi32>} : () -> tensor<10xi32>
478  %2 = "tosa.const"() {value = dense<-10> : tensor<10xi32>} : () -> tensor<10xi32>
479  %3 = "tosa.const"() {value = dense<-10> : tensor<10xi32>} : () -> tensor<10xi32>
480  %true = tosa.equal %2, %3 : (tensor<10xi32>, tensor<10xi32>) -> tensor<10xi1>
481  %false = tosa.equal %0, %1 : (tensor<10xi32>, tensor<10xi32>) -> tensor<10xi1>
482  // CHECK-DAG: %[[TRUE:.+]] = "tosa.const"() <{value = dense<true> : tensor<10xi1>}
483  // CHECK-DAG: %[[FALSE:.+]] = "tosa.const"() <{value = dense<false> : tensor<10xi1>}
484  // CHECK: return %[[TRUE]], %[[FALSE]]
485  return %true, %false : tensor<10xi1>, tensor<10xi1>
486}
487
488// -----
489
490// CHECK-LABEL: @fold_eq_i32
491func.func @fold_eq_i32(%arg0 : tensor<10xi32>) -> (tensor<10xi1>) {
492  // CHECK: %[[TRUE:.+]] = "tosa.const"() <{value = dense<true> : tensor<10xi1>}
493  %0 = tosa.equal %arg0, %arg0 : (tensor<10xi32>, tensor<10xi32>) -> tensor<10xi1>
494  // CHECK: return %[[TRUE]]
495  return %0 : tensor<10xi1>
496}
497
498// -----
499
500func.func @reshape_splat() -> tensor<6x5x4xi32> {
501  // CHECK: %[[SPLAT:.+]] = "tosa.const"() <{value = dense<42> : tensor<6x5x4xi32>}
502  %splat = "tosa.const"() {value = dense<42> : tensor<4x5x6xi32>} : () -> tensor<4x5x6xi32>
503  %reshape = tosa.reshape %splat { new_shape = array<i64: 6, 5, 4> } : (tensor<4x5x6xi32>) -> tensor<6x5x4xi32>
504  // CHECK: return %[[SPLAT]]
505  return %reshape : tensor<6x5x4xi32>
506}
507
508// -----
509
510// CHECK-LABEL: @slice_splat
511func.func @slice_splat() -> tensor<1x1x1xi32> {
512  // CHECK: %[[SLICE:.+]] = "tosa.const"() <{value = dense<42> : tensor<1x1x1xi32>}
513  %splat = "tosa.const"() {value = dense<42> : tensor<4x5x6xi32>} : () -> tensor<4x5x6xi32>
514  %start = tosa.const_shape {value = dense<[1, 2, 3]> : tensor<3xindex>} : () -> !tosa.shape<3>
515  %size = tosa.const_shape {value = dense<[1, 1, 1]> : tensor<3xindex>} : () -> !tosa.shape<3>
516  %slice= tosa.slice %splat, %start, %size : (tensor<4x5x6xi32>, !tosa.shape<3>, !tosa.shape<3>) -> tensor<1x1x1xi32>
517
518  // CHECK: return %[[SLICE]]
519  return %slice : tensor<1x1x1xi32>
520}
521
522// -----
523
524// CHECK-LABEL: @slice_singleton
525func.func @slice_singleton() -> tensor<1x1xi32> {
526  %splat = "tosa.const"() {value = dense<[[0, 1, 2], [3, 4, 5], [6, 7 ,8]]> : tensor<3x3xi32>} : () -> tensor<3x3xi32>
527  // CHECK: %[[SLICE:.+]] = "tosa.const"() <{value = dense<4> : tensor<1x1xi32>}
528  %start = tosa.const_shape {value = dense<[1, 1]> : tensor<2xindex>} : () -> !tosa.shape<2>
529  %size = tosa.const_shape {value = dense<[1, 1]> : tensor<2xindex>} : () -> !tosa.shape<2>
530  %slice= tosa.slice %splat, %start, %size : (tensor<3x3xi32>, !tosa.shape<2>, !tosa.shape<2>) -> tensor<1x1xi32>
531  // CHECK: return %[[SLICE]]
532  return %slice : tensor<1x1xi32>
533}
534
535// -----
536
537// CHECK: func.func @cast_float_to_float
538func.func @cast_float_to_float() -> tensor<f16> {
539  %splat = "tosa.const"() {value = dense<42.0> : tensor<f32>} : () -> tensor<f32>
540  // CHECK: %[[SPLAT:.+]] = "tosa.const"() <{value = dense<4.200000e+01> : tensor<f16>}
541  %cast = tosa.cast %splat : (tensor<f32>) -> tensor<f16>
542  // CHECK: return %[[SPLAT]]
543  return %cast : tensor<f16>
544}
545
546// -----
547
548// CHECK: func.func @cast_int_to_float
549func.func @cast_int_to_float() -> tensor<f16> {
550  %splat = "tosa.const"() {value = dense<4> : tensor<i32>} : () -> tensor<i32>
551  // CHECK: %[[SPLAT:.+]] = "tosa.const"() <{value = dense<4.000000e+00> : tensor<f16>}
552  %cast = tosa.cast %splat : (tensor<i32>) -> tensor<f16>
553  // CHECK: return %[[SPLAT]]
554  return %cast : tensor<f16>
555}
556
557// -----
558
559// CHECK: func.func @cast_float_to_int
560func.func @cast_float_to_int() -> tensor<i16> {
561  %splat = "tosa.const"() {value = dense<-4.0> : tensor<f32>} : () -> tensor<f32>
562  // CHECK: %[[SPLAT:.+]] = "tosa.const"() <{value = dense<-4> : tensor<i16>}
563  %cast = tosa.cast %splat : (tensor<f32>) -> tensor<i16>
564  // CHECK: return %[[SPLAT]]
565  return %cast : tensor<i16>
566}
567
568// -----
569
570// CHECK: func.func @cast_float_to_int_round
571func.func @cast_float_to_int_round() -> tensor<i16> {
572  %splat = "tosa.const"() {value = dense<-3.5> : tensor<f32>} : () -> tensor<f32>
573  // CHECK: %[[SPLAT:.+]] = "tosa.const"() <{value = dense<-4> : tensor<i16>}
574  %cast = tosa.cast %splat : (tensor<f32>) -> tensor<i16>
575  // CHECK: return %[[SPLAT]]
576  return %cast : tensor<i16>
577}
578
579// -----
580
581// CHECK: func.func @cast_int_to_int_trunc
582func.func @cast_int_to_int_trunc() -> tensor<i16> {
583  %splat = "tosa.const"() {value = dense<-1> : tensor<i32>} : () -> tensor<i32>
584  // CHECK: %[[SPLAT:.+]] = "tosa.const"() <{value = dense<-1> : tensor<i16>}
585  %cast = tosa.cast %splat : (tensor<i32>) -> tensor<i16>
586  // CHECK: return %[[SPLAT]]
587  return %cast : tensor<i16>
588}
589
590// -----
591
592// CHECK: func.func @cast_int_to_int_sign
593func.func @cast_int_to_int_sign() -> tensor<i32> {
594  %splat = "tosa.const"() {value = dense<-1> : tensor<i16>} : () -> tensor<i16>
595  // CHECK: %[[SPLAT:.+]] = "tosa.const"() <{value = dense<-1> : tensor<i32>}
596  %cast = tosa.cast %splat : (tensor<i16>) -> tensor<i32>
597  // CHECK: return %[[SPLAT]]
598  return %cast : tensor<i32>
599}
600
601// -----
602
603// CHECK-LABEL: @reverse_splat
604func.func @reverse_splat() -> tensor<10xi32> {
605  // CHECK: %[[SPLAT:.+]] = "tosa.const"() <{value = dense<42> : tensor<10xi32>}
606  %splat = "tosa.const"() {value = dense<42> : tensor<10xi32>} : () -> tensor<10xi32>
607  %reverse = tosa.reverse %splat { axis = 0 : i32 } : (tensor<10xi32>) -> tensor<10xi32>
608  // CHECK: return %[[SPLAT]]
609  return %reverse : tensor<10xi32>
610}
611
612// -----
613
614// CHECK-LABEL: @reverse_length_one
615func.func @reverse_length_one(%arg0 : tensor<10x1xi32>) -> (tensor<10x1xi32>, tensor<10x1xi32>) {
616  %nofold = tosa.reverse %arg0 { axis = 0 : i32 } : (tensor<10x1xi32>) -> tensor<10x1xi32>
617  %fold = tosa.reverse %arg0 { axis = 1 : i32 } : (tensor<10x1xi32>) -> tensor<10x1xi32>
618  // CHECK: %[[NOFOLD:.+]] = tosa.reverse %arg0 {axis = 0 : i32}
619  // CHECK: return %[[NOFOLD]], %arg0
620  return %nofold, %fold : tensor<10x1xi32>, tensor<10x1xi32>
621}
622
623// -----
624
625  func.func @reduce_sum_constant() -> tensor<1x3xi32> {
626    // CHECK-LABEL:   func.func @reduce_sum_constant() -> tensor<1x3xi32> {
627    // CHECK:    %[[VAL_0:.*]] = "tosa.const"() <{value = dense<{{\[\[}}5, 7, 9]]> : tensor<1x3xi32>}> : () -> tensor<1x3xi32>
628    // CHECK:         return %[[VAL_0]] : tensor<1x3xi32>
629
630    %const = "tosa.const"() {value = dense<[[1,2,3], [4,5,6]]> : tensor<2x3xi32>} : () -> tensor<2x3xi32>
631    %0 = tosa.reduce_sum %const {axis = 0 : i32} : (tensor<2x3xi32>) -> tensor<1x3xi32>
632    return %0 : tensor<1x3xi32>
633  }
634
635// -----
636
637  func.func @reduce_sum_constant() -> tensor<2x1xi32> {
638  // CHECK-LABEL:   func.func @reduce_sum_constant() -> tensor<2x1xi32> {
639  // CHECK:           %[[VAL_0:.*]] = "tosa.const"() <{value = dense<{{\[\[}}6], [15]]> : tensor<2x1xi32>}> : () -> tensor<2x1xi32>
640  // CHECK:           return %[[VAL_0]] : tensor<2x1xi32>
641  // CHECK:         }
642    %const = "tosa.const"() <{value = dense<[[1,2,3], [4,5,6]]> : tensor<2x3xi32>}> : () -> tensor<2x3xi32>
643    %0 = tosa.reduce_sum %const {axis = 1 : i32} : (tensor<2x3xi32>) -> tensor<2x1xi32>
644    return %0 : tensor<2x1xi32>
645  }
646
647
648// -----
649
650func.func @reduce_sum_constant() -> tensor<3x1xi32> {
651  // CHECK-LABEL:   func.func @reduce_sum_constant() -> tensor<3x1xi32> {
652  // CHECK:           %[[VAL_0:.*]] = "tosa.const"() <{value = dense<{{\[\[}}6], [15], [24]]> : tensor<3x1xi32>}> : () -> tensor<3x1xi32>
653  // CHECK:           return %[[VAL_0]] : tensor<3x1xi32>
654  // CHECK:         }
655  %const = "tosa.const"() <{value = dense<[[1, 2, 3], [4, 5, 6], [7, 8, 9]]> : tensor<3x3xi32>}> : () -> tensor<3x3xi32>
656  %0 = tosa.reduce_sum %const {axis = 1 : i32} : (tensor<3x3xi32>) -> tensor<3x1xi32>
657  return %0 : tensor<3x1xi32>
658}
659
660// -----
661
662func.func @reduce_sum_constant() -> tensor<2x1x4xi32> {
663  // CHECK-LABEL:   func.func @reduce_sum_constant() -> tensor<2x1x4xi32> {
664  // CHECK:           %[[VAL_0:.*]] = "tosa.const"() <{value = dense<{{\[\[}}[15, 18, 21, 24]], {{\[\[}}51, 54, 57, 60]]]> : tensor<2x1x4xi32>}> : () -> tensor<2x1x4xi32>
665  // CHECK:           return %[[VAL_0]] : tensor<2x1x4xi32>
666  // CHECK:         }
667  %const = "tosa.const"() <{value = dense<[[[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]], [[13, 14, 15, 16], [17, 18, 19, 20], [21, 22, 23, 24]]]> : tensor<2x3x4xi32>}> : () -> tensor<2x3x4xi32>
668  %0 = tosa.reduce_sum %const {axis = 1 : i32} : (tensor<2x3x4xi32>) -> tensor<2x1x4xi32>
669  return %0 : tensor<2x1x4xi32>
670}
671
672// -----
673
674func.func @reduce_sum_constant() -> tensor<1x3x3xi32> {
675  // CHECK-LABEL:   func.func @reduce_sum_constant() -> tensor<1x3x3xi32> {
676  // CHECK:           %[[VAL_0:.*]] = "tosa.const"() <{value = dense<{{\[\[}}[30, 33, 36], [39, 42, 45], [48, 51, 54]]]> : tensor<1x3x3xi32>}> : () -> tensor<1x3x3xi32>
677  // CHECK:           return %[[VAL_0]] : tensor<1x3x3xi32>
678  // CHECK:         }
679  %const = "tosa.const"() <{value = dense<[[[1, 2, 3], [4, 5, 6], [7, 8, 9]], [[10, 11, 12], [13, 14, 15], [16, 17, 18]], [[19, 20, 21], [22, 23, 24], [25, 26, 27]]]> : tensor<3x3x3xi32>}> : () -> tensor<3x3x3xi32>
680  %0 = tosa.reduce_sum %const {axis = 0 : i32} : (tensor<3x3x3xi32>) -> tensor<1x3x3xi32>
681  return %0 : tensor<1x3x3xi32>
682}
683
684// -----
685
686func.func @reduce_sum_constant() -> tensor<2x2x2x1xi32> {
687  // CHECK-LABEL:   func.func @reduce_sum_constant() -> tensor<2x2x2x1xi32> {
688  // CHECK:           %[[VAL_0:.*]] = "tosa.const"() <{value = dense<{{\[\[}}{{\[\[}}3], [7]], {{\[\[}}11], [15]]], {{\[\[}}[19], [23]], {{\[\[}}27], [31]]]]> : tensor<2x2x2x1xi32>}> : () -> tensor<2x2x2x1xi32>
689  // CHECK:           return %[[VAL_0]] : tensor<2x2x2x1xi32>
690  // CHECK:         }
691  %const = "tosa.const"() <{value = dense<[[[[1, 2], [3, 4]], [[5, 6], [7, 8]]], [[[9, 10], [11, 12]], [[13, 14], [15, 16]]]]> : tensor<2x2x2x2xi32>}> : () -> tensor<2x2x2x2xi32>
692  %0 = tosa.reduce_sum %const {axis = 3 : i32} : (tensor<2x2x2x2xi32>) -> tensor<2x2x2x1xi32>
693  return %0 : tensor<2x2x2x1xi32>
694}
695
696// -----
697
698func.func @reduce_sum_constant() -> tensor<1x1x1xi32> {
699  // CHECK-LABEL:   func.func @reduce_sum_constant() -> tensor<1x1x1xi32> {
700  // CHECK:           %[[VAL_0:.*]] = "tosa.const"() <{value = dense<42> : tensor<1x1x1xi32>}> : () -> tensor<1x1x1xi32>
701  // CHECK:           return %[[VAL_0]] : tensor<1x1x1xi32>
702  // CHECK:         }
703  %const = "tosa.const"() <{value = dense<[[[42]]]> : tensor<1x1x1xi32>}> : () -> tensor<1x1x1xi32>
704  %0 = tosa.reduce_sum %const {axis = 0 : i32} : (tensor<1x1x1xi32>) -> tensor<1x1x1xi32>
705  return %0 : tensor<1x1x1xi32>
706}
707
708// -----
709
710func.func @reduce_sum_constant() -> tensor<2x3x1x5xi32> {
711  // CHECK-LABEL:   func.func @reduce_sum_constant() -> tensor<2x3x1x5xi32> {
712  // CHECK:           %[[VAL_0:.*]] = "tosa.const"() <{value = dense<{{\[\[}}{{\[\[}}34, 38, 42, 46, 50]], {{\[\[}}114, 118, 122, 126, 130]], {{\[\[}}194, 198, 202, 206, 210]]], {{\[\[}}[274, 278, 282, 286, 290]], {{\[\[}}354, 358, 362, 366, 370]], {{\[\[}}434, 438, 442, 446, 450]]]]> : tensor<2x3x1x5xi32>}> : () -> tensor<2x3x1x5xi32>
713  // CHECK:           return %[[VAL_0]] : tensor<2x3x1x5xi32>
714  // CHECK:         }
715  %const = "tosa.const"() <{value = dense<[[[[1, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 12, 13, 14, 15], [16, 17, 18, 19, 20]], [[21, 22, 23, 24, 25], [26, 27, 28, 29, 30], [31, 32, 33, 34, 35], [36, 37, 38, 39, 40]], [[41, 42, 43, 44, 45], [46, 47, 48, 49, 50], [51, 52, 53, 54, 55], [56, 57, 58, 59, 60]]], [[[61, 62, 63, 64, 65], [66, 67, 68, 69, 70], [71, 72, 73, 74, 75], [76, 77, 78, 79, 80]], [[81, 82, 83, 84, 85], [86, 87, 88, 89, 90], [91, 92, 93, 94, 95], [96, 97, 98, 99, 100]], [[101, 102, 103, 104, 105], [106, 107, 108, 109, 110], [111, 112, 113, 114, 115], [116, 117, 118, 119, 120]]]]> : tensor<2x3x4x5xi32>}> : () -> tensor<2x3x4x5xi32>
716  %0 = tosa.reduce_sum %const {axis = 2 : i32} : (tensor<2x3x4x5xi32>) -> tensor<2x3x1x5xi32>
717  return %0 : tensor<2x3x1x5xi32>
718}
719
720// -----
721
722  func.func @reduce_prod_constant() -> tensor<1x3xi32> {
723    // CHECK-LABEL:   func.func @reduce_prod_constant() -> tensor<1x3xi32> {
724    // CHECK:    %[[VAL_0:.*]] = "tosa.const"() <{value = dense<{{\[\[}}4, 10, 18]]> : tensor<1x3xi32>}> : () -> tensor<1x3xi32>
725    // CHECK:         return %[[VAL_0]] : tensor<1x3xi32>
726
727    %const = "tosa.const"() <{value = dense<[[1,2,3], [4,5,6]]> : tensor<2x3xi32>}> : () -> tensor<2x3xi32>
728    %0 = tosa.reduce_prod %const {axis = 0 : i32} : (tensor<2x3xi32>) -> tensor<1x3xi32>
729    return %0 : tensor<1x3xi32>
730  }
731
732// -----
733
734  func.func @reduce_prod_constant() -> tensor<2x1xi32> {
735  // CHECK-LABEL:   func.func @reduce_prod_constant() -> tensor<2x1xi32> {
736  // CHECK:           %[[VAL_0:.*]] = "tosa.const"() <{value = dense<{{\[\[}}6], [120]]> : tensor<2x1xi32>}> : () -> tensor<2x1xi32>
737  // CHECK:           return %[[VAL_0]] : tensor<2x1xi32>
738  // CHECK:         }
739
740    %const = "tosa.const"() <{value = dense<[[1,2,3], [4,5,6]]> : tensor<2x3xi32>}> : () -> tensor<2x3xi32>
741    %0 = tosa.reduce_prod %const {axis = 1 : i32} : (tensor<2x3xi32>) -> tensor<2x1xi32>
742    return %0 : tensor<2x1xi32>
743  }
744
745// -----
746
747func.func @reduce_prod_constant() -> tensor<3x1xi32> {
748  // CHECK-LABEL:   func.func @reduce_prod_constant() -> tensor<3x1xi32> {
749  // CHECK:           %[[VAL_0:.*]] = "tosa.const"() <{value = dense<{{\[\[}}6], [120], [504]]> : tensor<3x1xi32>}> : () -> tensor<3x1xi32>
750  // CHECK:           return %[[VAL_0]] : tensor<3x1xi32>
751  // CHECK:         }
752  %const = "tosa.const"() <{value = dense<[[1, 2, 3], [4, 5, 6], [7, 8, 9]]> : tensor<3x3xi32>}> : () -> tensor<3x3xi32>
753  %0 = tosa.reduce_prod %const {axis = 1 : i32} : (tensor<3x3xi32>) -> tensor<3x1xi32>
754  return %0 : tensor<3x1xi32>
755}
756
757// -----
758
759func.func @reduce_prod_constant() -> tensor<2x1x4xi32> {
760  // CHECK-LABEL:   func.func @reduce_prod_constant() -> tensor<2x1x4xi32> {
761  // CHECK:           %[[VAL_0:.*]] = "tosa.const"() <{value = dense<{{\[\[}}[45, 120, 231, 384]], {{\[\[}}4641, 5544, 6555, 7680]]]> : tensor<2x1x4xi32>}> : () -> tensor<2x1x4xi32>
762  // CHECK:           return %[[VAL_0]] : tensor<2x1x4xi32>
763  // CHECK:         }
764  %const = "tosa.const"() <{value = dense<[[[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]], [[13, 14, 15, 16], [17, 18, 19, 20], [21, 22, 23, 24]]]> : tensor<2x3x4xi32>}> : () -> tensor<2x3x4xi32>
765  %0 = tosa.reduce_prod %const {axis = 1 : i32} : (tensor<2x3x4xi32>) -> tensor<2x1x4xi32>
766  return %0 : tensor<2x1x4xi32>
767}
768
769// -----
770
771func.func @reduce_prod_constant() -> tensor<1x3x3xi32> {
772  // CHECK-LABEL:   func.func @reduce_prod_constant() -> tensor<1x3x3xi32> {
773  // CHECK:           %[[VAL_0:.*]] = "tosa.const"() <{value = dense<{{\[\[}}[190, 440, 756], [1144, 1610, 2160], [2800, 3536, 4374]]]> : tensor<1x3x3xi32>}> : () -> tensor<1x3x3xi32>
774  // CHECK:           return %[[VAL_0]] : tensor<1x3x3xi32>
775  // CHECK:         }
776  %const = "tosa.const"() <{value = dense<[[[1, 2, 3], [4, 5, 6], [7, 8, 9]], [[10, 11, 12], [13, 14, 15], [16, 17, 18]], [[19, 20, 21], [22, 23, 24], [25, 26, 27]]]> : tensor<3x3x3xi32>}> : () -> tensor<3x3x3xi32>
777  %0 = tosa.reduce_prod %const {axis = 0 : i32} : (tensor<3x3x3xi32>) -> tensor<1x3x3xi32>
778  return %0 : tensor<1x3x3xi32>
779}
780
781// -----
782
783func.func @reduce_prod_constant() -> tensor<2x2x2x1xi32> {
784  // CHECK-LABEL:   func.func @reduce_prod_constant() -> tensor<2x2x2x1xi32> {
785  // CHECK:           %[[VAL_0:.*]] = "tosa.const"() <{value = dense<{{\[\[}}{{\[\[}}2], [12]], {{\[\[}}30], [56]]], {{\[\[}}[90], [132]], {{\[\[}}182], [240]]]]> : tensor<2x2x2x1xi32>}> : () -> tensor<2x2x2x1xi32>
786  // CHECK:           return %[[VAL_0]] : tensor<2x2x2x1xi32>
787  // CHECK:         }
788  %const = "tosa.const"() <{value = dense<[[[[1, 2], [3, 4]], [[5, 6], [7, 8]]], [[[9, 10], [11, 12]], [[13, 14], [15, 16]]]]> : tensor<2x2x2x2xi32>}> : () -> tensor<2x2x2x2xi32>
789  %0 = tosa.reduce_prod %const {axis = 3 : i32} : (tensor<2x2x2x2xi32>) -> tensor<2x2x2x1xi32>
790  return %0 : tensor<2x2x2x1xi32>
791}
792
793// -----
794
795func.func @reduce_prod_constant() -> tensor<1x1x1xi32> {
796  // CHECK-LABEL:   func.func @reduce_prod_constant() -> tensor<1x1x1xi32> {
797  // CHECK:           %[[VAL_0:.*]] = "tosa.const"() <{value = dense<42> : tensor<1x1x1xi32>}> : () -> tensor<1x1x1xi32>
798  // CHECK:           return %[[VAL_0]] : tensor<1x1x1xi32>
799  // CHECK:         }
800  %const = "tosa.const"() <{value = dense<[[[42]]]> : tensor<1x1x1xi32>}> : () -> tensor<1x1x1xi32>
801  %0 = tosa.reduce_prod %const {axis = 0 : i32} : (tensor<1x1x1xi32>) -> tensor<1x1x1xi32>
802  return %0 : tensor<1x1x1xi32>
803}
804
805// -----
806
807  func.func @reduce_max_constant() -> tensor<1x3xi32> {
808    // CHECK-LABEL:   func.func @reduce_max_constant() -> tensor<1x3xi32> {
809    // CHECK:    %[[VAL_0:.*]] = "tosa.const"() <{value = dense<{{\[\[}}4, 5, 6]]> : tensor<1x3xi32>}> : () -> tensor<1x3xi32>
810    // CHECK:         return %[[VAL_0]] : tensor<1x3xi32>
811
812    %const = "tosa.const"() <{value = dense<[[1,2,3], [4,5,6]]> : tensor<2x3xi32>}> : () -> tensor<2x3xi32>
813    %0 = tosa.reduce_max %const {axis = 0 : i32} : (tensor<2x3xi32>) -> tensor<1x3xi32>
814    return %0 : tensor<1x3xi32>
815  }
816
817// -----
818
819  func.func @reduce_max_constant() -> tensor<2x1xi32> {
820  // CHECK-LABEL:   func.func @reduce_max_constant() -> tensor<2x1xi32> {
821  // CHECK:           %[[VAL_0:.*]] = "tosa.const"() <{value = dense<{{\[\[}}3], [6]]> : tensor<2x1xi32>}> : () -> tensor<2x1xi32>
822  // CHECK:           return %[[VAL_0]] : tensor<2x1xi32>
823  // CHECK:         }
824
825    %const = "tosa.const"() <{value = dense<[[1,2,3], [4,5,6]]> : tensor<2x3xi32>}> : () -> tensor<2x3xi32>
826    %0 = tosa.reduce_max %const {axis = 1 : i32} : (tensor<2x3xi32>) -> tensor<2x1xi32>
827    return %0 : tensor<2x1xi32>
828  }
829
830// -----
831
832func.func @reduce_max_constant() -> tensor<3x1xi32> {
833  // CHECK-LABEL:   func.func @reduce_max_constant() -> tensor<3x1xi32> {
834  // CHECK:           %[[VAL_0:.*]] = "tosa.const"() <{value = dense<{{\[\[}}3], [6], [9]]> : tensor<3x1xi32>}> : () -> tensor<3x1xi32>
835  // CHECK:           return %[[VAL_0]] : tensor<3x1xi32>
836  // CHECK:         }
837  %const = "tosa.const"() <{value = dense<[[1, 2, 3], [4, 5, 6], [7, 8, 9]]> : tensor<3x3xi32>}> : () -> tensor<3x3xi32>
838  %0 = tosa.reduce_max %const {axis = 1 : i32} : (tensor<3x3xi32>) -> tensor<3x1xi32>
839  return %0 : tensor<3x1xi32>
840}
841
842// -----
843
844func.func @reduce_max_constant() -> tensor<2x1x4xi32> {
845  // CHECK-LABEL:   func.func @reduce_max_constant() -> tensor<2x1x4xi32> {
846  // CHECK:           %[[VAL_0:.*]] = "tosa.const"() <{value = dense<{{\[\[}}[9, 10, 11, 12]], {{\[\[}}21, 22, 23, 24]]]> : tensor<2x1x4xi32>}> : () -> tensor<2x1x4xi32>
847  // CHECK:           return %[[VAL_0]] : tensor<2x1x4xi32>
848  // CHECK:         }
849  %const = "tosa.const"() <{value = dense<[[[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]], [[13, 14, 15, 16], [17, 18, 19, 20], [21, 22, 23, 24]]]> : tensor<2x3x4xi32>}> : () -> tensor<2x3x4xi32>
850  %0 = tosa.reduce_max %const {axis = 1 : i32} : (tensor<2x3x4xi32>) -> tensor<2x1x4xi32>
851  return %0 : tensor<2x1x4xi32>
852}
853
854// -----
855
856func.func @reduce_max_constant() -> tensor<1x3x3xi32> {
857  // CHECK-LABEL:   func.func @reduce_max_constant() -> tensor<1x3x3xi32> {
858  // CHECK:           %[[VAL_0:.*]] = "tosa.const"() <{value = dense<{{\[\[}}[19, 20, 21], [22, 23, 24], [25, 26, 27]]]> : tensor<1x3x3xi32>}> : () -> tensor<1x3x3xi32>
859  // CHECK:           return %[[VAL_0]] : tensor<1x3x3xi32>
860  // CHECK:         }
861  %const = "tosa.const"() <{value = dense<[[[1, 2, 3], [4, 5, 6], [7, 8, 9]], [[10, 11, 12], [13, 14, 15], [16, 17, 18]], [[19, 20, 21], [22, 23, 24], [25, 26, 27]]]> : tensor<3x3x3xi32>}> : () -> tensor<3x3x3xi32>
862  %0 = tosa.reduce_max %const {axis = 0 : i32} : (tensor<3x3x3xi32>) -> tensor<1x3x3xi32>
863  return %0 : tensor<1x3x3xi32>
864}
865
866// -----
867
868func.func @reduce_max_constant() -> tensor<2x2x2x1xi32> {
869  // CHECK-LABEL:   func.func @reduce_max_constant() -> tensor<2x2x2x1xi32> {
870  // CHECK:           %[[VAL_0:.*]] = "tosa.const"() <{value = dense<{{\[\[}}{{\[\[}}2], [4]], {{\[\[}}6], [8]]], {{\[\[}}[10], [12]], {{\[\[}}14], [16]]]]> : tensor<2x2x2x1xi32>}> : () -> tensor<2x2x2x1xi32>
871  // CHECK:           return %[[VAL_0]] : tensor<2x2x2x1xi32>
872  // CHECK:         }
873  %const = "tosa.const"() <{value = dense<[[[[1, 2], [3, 4]], [[5, 6], [7, 8]]], [[[9, 10], [11, 12]], [[13, 14], [15, 16]]]]> : tensor<2x2x2x2xi32>}> : () -> tensor<2x2x2x2xi32>
874  %0 = tosa.reduce_max %const {axis = 3 : i32} : (tensor<2x2x2x2xi32>) -> tensor<2x2x2x1xi32>
875  return %0 : tensor<2x2x2x1xi32>
876}
877
878// -----
879
880func.func @reduce_max_constant() -> tensor<1x1x1xi32> {
881  // CHECK-LABEL:   func.func @reduce_max_constant() -> tensor<1x1x1xi32> {
882  // CHECK:           %[[VAL_0:.*]] = "tosa.const"() <{value = dense<42> : tensor<1x1x1xi32>}> : () -> tensor<1x1x1xi32>
883  // CHECK:           return %[[VAL_0]] : tensor<1x1x1xi32>
884  // CHECK:         }
885  %const = "tosa.const"() <{value = dense<[[[42]]]> : tensor<1x1x1xi32>}> : () -> tensor<1x1x1xi32>
886  %0 = tosa.reduce_max %const {axis = 0 : i32} : (tensor<1x1x1xi32>) -> tensor<1x1x1xi32>
887  return %0 : tensor<1x1x1xi32>
888}
889
890// -----
891
892  func.func @reduce_min_constant() -> tensor<1x3xi32> {
893    // CHECK-LABEL:   func.func @reduce_min_constant() -> tensor<1x3xi32> {
894    // CHECK:    %[[VAL_0:.*]] = "tosa.const"() <{value = dense<{{\[\[}}1, 2, 3]]> : tensor<1x3xi32>}> : () -> tensor<1x3xi32>
895    // CHECK:         return %[[VAL_0]] : tensor<1x3xi32>
896    %const = "tosa.const"() <{value = dense<[[1,2,3], [4,5,6]]> : tensor<2x3xi32>}> : () -> tensor<2x3xi32>
897    %0 = tosa.reduce_min %const {axis = 0 : i32} : (tensor<2x3xi32>) -> tensor<1x3xi32>
898    return %0 : tensor<1x3xi32>
899  }
900
901
902// -----
903
904  func.func @reduce_min_constant() -> tensor<2x1xi32> {
905  // CHECK-LABEL:   func.func @reduce_min_constant() -> tensor<2x1xi32> {
906  // CHECK:           %[[VAL_0:.*]] = "tosa.const"() <{value = dense<{{\[\[}}1], [4]]> : tensor<2x1xi32>}> : () -> tensor<2x1xi32>
907  // CHECK:           return %[[VAL_0]] : tensor<2x1xi32>
908  // CHECK:         }
909
910    %const = "tosa.const"() <{value = dense<[[1,2,3], [4,5,6]]> : tensor<2x3xi32>}> : () -> tensor<2x3xi32>
911    %0 = tosa.reduce_min %const {axis = 1 : i32} : (tensor<2x3xi32>) -> tensor<2x1xi32>
912    return %0 : tensor<2x1xi32>
913  }
914
915// -----
916
917func.func @reduce_min_constant() -> tensor<3x1xi32> {
918  // CHECK-LABEL:   func.func @reduce_min_constant() -> tensor<3x1xi32> {
919  // CHECK:           %[[VAL_0:.*]] = "tosa.const"() <{value = dense<{{\[\[}}1], [4], [7]]> : tensor<3x1xi32>}> : () -> tensor<3x1xi32>
920  // CHECK:           return %[[VAL_0]] : tensor<3x1xi32>
921  // CHECK:         }
922  %const = "tosa.const"() <{value = dense<[[1, 2, 3], [4, 5, 6], [7, 8, 9]]> : tensor<3x3xi32>}> : () -> tensor<3x3xi32>
923  %0 = tosa.reduce_min %const {axis = 1 : i32} : (tensor<3x3xi32>) -> tensor<3x1xi32>
924  return %0 : tensor<3x1xi32>
925}
926
927// -----
928
929func.func @reduce_min_constant() -> tensor<2x1x4xi32> {
930  // CHECK-LABEL:   func.func @reduce_min_constant() -> tensor<2x1x4xi32> {
931  // CHECK:           %[[VAL_0:.*]] = "tosa.const"() <{value = dense<{{\[\[}}[1, 2, 3, 4]], {{\[\[}}13, 14, 15, 16]]]> : tensor<2x1x4xi32>}> : () -> tensor<2x1x4xi32>
932  // CHECK:           return %[[VAL_0]] : tensor<2x1x4xi32>
933  // CHECK:         }
934  %const = "tosa.const"() <{value = dense<[[[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]], [[13, 14, 15, 16], [17, 18, 19, 20], [21, 22, 23, 24]]]> : tensor<2x3x4xi32>}> : () -> tensor<2x3x4xi32>
935  %0 = tosa.reduce_min %const {axis = 1 : i32} : (tensor<2x3x4xi32>) -> tensor<2x1x4xi32>
936  return %0 : tensor<2x1x4xi32>
937}
938
939// -----
940
941func.func @reduce_min_constant() -> tensor<1x3x3xi32> {
942  // CHECK-LABEL:   func.func @reduce_min_constant() -> tensor<1x3x3xi32> {
943  // CHECK:           %[[VAL_0:.*]] = "tosa.const"() <{value = dense<{{\[\[}}[1, 2, 3], [4, 5, 6], [7, 8, 9]]]> : tensor<1x3x3xi32>}> : () -> tensor<1x3x3xi32>
944  // CHECK:           return %[[VAL_0]] : tensor<1x3x3xi32>
945  // CHECK:         }
946  %const = "tosa.const"() <{value = dense<[[[1, 2, 3], [4, 5, 6], [7, 8, 9]], [[10, 11, 12], [13, 14, 15], [16, 17, 18]], [[19, 20, 21], [22, 23, 24], [25, 26, 27]]]> : tensor<3x3x3xi32>}> : () -> tensor<3x3x3xi32>
947  %0 = tosa.reduce_min %const {axis = 0 : i32} : (tensor<3x3x3xi32>) -> tensor<1x3x3xi32>
948  return %0 : tensor<1x3x3xi32>
949}
950
951// -----
952
953func.func @reduce_min_constant() -> tensor<2x2x2x1xi32> {
954  // CHECK-LABEL:   func.func @reduce_min_constant() -> tensor<2x2x2x1xi32> {
955  // CHECK:           %[[VAL_0:.*]] = "tosa.const"() <{value = dense<{{\[\[}}{{\[\[}}1], [3]], {{\[\[}}5], [7]]], {{\[\[}}[9], [11]], {{\[\[}}13], [15]]]]> : tensor<2x2x2x1xi32>}> : () -> tensor<2x2x2x1xi32>
956  // CHECK:           return %[[VAL_0]] : tensor<2x2x2x1xi32>
957  // CHECK:         }
958  %const = "tosa.const"() <{value = dense<[[[[1, 2], [3, 4]], [[5, 6], [7, 8]]], [[[9, 10], [11, 12]], [[13, 14], [15, 16]]]]> : tensor<2x2x2x2xi32>}> : () -> tensor<2x2x2x2xi32>
959  %0 = tosa.reduce_min %const {axis = 3 : i32} : (tensor<2x2x2x2xi32>) -> tensor<2x2x2x1xi32>
960  return %0 : tensor<2x2x2x1xi32>
961}
962
963// -----
964
965func.func @reduce_min_constant() -> tensor<1x1x1xi32> {
966  // CHECK-LABEL:   func.func @reduce_min_constant() -> tensor<1x1x1xi32> {
967  // CHECK:           %[[VAL_0:.*]] = "tosa.const"() <{value = dense<42> : tensor<1x1x1xi32>}> : () -> tensor<1x1x1xi32>
968  // CHECK:           return %[[VAL_0]] : tensor<1x1x1xi32>
969  // CHECK:         }
970  %const = "tosa.const"() <{value = dense<[[[42]]]> : tensor<1x1x1xi32>}> : () -> tensor<1x1x1xi32>
971  %0 = tosa.reduce_min %const {axis = 0 : i32} : (tensor<1x1x1xi32>) -> tensor<1x1x1xi32>
972  return %0 : tensor<1x1x1xi32>
973}
974
975// -----
976
977func.func @reduce_any_constant() -> tensor<1x3xi1> {
978  // CHECK-LABEL:   func.func @reduce_any_constant() -> tensor<1x3xi1> {
979  // CHECK:    %[[VAL_0:.*]] = "tosa.const"() <{value = dense<true> : tensor<1x3xi1>}> : () -> tensor<1x3xi1>
980  // CHECK:         return %[[VAL_0]] : tensor<1x3xi1>
981
982  %const = "tosa.const"() <{value = dense<[[true,true,true], [true,false,true]]> : tensor<2x3xi1>}> : () -> tensor<2x3xi1>
983  %0 = tosa.reduce_any %const {axis = 0 : i32} : (tensor<2x3xi1>) -> tensor<1x3xi1>
984  return %0 : tensor<1x3xi1>
985}
986
987
988// -----
989
990func.func @reduce_any_constant() -> tensor<2x1xi1> {
991// CHECK-LABEL:   func.func @reduce_any_constant() -> tensor<2x1xi1> {
992// CHECK:           %[[VAL_0:.*]] = "tosa.const"() <{value = dense<true> : tensor<2x1xi1>}> : () -> tensor<2x1xi1>
993// CHECK:           return %[[VAL_0]] : tensor<2x1xi1>
994// CHECK:         }
995
996  %const = "tosa.const"() <{value = dense<[[true,true,true], [true,false,true]]> : tensor<2x3xi1>}> : () -> tensor<2x3xi1>
997  %0 = tosa.reduce_any %const {axis = 1 : i32} : (tensor<2x3xi1>) -> tensor<2x1xi1>
998  return %0 : tensor<2x1xi1>
999}
1000
1001// -----
1002
1003func.func @reduce_any_constant() -> tensor<3x1xi1> {
1004  // CHECK-LABEL:   func.func @reduce_any_constant() -> tensor<3x1xi1> {
1005  // CHECK:           %[[VAL_0:.*]] = "tosa.const"() <{value = dense<{{\[\[}}true], [false], [true]]> : tensor<3x1xi1>}> : () -> tensor<3x1xi1>
1006  // CHECK:           return %[[VAL_0]] : tensor<3x1xi1>
1007  // CHECK:         }
1008  %const = "tosa.const"() <{value = dense<[[true, false, false], [false, false, false], [false, false, true]]> : tensor<3x3xi1>}> : () -> tensor<3x3xi1>
1009  %0 = tosa.reduce_any %const {axis = 1 : i32} : (tensor<3x3xi1>) -> tensor<3x1xi1>
1010  return %0 : tensor<3x1xi1>
1011}
1012
1013// -----
1014
1015func.func @reduce_any_constant() -> tensor<2x1x4xi1> {
1016  // CHECK-LABEL:   func.func @reduce_any_constant() -> tensor<2x1x4xi1> {
1017  // CHECK:           %[[VAL_0:.*]] = "tosa.const"() <{value = dense<{{\[\[}}[true, false, true, true]], {{\[\[}}true, false, true, false]]]> : tensor<2x1x4xi1>}> : () -> tensor<2x1x4xi1>
1018  // CHECK:           return %[[VAL_0]] : tensor<2x1x4xi1>
1019  // CHECK:         }
1020  %const = "tosa.const"() <{value = dense<[[[true, false, false, true], [false, false, true, false], [true, false, true, true]], [[false, false, false, false], [false, false, true, false], [true, false, true, false]]]> : tensor<2x3x4xi1>}> : () -> tensor<2x3x4xi1>
1021  %0 = tosa.reduce_any %const {axis = 1 : i32} : (tensor<2x3x4xi1>) -> tensor<2x1x4xi1>
1022  return %0 : tensor<2x1x4xi1>
1023}
1024
1025// -----
1026
1027  func.func @reduce_all_constant() -> tensor<1x3xi1> {
1028  // CHECK-LABEL:   func.func @reduce_all_constant() -> tensor<1x3xi1> {
1029  // CHECK:           %[[VAL_0:.*]] = "tosa.const"() <{value = dense<{{\[\[}}true, false, true]]> : tensor<1x3xi1>}> : () -> tensor<1x3xi1>
1030  // CHECK:           return %[[VAL_0]] : tensor<1x3xi1>
1031  // CHECK:         }
1032    %const = "tosa.const"() <{value = dense<[[true,true,true], [true,false,true]]> : tensor<2x3xi1>}> : () -> tensor<2x3xi1>
1033    %0 = tosa.reduce_all %const {axis = 0 : i32} : (tensor<2x3xi1>) -> tensor<1x3xi1>
1034    return %0 : tensor<1x3xi1>
1035  }
1036
1037// -----
1038
1039  func.func @reduce_all_constant() -> tensor<2x1xi1> {
1040  // CHECK-LABEL:   func.func @reduce_all_constant() -> tensor<2x1xi1> {
1041  // CHECK:           %[[VAL_0:.*]] = "tosa.const"() <{value = dense<{{\[\[}}true], [false]]> : tensor<2x1xi1>}> : () -> tensor<2x1xi1>
1042  // CHECK:           return %[[VAL_0]] : tensor<2x1xi1>
1043  // CHECK:         }
1044    %const = "tosa.const"() <{value = dense<[[true,true,true], [true,false,true]]> : tensor<2x3xi1>}> : () -> tensor<2x3xi1>
1045    %0 = tosa.reduce_all %const {axis = 1 : i32} : (tensor<2x3xi1>) -> tensor<2x1xi1>
1046    return %0 : tensor<2x1xi1>
1047  }
1048
1049// -----
1050
1051func.func @reduce_all_constant() -> tensor<3x1xi1> {
1052  // CHECK-LABEL:   func.func @reduce_all_constant() -> tensor<3x1xi1> {
1053  // CHECK:           %[[VAL_0:.*]] = "tosa.const"() <{value = dense<false> : tensor<3x1xi1>}> : () -> tensor<3x1xi1>
1054  // CHECK:           return %[[VAL_0]] : tensor<3x1xi1>
1055  // CHECK:         }
1056  %const = "tosa.const"() <{value = dense<[[true, false, false], [false, false, false], [false, false, true]]> : tensor<3x3xi1>}> : () -> tensor<3x3xi1>
1057  %0 = tosa.reduce_all %const {axis = 1 : i32} : (tensor<3x3xi1>) -> tensor<3x1xi1>
1058  return %0 : tensor<3x1xi1>
1059}
1060
1061// -----
1062
1063func.func @reduce_all_constant() -> tensor<2x1x4xi1> {
1064  // CHECK-LABEL:   func.func @reduce_all_constant() -> tensor<2x1x4xi1> {
1065  // CHECK:           %[[VAL_0:.*]] = "tosa.const"() <{value = dense<false> : tensor<2x1x4xi1>}> : () -> tensor<2x1x4xi1>
1066  // CHECK:           return %[[VAL_0]] : tensor<2x1x4xi1>
1067  // CHECK:         }
1068  %const = "tosa.const"() <{value = dense<[[[true, false, false, true], [false, false, true, false], [true, false, true, true]], [[false, false, false, false], [false, false, true, false], [true, false, true, false]]]> : tensor<2x3x4xi1>}> : () -> tensor<2x3x4xi1>
1069  %0 = tosa.reduce_all %const {axis = 1 : i32} : (tensor<2x3x4xi1>) -> tensor<2x1x4xi1>
1070  return %0 : tensor<2x1x4xi1>
1071}
1072
1073// -----
1074
1075func.func @reduce_sum_constant() -> tensor<1x3xi32> {
1076// CHECK-LABEL:   func.func @reduce_sum_constant() -> tensor<1x3xi32> {
1077// CHECK:           %[[VAL_0:.*]] = "tosa.const"() <{value = dense<2> : tensor<1x3xi32>}> : () -> tensor<1x3xi32>
1078// CHECK:           return %[[VAL_0]] : tensor<1x3xi32>
1079// CHECK:         }
1080  %const = "tosa.const"() <{value = dense<1> : tensor<2x3xi32>}> : () -> tensor<2x3xi32>
1081  %0 = tosa.reduce_sum %const {axis = 0 : i32} : (tensor<2x3xi32>) -> tensor<1x3xi32>
1082  return %0 : tensor<1x3xi32>
1083}
1084
1085// -----
1086
1087func.func @reduce_sum_constant() -> tensor<1x3xi32> {
1088  // CHECK-LABEL:     func.func @reduce_sum_constant() -> tensor<1x3xi32> {
1089  // CHECK:           %[[VAL_0:.*]] = "tosa.const"() <{value = dense<{{\[\[}}1, 2, 3], [4, 5, 6]]> : tensor<2x3xi32>}> : () -> tensor<2x3xi32>
1090  // CHECK:           %[[VAL_1:.*]] = "tosa.const"() <{value = dense<{{\[\[}}1, 2, 3], [4, 5, 7]]> : tensor<2x3xi32>}> : () -> tensor<2x3xi32>
1091  // CHECK:           %[[VAL_2:.*]] = tosa.add %[[VAL_0]], %[[VAL_1]] : (tensor<2x3xi32>, tensor<2x3xi32>) -> tensor<2x3xi32>
1092  // CHECK:           %[[VAL_3:.*]] = tosa.reduce_sum %[[VAL_2]] {axis = 0 : i32} : (tensor<2x3xi32>) -> tensor<1x3xi32>
1093  // CHECK:           return %[[VAL_3]] : tensor<1x3xi32>
1094  %arg0 = "tosa.const"() <{value = dense<[[1,2,3], [4,5,6]]> : tensor<2x3xi32>}> : () -> tensor<2x3xi32>
1095  %arg1 = "tosa.const"() <{value = dense<[[1,2,3], [4,5,7]]> : tensor<2x3xi32>}> : () -> tensor<2x3xi32>
1096  %arg2 = tosa.add %arg0, %arg1 : (tensor<2x3xi32>, tensor<2x3xi32>) -> tensor<2x3xi32>
1097  %0 = tosa.reduce_sum %arg2 {axis = 0 : i32} : (tensor<2x3xi32>) -> tensor<1x3xi32>
1098  return %0 : tensor<1x3xi32>
1099}
1100
1101// -----
1102
1103func.func @reduce_sum_constant_aggressive() -> tensor<1x3xi32> {
1104  // AGGRESIVE-LABEL: func.func @reduce_sum_constant_aggressive() -> tensor<1x3xi32> {
1105  // AGGRESIVE:       %[[VAL_0:.*]] = "tosa.const"() <{value = dense<4> : tensor<1x3xi32>}> : () -> tensor<1x3xi32>
1106  // AGGRESIVE:       return %[[VAL_0:.*]] : tensor<1x3xi32>
1107
1108  // CHECK-LABEL:     func.func @reduce_sum_constant_aggressive() -> tensor<1x3xi32> {
1109  // CHECK:           %[[VAL_0:.*]] = "tosa.const"() <{value = dense<1> : tensor<2x3xi32>}> : () -> tensor<2x3xi32>
1110  // CHECK:           %[[VAL_1:.*]] = tosa.reduce_sum %[[VAL_0]] {axis = 0 : i32} : (tensor<2x3xi32>) -> tensor<1x3xi32>
1111  // CHECK:           %[[VAL_2:.*]] = tosa.reduce_sum %[[VAL_0]] {axis = 0 : i32} : (tensor<2x3xi32>) -> tensor<1x3xi32>
1112  // CHECK:           %[[VAL_3:.*]] = tosa.add %[[VAL_1]], %[[VAL_2]] : (tensor<1x3xi32>, tensor<1x3xi32>) -> tensor<1x3xi32>
1113  // CHECK:           return %[[VAL_3]] : tensor<1x3xi32>
1114
1115  %const = "tosa.const"() {value = dense<1> : tensor<2x3xi32>} : () -> tensor<2x3xi32>
1116  %0 = tosa.reduce_sum %const {axis = 0 : i32} : (tensor<2x3xi32>) -> tensor<1x3xi32>
1117  %1 = tosa.reduce_sum %const {axis = 0 : i32} : (tensor<2x3xi32>) -> tensor<1x3xi32>
1118  %res = tosa.add %0, %1 : (tensor<1x3xi32>, tensor<1x3xi32>) -> tensor<1x3xi32>
1119  return %res : tensor<1x3xi32>
1120}
1121
1122// -----
1123
1124func.func @reduce_sum_constant_aggressive() -> tensor<2x3xi32> {
1125  // AGGRESIVE-LABEL:     func.func @reduce_sum_constant_aggressive() -> tensor<2x3xi32> {
1126  // AGGRESIVE-DAG:       %[[VAL_0:.*]] = "tosa.const"() <{value = dense<2> : tensor<1x2x3xi32>}> : () -> tensor<1x2x3xi32>
1127  // AGGRESIVE-DAG:       %[[VAL_1:.*]] = "tosa.const"() <{value = dense<1> : tensor<2x2x3xi32>}> : () -> tensor<2x2x3xi32>
1128  // AGGRESIVE-DAG:       %[[VAL_2:.*]] = "tosa.const"() <{value = dense<2> : tensor<2x3xi32>}> : () -> tensor<2x3xi32>
1129  // AGGRESIVE:           %[[VAL_3:.*]] = tosa.argmax %[[VAL_0]] {axis = 1 : i32} : (tensor<1x2x3xi32>) -> tensor<1x3xi32>
1130  // AGGRESIVE:           %[[VAL_4:.*]] = tosa.argmax %[[VAL_1]] {axis = 0 : i32} : (tensor<2x2x3xi32>) -> tensor<2x3xi32>
1131  // AGGRESIVE:           %[[VAL_5:.*]] = tosa.add %[[VAL_3]], %[[VAL_2]] : (tensor<1x3xi32>, tensor<2x3xi32>) -> tensor<2x3xi32>
1132  // AGGRESIVE:           %[[VAL_6:.*]] = tosa.add %[[VAL_5]], %[[VAL_4]] : (tensor<2x3xi32>, tensor<2x3xi32>) -> tensor<2x3xi32>
1133  // AGGRESIVE:           return %[[VAL_6]] : tensor<2x3xi32>
1134
1135  // CHECK-LABEL:     func.func @reduce_sum_constant_aggressive() -> tensor<2x3xi32> {
1136  // CHECK:           %[[VAL_0:.*]] = "tosa.const"() <{value = dense<1> : tensor<2x2x3xi32>}> : () -> tensor<2x2x3xi32>
1137  // CHECK:           %[[VAL_1:.*]] = "tosa.const"() <{value = dense<2> : tensor<2x3xi32>}> : () -> tensor<2x3xi32>
1138  // CHECK:           %[[VAL_2:.*]] = tosa.reduce_sum %[[VAL_0]] {axis = 0 : i32} : (tensor<2x2x3xi32>) -> tensor<1x2x3xi32>
1139  // CHECK:           %[[VAL_3:.*]] = tosa.argmax %[[VAL_2]] {axis = 1 : i32} : (tensor<1x2x3xi32>) -> tensor<1x3xi32>
1140  // CHECK:           %[[VAL_4:.*]] = tosa.argmax %[[VAL_0]] {axis = 0 : i32} : (tensor<2x2x3xi32>) -> tensor<2x3xi32>
1141  // CHECK:           %[[VAL_5:.*]] = tosa.add %[[VAL_3]], %[[VAL_1]] : (tensor<1x3xi32>, tensor<2x3xi32>) -> tensor<2x3xi32>
1142  // CHECK:           %[[VAL_6:.*]] = tosa.add %[[VAL_5]], %[[VAL_4]] : (tensor<2x3xi32>, tensor<2x3xi32>) -> tensor<2x3xi32>
1143  // CHECK:           return %[[VAL_6]] : tensor<2x3xi32>
1144
1145  %const0 = "tosa.const"() {value = dense<1> : tensor<2x2x3xi32>} : () -> tensor<2x2x3xi32>
1146  %const1 = "tosa.const"() {value = dense<2> : tensor<2x3xi32>} : () -> tensor<2x3xi32>
1147  %reduce0 = tosa.reduce_sum %const0 {axis = 0 : i32} : (tensor<2x2x3xi32>) -> tensor<1x2x3xi32>
1148  %argmax0 = tosa.argmax %reduce0 {axis = 1 : i32} : (tensor<1x2x3xi32>) -> tensor<1x3xi32>
1149  %argmax1 = tosa.argmax %const0 {axis = 0 : i32} : (tensor<2x2x3xi32>) -> tensor<2x3xi32>
1150  %res0 = tosa.add %argmax0, %const1 : (tensor<1x3xi32>, tensor<2x3xi32>) -> tensor<2x3xi32>
1151  %res1 = tosa.add %res0, %argmax1 : (tensor<2x3xi32>, tensor<2x3xi32>) -> tensor<2x3xi32>
1152  return %res1 : tensor<2x3xi32>
1153}
1154