• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// RUN: tf-opt %s -test-constant-fold | FileCheck %s --dump-input-on-failure
2
3// CHECK-LABEL: @add_float
4func @add_float() -> (tensor<f32>, tensor<4xf32>, tensor<4xf32>, tensor<4xf32>, tensor<4xf32>) {
5  %0 = constant dense<4.5> : tensor<f32>
6  %1 = constant dense<1.5> : tensor<f32>
7
8  %2 = constant dense< 3.5> : tensor<4xf32>
9  %3 = constant dense<-0.5> : tensor<4xf32>
10
11  // CHECK: %cst = constant dense<3.500000e+00> : tensor<4xf32>
12  // CHECK: %cst_0 = constant dense<-5.000000e-01> : tensor<4xf32>
13  // CHECK: %cst_1 = constant dense<6.000000e+00> : tensor<f32>
14  // CHECK: %cst_2 = constant dense<4.000000e+00> : tensor<4xf32>
15  // CHECK: %cst_3 = constant dense<5.000000e+00> : tensor<4xf32>
16  // CHECK: %cst_4 = constant dense<3.000000e+00> : tensor<4xf32>
17  // CHECK: %0 = tfl.add %cst, %cst_0 {fused_activation_function = "SIGN_BIT"} : tensor<4xf32>
18
19  %5 = "tfl.add"(%0, %1) {fused_activation_function = "NONE"} : (tensor<  f32>, tensor<  f32>) -> tensor<  f32>
20  %6 = "tfl.add"(%0, %3) {fused_activation_function = "NONE"} : (tensor<  f32>, tensor<4xf32>) -> tensor<4xf32>
21  %7 = "tfl.add"(%2, %1) {fused_activation_function = "NONE"} : (tensor<4xf32>, tensor<  f32>) -> tensor<4xf32>
22  %8 = "tfl.add"(%2, %3) {fused_activation_function = "NONE"} : (tensor<4xf32>, tensor<4xf32>) -> tensor<4xf32>
23  %9 = "tfl.add"(%2, %3) {fused_activation_function = "SIGN_BIT"} : (tensor<4xf32>, tensor<4xf32>) -> tensor<4xf32>
24
25  return %5, %6, %7, %8, %9 : tensor<f32>, tensor<4xf32>, tensor<4xf32>, tensor<4xf32>, tensor<4xf32>
26}
27
28// CHECK-LABEL: @add_int
29func @add_int() -> (tensor<i32>, tensor<4xi32>, tensor<4xi32>, tensor<4xi32>) {
30  %0 = constant dense<8> : tensor<i32>
31  %1 = constant dense<1> : tensor<i32>
32
33  %2 = constant dense< 4> : tensor<4xi32>
34  %3 = constant dense<-2> : tensor<4xi32>
35
36  // CHECK: %cst = constant dense<9> : tensor<i32>
37  // CHECK: %cst_0 = constant dense<6> : tensor<4xi32>
38  // CHECK: %cst_1 = constant dense<5> : tensor<4xi32>
39  // CHECK: %cst_2 = constant dense<2> : tensor<4xi32>
40
41  %5 = "tfl.add"(%0, %1) {fused_activation_function = "NONE"} : (tensor<  i32>, tensor<  i32>) -> tensor<  i32>
42  %6 = "tfl.add"(%0, %3) {fused_activation_function = "NONE"} : (tensor<  i32>, tensor<4xi32>) -> tensor<4xi32>
43  %7 = "tfl.add"(%2, %1) {fused_activation_function = "NONE"} : (tensor<4xi32>, tensor<  i32>) -> tensor<4xi32>
44  %8 = "tfl.add"(%2, %3) {fused_activation_function = "NONE"} : (tensor<4xi32>, tensor<4xi32>) -> tensor<4xi32>
45
46  return %5, %6, %7, %8 : tensor<i32>, tensor<4xi32>, tensor<4xi32>, tensor<4xi32>
47}
48
49// CHECK-LABEL: @sub_float
50func @sub_float() -> (tensor<f32>, tensor<4xf32>, tensor<4xf32>, tensor<4xf32>) {
51  %0 = constant dense<4.5> : tensor<f32>
52  %1 = constant dense<1.5> : tensor<f32>
53
54  %2 = constant dense< 3.5> : tensor<4xf32>
55  %3 = constant dense<-0.5> : tensor<4xf32>
56
57  // CHECK: %cst = constant dense<3.000000e+00> : tensor<f32>
58  // CHECK: %cst_0 = constant dense<5.000000e+00> : tensor<4xf32>
59  // CHECK: %cst_1 = constant dense<2.000000e+00> : tensor<4xf32>
60  // CHECK: %cst_2 = constant dense<4.000000e+00> : tensor<4xf32>
61
62  %5 = "tfl.sub"(%0, %1) {fused_activation_function = "NONE"} : (tensor<  f32>, tensor<  f32>) -> tensor<  f32>
63  %6 = "tfl.sub"(%0, %3) {fused_activation_function = "NONE"} : (tensor<  f32>, tensor<4xf32>) -> tensor<4xf32>
64  %7 = "tfl.sub"(%2, %1) {fused_activation_function = "NONE"} : (tensor<4xf32>, tensor<  f32>) -> tensor<4xf32>
65  %8 = "tfl.sub"(%2, %3) {fused_activation_function = "NONE"} : (tensor<4xf32>, tensor<4xf32>) -> tensor<4xf32>
66
67  return %5, %6, %7, %8 : tensor<f32>, tensor<4xf32>, tensor<4xf32>, tensor<4xf32>
68}
69
70// CHECK-LABEL: @sub_int
71func @sub_int() -> (tensor<i32>, tensor<4xi32>, tensor<4xi32>, tensor<4xi32>) {
72  %0 = constant dense<8> : tensor<i32>
73  %1 = constant dense<1> : tensor<i32>
74
75  %2 = constant dense< 4> : tensor<4xi32>
76  %3 = constant dense<-2> : tensor<4xi32>
77
78  // CHECK: %cst = constant dense<7> : tensor<i32>
79  // CHECK: %cst_0 = constant dense<10> : tensor<4xi32>
80  // CHECK: %cst_1 = constant dense<3> : tensor<4xi32>
81  // CHECK: %cst_2 = constant dense<6> : tensor<4xi32>
82
83  %5 = "tfl.sub"(%0, %1) {fused_activation_function = "NONE"} : (tensor<  i32>, tensor<  i32>) -> tensor<  i32>
84  %6 = "tfl.sub"(%0, %3) {fused_activation_function = "NONE"} : (tensor<  i32>, tensor<4xi32>) -> tensor<4xi32>
85  %7 = "tfl.sub"(%2, %1) {fused_activation_function = "NONE"} : (tensor<4xi32>, tensor<  i32>) -> tensor<4xi32>
86  %8 = "tfl.sub"(%2, %3) {fused_activation_function = "NONE"} : (tensor<4xi32>, tensor<4xi32>) -> tensor<4xi32>
87
88  return %5, %6, %7, %8 : tensor<i32>, tensor<4xi32>, tensor<4xi32>, tensor<4xi32>
89}
90
91// CHECK-LABEL: @mul_float
92func @mul_float() -> (tensor<f32>, tensor<4xf32>, tensor<4xf32>, tensor<4xf32>) {
93  %0 = constant dense<4.5> : tensor<f32>
94  %1 = constant dense<1.5> : tensor<f32>
95
96  %2 = constant dense< 3.5> : tensor<4xf32>
97  %3 = constant dense<-0.5> : tensor<4xf32>
98
99  // CHECK: %cst = constant dense<6.750000e+00> : tensor<f32>
100  // CHECK: %cst_0 = constant dense<-2.250000e+00> : tensor<4xf32>
101  // CHECK: %cst_1 = constant dense<5.250000e+00> : tensor<4xf32>
102  // CHECK: %cst_2 = constant dense<-1.750000e+00> : tensor<4xf32>
103
104  %5 = "tfl.mul"(%0, %1) {fused_activation_function = "NONE"} : (tensor<  f32>, tensor<  f32>) -> tensor<  f32>
105  %6 = "tfl.mul"(%0, %3) {fused_activation_function = "NONE"} : (tensor<  f32>, tensor<4xf32>) -> tensor<4xf32>
106  %7 = "tfl.mul"(%2, %1) {fused_activation_function = "NONE"} : (tensor<4xf32>, tensor<  f32>) -> tensor<4xf32>
107  %8 = "tfl.mul"(%2, %3) {fused_activation_function = "NONE"} : (tensor<4xf32>, tensor<4xf32>) -> tensor<4xf32>
108
109  return %5, %6, %7, %8 : tensor<f32>, tensor<4xf32>, tensor<4xf32>, tensor<4xf32>
110}
111
112// CHECK-LABEL: @elementwise_unary_ops
113func @elementwise_unary_ops() -> (tensor<f32>, tensor<f32>, tensor<f32>, tensor<f32>, tensor<f32>, tensor<f32>, tensor<f32>) {
114  %0 = constant dense<-1.0> : tensor<f32>
115  %1 = constant dense<1.0> : tensor<f32>
116  %2 = constant dense<1.0> : tensor<f32>
117  %3 = constant dense<1.0> : tensor<f32>
118  %4 = constant dense<4.0> : tensor<f32>
119  %5 = constant dense<4.0> : tensor<f32>
120  %6 = constant dense<2.0> : tensor<f32>
121
122  // CHECK-DAG: [[cst0:%.*]] = constant dense<1.000000e+00> : tensor<f32>
123  // CHECK-DAG: [[cst1:%.*]] = constant dense<0.841470957> : tensor<f32>
124  // CHECK-DAG: [[cst2:%.*]] = constant dense<0.540302277> : tensor<f32>
125  // CHECK-DAG: [[cst3:%.*]] = constant dense<0.000000e+00> : tensor<f32>
126  // CHECK-DAG: [[cst4:%.*]] = constant dense<2.000000e+00> : tensor<f32>
127  // CHECK-DAG: [[cst5:%.*]] = constant dense<5.000000e-01> : tensor<f32>
128  // CHECK-DAG: [[cst6:%.*]] = constant dense<4.000000e+00> : tensor<f32>
129  // CHECK: return [[cst0]], [[cst1]], [[cst2]], [[cst3]], [[cst4]], [[cst5]], [[cst6]]
130
131  %7 = "tfl.abs"(%0) : (tensor<f32>) -> tensor<f32>
132  %8 = "tfl.sin"(%1) : (tensor<f32>) -> tensor<f32>
133  %9 = "tfl.cos"(%2) : (tensor<f32>) -> tensor<f32>
134  %10 = "tfl.log"(%3) : (tensor<f32>) -> tensor<f32>
135  %11 = "tfl.sqrt"(%4) : (tensor<f32>) -> tensor<f32>
136  %12 = "tfl.rsqrt"(%5) : (tensor<f32>) -> tensor<f32>
137  %13 = "tfl.square"(%6) : (tensor<f32>) -> tensor<f32>
138
139  return %7, %8, %9, %10, %11, %12, %13 : tensor<f32>, tensor<f32>, tensor<f32>, tensor<f32>, tensor<f32>, tensor<f32>, tensor<f32>
140}
141
142// CHECK-LABEL: @mul_int
143func @mul_int() -> (tensor<i32>, tensor<4xi32>, tensor<4xi32>, tensor<4xi32>) {
144  %0 = constant dense<8> : tensor<i32>
145  %1 = constant dense<1> : tensor<i32>
146
147  %2 = constant dense< 4> : tensor<4xi32>
148  %3 = constant dense<-2> : tensor<4xi32>
149
150  // CHECK-DAG: [[cst0:%.*]] = constant dense<8> : tensor<i32>
151  // CHECK-DAG: [[cst1:%.*]] = constant dense<-16> : tensor<4xi32>
152  // CHECK-DAG: [[cst2:%.*]] = constant dense<4> : tensor<4xi32>
153  // CHECK-DAG: [[cst3:%.*]] = constant dense<-8> : tensor<4xi32>
154  // CHECK: return [[cst0]], [[cst1]], [[cst2]], [[cst3]]
155
156  %5 = "tfl.mul"(%0, %1) {fused_activation_function = "NONE"} : (tensor<  i32>, tensor<  i32>) -> tensor<  i32>
157  %6 = "tfl.mul"(%0, %3) {fused_activation_function = "NONE"} : (tensor<  i32>, tensor<4xi32>) -> tensor<4xi32>
158  %7 = "tfl.mul"(%2, %1) {fused_activation_function = "NONE"} : (tensor<4xi32>, tensor<  i32>) -> tensor<4xi32>
159  %8 = "tfl.mul"(%2, %3) {fused_activation_function = "NONE"} : (tensor<4xi32>, tensor<4xi32>) -> tensor<4xi32>
160
161  return %5, %6, %7, %8 : tensor<i32>, tensor<4xi32>, tensor<4xi32>, tensor<4xi32>
162}
163
164// CHECK-LABEL: @add_dense_splat_int
165func @add_dense_splat_int() -> tensor<4xi32> {
166  %0 = constant dense<[-10, -1, 42, 100]> : tensor<4xi32>
167  %1 = constant dense< 5> : tensor<4xi32>
168
169  %2 = "tfl.add"(%0, %1) {fused_activation_function = "NONE"} : (tensor<4xi32>, tensor<4xi32>) -> tensor<4xi32>
170
171  return %2 : tensor<4xi32>
172
173// CHECK:  %cst = constant dense<[-5, 4, 47, 105]> : tensor<4xi32>
174// CHECK:  return %cst
175}
176
177// CHECK-LABEL: @add_splat_dense_int
178func @add_splat_dense_int() -> tensor<4xi32> {
179  %0 = constant dense< 5> : tensor<4xi32>
180  %1 = constant dense<[-10, -1, 42, 100]> : tensor<4xi32>
181
182  %2 = "tfl.add"(%0, %1) {fused_activation_function = "NONE"} : (tensor<4xi32>, tensor<4xi32>) -> tensor<4xi32>
183
184  return %2 : tensor<4xi32>
185
186// CHECK:  %cst = constant dense<[-5, 4, 47, 105]> : tensor<4xi32>
187// CHECK:  return %cst
188}
189
190// CHECK-LABEL: @add_dense_dense_int_same_shape
191func @add_dense_dense_int_same_shape() -> tensor<4xi32> {
192  %0 = constant dense<[15, 23, -44, -2]> : tensor<4xi32>
193  %1 = constant dense<[-10, -1, 42, 100]> : tensor<4xi32>
194
195  %2 = "tfl.add"(%0, %1) {fused_activation_function = "NONE"} : (tensor<4xi32>, tensor<4xi32>) -> tensor<4xi32>
196
197  return %2 : tensor<4xi32>
198
199// CHECK:  %cst = constant dense<[5, 22, -2, 98]> : tensor<4xi32>
200// CHECK:  return %cst
201}
202
203// CHECK-LABEL: @add_dense_dense_int_trailing_dim
204func @add_dense_dense_int_trailing_dim() -> (tensor<2x2xi32>, tensor<2x2x2xi32>, tensor<2x2x2xi32>) {
205  %cst_0 = constant dense<[10, 20]> : tensor<2xi32>
206  %cst_1 = constant dense<[[1, 2], [3, 4]]> : tensor<2x2xi32>
207  %cst_2 = constant dense<[[[1, 1], [2, 2]], [[3, 3], [4, 4]]]> : tensor<2x2x2xi32>
208
209  %0 = "tfl.add"(%cst_0, %cst_1) {fused_activation_function = "NONE"} : (tensor<    2xi32>, tensor<  2x2xi32>) -> tensor<  2x2xi32>
210  %1 = "tfl.add"(%cst_2, %cst_1) {fused_activation_function = "NONE"} : (tensor<2x2x2xi32>, tensor<  2x2xi32>) -> tensor<2x2x2xi32>
211  %2 = "tfl.add"(%cst_0, %cst_2) {fused_activation_function = "NONE"} : (tensor<    2xi32>, tensor<2x2x2xi32>) -> tensor<2x2x2xi32>
212
213  return %0, %1, %2 : tensor<2x2xi32>, tensor<2x2x2xi32>, tensor<2x2x2xi32>
214
215// CHECK:  %cst = constant dense<{{\[\[}}11, 22], [13, 24]]> : tensor<2x2xi32>
216// CHECK:  %cst_0 = constant dense<{{\[\[\[}}2, 3], [5, 6]], {{\[\[}}4, 5], [7, 8]]]> : tensor<2x2x2xi32>
217// CHECK:  %cst_1 = constant dense<{{\[\[\[}}11, 21], [12, 22]], {{\[\[}}13, 23], [14, 24]]]> : tensor<2x2x2xi32>
218// CHECK:  return %cst, %cst_0, %cst_1
219}
220
221// CHECK-LABEL: @add_dense_dense_int_mixing_1_n
222func @add_dense_dense_int_mixing_1_n() -> tensor<2x2xi32> {
223  %cst_0 = constant dense<[[1, 2]]> : tensor<1x2xi32>
224  %cst_1 = constant dense<[[3], [4]]> : tensor<2x1xi32>
225
226  %0 = "tfl.add"(%cst_0, %cst_1) {fused_activation_function = "NONE"} : (tensor<1x2xi32>, tensor<2x1xi32>) -> tensor<2x2xi32>
227
228  return %0 : tensor<2x2xi32>
229// CHECK: %cst = constant dense<{{\[\[}}4, 5], [5, 6]]> : tensor<2x2xi32>
230// CHECK:  return %cst
231}
232
233// CHECK-LABEL: @add_dense_splat_float
234func @add_dense_splat_float() -> tensor<4xf32> {
235  %0 = constant dense<[-10.0, -1.5, 42.0, 7.25]> : tensor<4xf32>
236  %1 = constant dense< 3.5> : tensor<4xf32>
237
238  %2 = "tfl.add"(%0, %1) {fused_activation_function = "NONE"} : (tensor<4xf32>, tensor<4xf32>) -> tensor<4xf32>
239
240  return %2 : tensor<4xf32>
241
242// CHECK:  %cst = constant dense<[-6.500000e+00, 2.000000e+00, 4.550000e+01, 1.075000e+01]> : tensor<4xf32>
243// CHECK:  return %cst
244}
245
246// CHECK-LABEL: @add_splat_dense_float
247func @add_splat_dense_float() -> tensor<4xf32> {
248  %0 = constant dense< 3.5> : tensor<4xf32>
249  %1 = constant dense<[-10.0, -1.5, 42.0, 7.25]> : tensor<4xf32>
250
251  %2 = "tfl.add"(%0, %1) {fused_activation_function = "NONE"} : (tensor<4xf32>, tensor<4xf32>) -> tensor<4xf32>
252
253  return %2 : tensor<4xf32>
254
255// CHECK:  %cst = constant dense<[-6.500000e+00, 2.000000e+00, 4.550000e+01, 1.075000e+01]> : tensor<4xf32>
256// CHECK:  return %cst
257}
258
259// CHECK-LABEL: @add_dense_dense_float_same_shape
260func @add_dense_dense_float_same_shape() -> (tensor<4xf32>) {
261  %0 = constant dense<[1.5, 2.3, -4.4, -2.0]> : tensor<4xf32>
262  %1 = constant dense<[-10.4, -1.3, 42.4, 100.0]> : tensor<4xf32>
263
264  %2 = "tfl.add"(%0, %1) {fused_activation_function = "NONE"} : (tensor<4xf32>, tensor<4xf32>) -> tensor<4xf32>
265
266  return %2 : tensor<4xf32>
267
268// CHECK:  %cst = constant dense<[-8.89999961, 1.000000e+00, 3.800000e+01, 9.800000e+01]> : tensor<4xf32>
269// CHECK:  return %cst
270}
271
272// CHECK-LABEL: @add_dense_dense_float_trailing_dim
273func @add_dense_dense_float_trailing_dim() -> (tensor<2x2xf32>, tensor<2x2x2xf32>, tensor<2x2x2xf32>) {
274  %cst_0 = constant dense<[1., -4.]> : tensor<2xf32>
275  %cst_1 = constant dense<[[-5.5, 1.5], [7.5, -4.5]]> : tensor<2x2xf32>
276  %cst_2 = constant dense<[[[1., 1.], [2., 2.]], [[3., 3.], [4., 4.]]]> : tensor<2x2x2xf32>
277
278  %0 = "tfl.add"(%cst_0, %cst_1) {fused_activation_function = "NONE"} : (tensor<    2xf32>, tensor<  2x2xf32>) -> tensor<  2x2xf32>
279  %1 = "tfl.add"(%cst_2, %cst_1) {fused_activation_function = "NONE"} : (tensor<2x2x2xf32>, tensor<  2x2xf32>) -> tensor<2x2x2xf32>
280  %2 = "tfl.add"(%cst_0, %cst_2) {fused_activation_function = "NONE"} : (tensor<    2xf32>, tensor<2x2x2xf32>) -> tensor<2x2x2xf32>
281
282  return %0, %1, %2 : tensor<2x2xf32>, tensor<2x2x2xf32>, tensor<2x2x2xf32>
283
284// CHECK:  %cst = constant dense<{{\[\[}}-4.500000e+00, -2.500000e+00], [8.500000e+00, -8.500000e+00]]> : tensor<2x2xf32>
285// CHECK:  %cst_0 = constant dense<{{\[\[\[}}-4.500000e+00, 2.500000e+00], [9.500000e+00, -2.500000e+00]], {{\[\[}}-2.500000e+00, 4.500000e+00], [1.150000e+01, -5.000000e-01]]]> : tensor<2x2x2xf32>
286// CHECK:  %cst_1 = constant dense<{{\[\[\[}}2.000000e+00, -3.000000e+00], [3.000000e+00, -2.000000e+00]], {{\[\[}}4.000000e+00, -1.000000e+00], [5.000000e+00, 0.000000e+00]]]> : tensor<2x2x2xf32>
287// CHECK:  return %cst, %cst_0, %cst_1
288}
289
290// CHECK-LABEL: @add_dense_dense_float_mixfng_1_n
291func @add_dense_dense_float_mixfng_1_n() -> tensor<2x2xf32> {
292  %cst_0 = constant dense<[[1.5, -2.5]]> : tensor<1x2xf32>
293  %cst_1 = constant dense<[[-3.], [4.]]> : tensor<2x1xf32>
294
295  %0 = "tfl.add"(%cst_0, %cst_1) {fused_activation_function = "NONE"} : (tensor<1x2xf32>, tensor<2x1xf32>) -> tensor<2x2xf32>
296
297  return %0 : tensor<2x2xf32>
298
299// CHECK: %cst = constant dense<{{\[\[}}-1.500000e+00, -5.500000e+00], [5.500000e+00, 1.500000e+00]]> : tensor<2x2xf32>
300// CHECK:  return %cst
301}
302
303// CHECK-LABEL: @rank
304func @rank() -> tensor<1xi32> {
305  %cst = constant dense<[[1], [2]]> : tensor<2x1xi32>
306
307  // CHECK: [[cst:%.*]] = constant dense<2> : tensor<1xi32>
308  // CHECK: return [[cst]]
309  %0 = "tfl.rank"(%cst) : (tensor<2x1xi32>) -> tensor<1xi32>
310  return %0 : tensor<1xi32>
311}
312
313// CHECK-LABEL: @rank_input_known_rank
314func @rank_input_known_rank(%arg0 : tensor<2x1xi32>) -> tensor<1xi32> {
315  // CHECK: [[cst:%.*]] = constant dense<2> : tensor<1xi32>
316  // CHECK: return [[cst]]
317  %0 = "tfl.rank"(%arg0) : (tensor<2x1xi32>) -> tensor<1xi32>
318  return %0 : tensor<1xi32>
319}
320
321// CHECK-LABEL: @reshape
322func @reshape() -> tensor<4xi32> {
323  %input = constant dense<[[1, 2], [3, 4]]> : tensor<2x2xi32>
324  %shape = constant dense<[4]> : tensor<1xi32>
325
326  // CHECK: [[cst:%.*]] = constant dense<[1, 2, 3, 4]> : tensor<4xi32>
327  // CHECK: return [[cst]]
328  %0 = "tfl.reshape"(%input, %shape) : (tensor<2x2xi32>, tensor<1xi32>) -> tensor<4xi32>
329  return %0 : tensor<4xi32>
330}
331
332// CHECK-LABEL: @reshape_dynamic_output
333func @reshape_dynamic_output() -> tensor<?xi32> {
334  %input = constant dense<[[1, 2], [3, 4]]> : tensor<2x2xi32>
335  %shape = constant dense<[4]> : tensor<1xi32>
336
337  // CHECK: [[cst:%.*]] = "tfl.pseudo_const"() {value = dense<[1, 2, 3, 4]> : tensor<4xi32>} : () -> tensor<?xi32>
338  // CHECK: return [[cst]]
339  %0 = "tfl.reshape"(%input, %shape) : (tensor<2x2xi32>, tensor<1xi32>) -> tensor<?xi32>
340  return %0 : tensor<?xi32>
341}
342
343
344// CHECK-LABEL: @pseudo_const
345func @pseudo_const() -> tensor<i32> {
346  // CHECK: [[cst:%.*]] = constant dense<1> : tensor<i32>
347  // CHECK: return [[cst]]
348  %0 = "tfl.pseudo_const"() {value = dense<1> : tensor<i32>} : () -> tensor<i32>
349  return %0 : tensor<i32>
350}
351
352
353// CHECK-LABEL: @range_int
354func @range_int() -> tensor<?xi32> {
355  %cst = constant dense<0> : tensor<i32>
356  %cst_1 = constant dense<4> : tensor<i32>
357  %cst_2 = constant dense<1> : tensor<i32>
358
359  // CHECK: [[cst:%.*]] = "tfl.pseudo_const"() {value = dense<[0, 1, 2, 3]> : tensor<4xi32>} : () -> tensor<?xi32>
360  // CHECK: return [[cst]]
361  %0 = "tfl.range"(%cst, %cst_1, %cst_2) : (tensor<i32>, tensor<i32>, tensor<i32>) -> tensor<?xi32>
362  return %0 : tensor<?xi32>
363}
364
365// CHECK-LABEL: @range_float
366func @range_float() -> tensor<?xf32> {
367  %cst = constant dense<0.0> : tensor<f32>
368  %cst_1 = constant dense<4.0> : tensor<f32>
369  %cst_2 = constant dense<1.0> : tensor<f32>
370
371  // CHECK: [[cst:%.*]] = "tfl.pseudo_const"() {value = dense<[0.000000e+00, 1.000000e+00, 2.000000e+00, 3.000000e+00]> : tensor<4xf32>} : () -> tensor<?xf32>
372  // CHECK: return [[cst]]
373  %0 = "tfl.range"(%cst, %cst_1, %cst_2) : (tensor<f32>, tensor<f32>, tensor<f32>) -> tensor<?xf32>
374  return %0 : tensor<?xf32>
375}
376
377
378// CHECK-LABEL: @range_float_neg_delta
379func @range_float_neg_delta() -> tensor<?xf32> {
380  %cst = constant dense<0.0> : tensor<f32>
381  %cst_1 = constant dense<-4.0> : tensor<f32>
382  %cst_2 = constant dense<-1.0> : tensor<f32>
383
384  // CHECK: [[cst:%.*]] = "tfl.pseudo_const"() {value = dense<[0.000000e+00, -1.000000e+00, -2.000000e+00, -3.000000e+00]> : tensor<4xf32>} : () -> tensor<?xf32>
385  // CHECK: return [[cst]]
386  %0 = "tfl.range"(%cst, %cst_1, %cst_2) : (tensor<f32>, tensor<f32>, tensor<f32>) -> tensor<?xf32>
387  return %0 : tensor<?xf32>
388}
389
390// CHECK-LABEL: @range_float_nonzero_base
391func @range_float_nonzero_base() -> tensor<?xf32> {
392  %cst = constant dense<2.0> : tensor<f32>
393  %cst_1 = constant dense<7.0> : tensor<f32>
394  %cst_2 = constant dense<1.5> : tensor<f32>
395
396  // CHECK: [[cst:%.*]] = "tfl.pseudo_const"() {value = dense<[2.000000e+00, 3.500000e+00, 5.000000e+00, 6.500000e+00]> : tensor<4xf32>} : () -> tensor<?xf32>
397  // CHECK: return [[cst]]
398  %0 = "tfl.range"(%cst, %cst_1, %cst_2) : (tensor<f32>, tensor<f32>, tensor<f32>) -> tensor<?xf32>
399  return %0 : tensor<?xf32>
400}
401
402// CHECK-LABEL: @transpose_no_fold
403func @transpose_no_fold(%arg0 : tensor<2xi32>) -> tensor<2x2xi32> {
404  %cst = constant dense<[[0, 1], [2, 3]]> : tensor<2x2xi32>
405
406  // CHECK: tfl.transpose
407  %0 = "tfl.transpose"(%cst, %arg0) : (tensor<2x2xi32>, tensor<2xi32>) -> tensor<2x2xi32>
408  return %0 : tensor<2x2xi32>
409}
410
411// CHECK-LABEL: @transpose_1d
412// Basic 1D identity
413func @transpose_1d() -> tensor<3xi32> {
414  %cst = constant dense<[1, 2, 3]> : tensor<3xi32>
415  %cst_perm = constant dense<0> : tensor<1xi32>
416
417  // CHECK: [[cst:%.*]] = constant dense<{{\[}}1, 2, 3]> : tensor<3xi32>
418  // CHECK: return [[cst]]
419  %0 = "tfl.transpose"(%cst, %cst_perm) : (tensor<3xi32>, tensor<1xi32>) -> tensor<3xi32>
420  return %0 : tensor<3xi32>
421}
422
423// CHECK-LABEL: @transpose_dynamic
424func @transpose_dynamic() -> tensor<?xi32> {
425  %cst = constant dense<[1, 2, 3]> : tensor<3xi32>
426  %cst_perm = constant dense<0> : tensor<1xi32>
427
428  // CHECK: [[cst:%.*]] = "tfl.pseudo_const"() {value = dense<{{\[}}1, 2, 3]> : tensor<3xi32>} : () -> tensor<?xi32>
429  // CHECK: return [[cst]]
430  %0 = "tfl.transpose"(%cst, %cst_perm) : (tensor<3xi32>, tensor<1xi32>) -> tensor<?xi32>
431  return %0 : tensor<?xi32>
432}
433
434// CHECK-LABEL: @transpose_2d
435func @transpose_2d() -> tensor<2x2xi32> {
436  %cst = constant dense<[[0, 1], [2, 3]]> : tensor<2x2xi32>
437  %cst_perm = constant dense<[1, 0]> : tensor<2xi32>
438
439  // CHECK: [[cst:%.*]] = constant dense<{{\[\[}}0, 2], {{\[}}1, 3]]> : tensor<2x2xi32>
440  // CHECK: return [[cst]]
441  %0 = "tfl.transpose"(%cst, %cst_perm) : (tensor<2x2xi32>, tensor<2xi32>) -> tensor<2x2xi32>
442  return %0 : tensor<2x2xi32>
443}
444
445// CHECK-LABEL: @transpose_2d_identity
446func @transpose_2d_identity() -> tensor<2x2xi32> {
447  %cst = constant dense<[[0, 1], [2, 3]]> : tensor<2x2xi32>
448  %cst_perm = constant dense<[0, 1]> : tensor<2xi32>
449
450  // CHECK: [[cst:%.*]] = constant dense<{{\[\[}}0, 1], {{\[}}2, 3]]> : tensor<2x2xi32>
451  // CHECK: return [[cst]]
452  %0 = "tfl.transpose"(%cst, %cst_perm) : (tensor<2x2xi32>, tensor<2xi32>) -> tensor<2x2xi32>
453  return %0 : tensor<2x2xi32>
454}
455
456// CHECK-LABEL: @transpose_3d
457// A test case adopted from TransposeTest.Test3DInputConstTensor in
458// tensorflow/lite/kernels/transpose_test.cc
459func @transpose_3d() -> tensor<4x2x3xi32> {
460  %cst = constant dense<[[[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11]], [[12, 13, 14, 15], [16, 17, 18, 19], [20, 21, 22, 23]]]> : tensor<2x3x4xi32>
461  %cst_perm = constant dense<[2, 0, 1]> : tensor<3xi32>
462
463  // CHECK: [[cst:%.*]] = constant dense<{{\[\[\[}}0, 4, 8], {{\[}}12, 16, 20]], {{\[\[}}1, 5, 9], {{\[}}13, 17, 21]], {{\[\[}}2, 6, 10], {{\[}}14, 18, 22]], {{\[\[}}3, 7, 11], {{\[}}15, 19, 23]]]> : tensor<4x2x3xi32>
464  // CHECK: return [[cst]]
465  %0 = "tfl.transpose"(%cst, %cst_perm) : (tensor<2x3x4xi32>, tensor<3xi32>) -> tensor<4x2x3xi32>
466  return %0 : tensor<4x2x3xi32>
467}
468
469// CHECK-LABEL: @ConstantFoldBinaryOpDynamicOutput
470func @ConstantFoldBinaryOpDynamicOutput() -> tensor<?xi32> {
471  %cst = constant dense<10> : tensor<i32>
472  %cst_0 = "tfl.pseudo_const"() {value = dense<[5, 10]> : tensor<2xi32>} : () -> tensor<?xi32>
473  %87 = "tfl.sub"(%cst_0, %cst) {fused_activation_function = "NONE"} : (tensor<?xi32>, tensor<i32>) -> tensor<?xi32>
474  return %87 : tensor<?xi32>
475
476  // CHECK: [[cst:%.*]] = "tfl.pseudo_const"() {value = dense<[-5, 0]> : tensor<2xi32>} : () -> tensor<?xi32>
477  // CHECK: return [[cst]]
478}
479
480// CHECK-LABEL: @add_dense_dense_int_same_shape_dynamic
481func @add_dense_dense_int_same_shape_dynamic() -> tensor<?xi32> {
482  %0 = constant dense<[15, 23, -44, -2]> : tensor<4xi32>
483  %1 = constant dense<[-10, -1, 42, 100]> : tensor<4xi32>
484
485  %2 = "tfl.add"(%0, %1) {fused_activation_function = "NONE"} : (tensor<4xi32>, tensor<4xi32>) -> tensor<?xi32>
486
487  return %2 : tensor<?xi32>
488
489  // CHECK: [[cst:%.*]] = "tfl.pseudo_const"() {value = dense<[5, 22, -2, 98]> : tensor<4xi32>} : () -> tensor<?xi32>
490  // CHECK: return [[cst]]
491}
492
493// CHECK-LABEL: @concat_2_tensors_1_empty
494func @concat_2_tensors_1_empty() -> tensor<2xi32> {
495  %1 = constant dense<1> : tensor<2xi32>
496  %2 = constant dense<[]> : tensor<0xi32>
497  %3 = "tfl.concatenation"(%1, %2) {axis = 0 : i32, fused_activation_function = "NONE"} : (tensor<2xi32>, tensor<0xi32>) -> tensor<2xi32>
498  return %3 : tensor<2xi32>
499
500  // CHECK: [[cst:%.*]] = constant dense<1> : tensor<2xi32>
501  // CHECK: return [[cst]] : tensor<2xi32>
502}
503
504// CHECK-LABEL: @concat_3_tensors_1_empty
505func @concat_3_tensors_1_empty() -> tensor<?xi32> {
506  %0 = constant dense<1> : tensor<2xi32>
507  %1 = constant dense<1> : tensor<2xi32>
508  %2 = constant dense<[]> : tensor<0xi32>
509  %3 = "tfl.concatenation"(%0, %1, %2) {axis = 0 : i32, fused_activation_function = "NONE"} : (tensor<2xi32>, tensor<2xi32>, tensor<0xi32>) -> tensor<?xi32>
510  return %3 : tensor<?xi32>
511
512  // CHECK: %0 = "tfl.concatenation"(%cst, %cst) {axis = 0 : i32, fused_activation_function = "NONE"}
513  // CHECK: return %0 : tensor<?xi32>
514}
515
516// CHECK-LABEL: @concatConstantTensorsFirstDim
517func @concatConstantTensorsFirstDim() -> tensor<2x2x3xi32> {
518  %cst_0 = constant dense<0> : tensor<1x2x3xi32>
519  %cst_1 = constant dense<1> : tensor<1x2x3xi32>
520  %0 = "tfl.concatenation"(%cst_0, %cst_1) {axis = 0 : i32, fused_activation_function = "NONE"} : (tensor<1x2x3xi32>, tensor<1x2x3xi32>) -> tensor<2x2x3xi32>
521  return %0 : tensor<2x2x3xi32>
522
523  // CHECK: [[cst:%.*]] = constant dense<[{{\[}}{{\[}}0, 0, 0], {{\[}}0, 0, 0]], {{\[}}{{\[}}1, 1, 1], {{\[}}1, 1, 1]]]> : tensor<2x2x3xi32>
524  // CHECK-NOT: constant-dense
525  // CHECK-NOT: "tfl.concatenation"
526  // CHECK: return [[cst]]
527}
528
529// CHECK-LABEL: @concatConstantTensorsMiddleDim
530func @concatConstantTensorsMiddleDim() -> tensor<1x4x3xi32> {
531  %cst_0 = constant dense<0> : tensor<1x2x3xi32>
532  %cst_1 = constant dense<1> : tensor<1x2x3xi32>
533  %0 = "tfl.concatenation"(%cst_0, %cst_1) {axis = 1 : i32, fused_activation_function = "NONE"} : (tensor<1x2x3xi32>, tensor<1x2x3xi32>) -> tensor<1x4x3xi32>
534  return %0 : tensor<1x4x3xi32>
535
536  // CHECK: [[cst:%.*]] = constant dense<[{{\[}}{{\[}}0, 0, 0], {{\[}}0, 0, 0], {{\[}}1, 1, 1], {{\[}}1, 1, 1]]]> : tensor<1x4x3xi32>
537  // CHECK-NOT: constant-dense
538  // CHECK-NOT: "tfl.concatenation"
539  // CHECK: return [[cst]]
540}
541
542// CHECK-LABEL: @concatConstantTensorsLastDim
543func @concatConstantTensorsLastDim() -> tensor<1x2x6xi32> {
544  %cst_0 = constant dense<0> : tensor<1x2x3xi32>
545  %cst_1 = constant dense<1> : tensor<1x2x3xi32>
546  %0 = "tfl.concatenation"(%cst_0, %cst_1) {axis = 2 : i32, fused_activation_function = "NONE"} : (tensor<1x2x3xi32>, tensor<1x2x3xi32>) -> tensor<1x2x6xi32>
547  return %0 : tensor<1x2x6xi32>
548
549  // CHECK: [[cst:%.*]] = constant dense<[{{\[}}{{\[}}0, 0, 0, 1, 1, 1], {{\[}}0, 0, 0, 1, 1, 1]]]> : tensor<1x2x6xi32>
550  // CHECK-NOT: constant-dense
551  // CHECK-NOT: "tfl.concatenation"
552  // CHECK: return [[cst]]
553}
554
555// CHECK-LABEL: @div_dense_dense_float_mixfng_1_n
556func @div_dense_dense_float_mixfng_1_n() -> tensor<2x2xf32> {
557  %cst_0 = constant dense<[[1.5, -2.5]]> : tensor<1x2xf32>
558  %cst_1 = constant dense<[[-3.], [4.]]> : tensor<2x1xf32>
559
560  %0 = "tfl.div"(%cst_0, %cst_1) {fused_activation_function = "NONE"} : (tensor<1x2xf32>, tensor<2x1xf32>) -> tensor<2x2xf32>
561
562  return %0 : tensor<2x2xf32>
563
564// CHECK: %cst = constant dense<{{\[\[}}-5.000000e-01, 0.833333313], [3.750000e-01, -6.250000e-01]]> : tensor<2x2xf32>
565// CHECK:  return %cst
566}
567
568// CHECK-LABEL: @div_dense_different_rank
569func @div_dense_different_rank() -> tensor<1x2x2xf32> {
570  %cst_0 = constant dense<[[[1.0],[2.0]]]> : tensor<1x2x1xf32>
571  %cst_1 = constant dense<[[2.0, 3.0]]> : tensor<1x2xf32>
572
573  %0 = "tfl.div"(%cst_0, %cst_1) {fused_activation_function = "NONE"} : (tensor<1x2x1xf32>, tensor<1x2xf32>) -> tensor<1x2x2xf32>
574
575  return %0 : tensor<1x2x2xf32>
576
577// CHECK: %cst = constant dense<[{{\[}}{{\[}}5.000000e-01, 0.333333343], [1.000000e+00, 0.666666686]]]> : tensor<1x2x2xf32>
578// CHECK:  return %cst
579}
580