[RISCV] Add Qualcomm uC Xqcics(Conditional Select) extension (#119504)
[llvm-project.git] / mlir / test / Conversion / TosaToLinalg / tosa-to-linalg-resize.mlir
blobd42d0a46692d47e302c4ad1c594b23287669d6b2
1 // RUN: mlir-opt --split-input-file -pass-pipeline="builtin.module(func.func(tosa-to-linalg))" %s -o -| FileCheck %s
3 // CHECK-LABEL: @unary_resize_nearest_fp32
4 func.func @unary_resize_nearest_fp32(%arg0 : tensor<3x1x1x7xf32>) -> tensor<3x1x1x7xf32> {
5   %resize = "tosa.resize"(%arg0) {mode = "NEAREST_NEIGHBOR", scale = array<i64: 2, 2, 1, 1>, offset = array<i64: 0, 0>, border = array<i64: 0, 0>} : (tensor<3x1x1x7xf32>) -> tensor<3x1x1x7xf32>
6   // CHECK: return %arg0
7   return %resize : tensor<3x1x1x7xf32>
10 // -----
12 // CHECK-LABEL: @unary_resize_nearest_fp16
13 func.func @unary_resize_nearest_fp16(%arg0 : tensor<3x1x1x7xf16>) -> tensor<3x1x1x7xf16> {
14   %resize = "tosa.resize"(%arg0) {mode = "NEAREST_NEIGHBOR", scale = array<i64: 2, 2, 1, 1>, offset = array<i64: 0, 0>, border = array<i64: 0, 0>} : (tensor<3x1x1x7xf16>) -> tensor<3x1x1x7xf16>
15   // CHECK: return %arg0
16   return %resize : tensor<3x1x1x7xf16>
19 // -----
21 // CHECK-LABEL: @unary_resize_bilinear_fp32
22 func.func @unary_resize_bilinear_fp32(%arg0 : tensor<3x1x1x7xf32>) -> tensor<3x1x1x7xf32> {
23   %resize = "tosa.resize"(%arg0) {mode = "BILINEAR", scale = array<i64: 2, 2, 1, 1>, offset = array<i64: 0, 0>, border = array<i64: 0, 0>} : (tensor<3x1x1x7xf32>) -> tensor<3x1x1x7xf32>
24   // CHECK: return %arg0
25   return %resize : tensor<3x1x1x7xf32>
28 // -----
30 // CHECK-LABEL: @unary_resize_bilinear_fp16
31 func.func @unary_resize_bilinear_fp16(%arg0 : tensor<3x1x1x7xf16>) -> tensor<3x1x1x7xf16> {
32   %resize = "tosa.resize"(%arg0) {mode = "BILINEAR", scale = array<i64: 2, 2, 1, 1>, offset = array<i64: 0, 0>, border = array<i64: 0, 0>} : (tensor<3x1x1x7xf16>) -> tensor<3x1x1x7xf16>
33   // CHECK: return %arg0
34   return %resize : tensor<3x1x1x7xf16>
37 // -----
39 // CHECK-LABEL: @unary_resize_nearest_i8
40 func.func @unary_resize_nearest_i8(%arg0 : tensor<3x1x1x7xi8>) -> tensor<3x1x1x7xi8> {
41   %resize = "tosa.resize"(%arg0) {mode = "NEAREST_NEIGHBOR", scale = array<i64: 2, 1, 3, 1>, offset = array<i64: 0, 0>, border = array<i64: 0, 0>} : (tensor<3x1x1x7xi8>) -> tensor<3x1x1x7xi8>
42   // CHECK: return %arg0
43   return %resize : tensor<3x1x1x7xi8>
46 // -----
48 // CHECK-LABEL: @broadcast_resize_nearest_f32
49 func.func @broadcast_resize_nearest_f32(%arg0 : tensor<3x1x1x7xf32>) -> tensor<3x1x5x7xf32> {
50   // CHECK: %[[COLLAPSE:.+]] = tensor.collapse_shape %arg0
51   // CHECK-NEXT{literal}: [[0], [1, 2, 3]] : tensor<3x1x1x7xf32> into tensor<3x7xf32>
52   // CHECK: %[[EMPTY:.+]] = tensor.empty() : tensor<3x1x5x7xf32>
53   // CHECK: %[[GENERIC:.+]] = linalg.generic 
54   // CHECK-SAME: indexing_maps = [#map, #map1], iterator_types = ["parallel", "parallel", "parallel", "parallel"]}
55   // CHECK-SAME: ins(%[[COLLAPSE]] : tensor<3x7xf32>) outs(%[[EMPTY]] : tensor<3x1x5x7xf32>)
56   // CHECK: ^bb0(%[[IN:.+]]: f32, %[[OUT:.+]]: f32):
57   // CHECK:   linalg.yield %[[IN]] : f32
58   %resize = "tosa.resize"(%arg0) {mode = "NEAREST_NEIGHBOR", scale = array<i64: 2, 1, 3, 1>, offset = array<i64: 0, 0>, border = array<i64: 0, 0>} : (tensor<3x1x1x7xf32>) -> tensor<3x1x5x7xf32>
60  // CHECK: return %[[GENERIC]]
61   return %resize : tensor<3x1x5x7xf32>
64 // -----
66 // CHECK-LABEL: @broadcast_resize_bilinear_i8
67 func.func @broadcast_resize_bilinear_i8(%arg0 : tensor<3x1x1x7xi8>) -> tensor<3x4x5x7xi32> {
68   // CHECK: %[[COLLAPSE:.+]] = tensor.collapse_shape %arg0
69   // CHECK-SAME{literal}: [[0], [1, 2, 3]] : tensor<3x1x1x7xi8> into tensor<3x7xi8>
70   // CHECK: %[[EMPTY:.+]] = tensor.empty() : tensor<3x7xi32>
71   // CHECK: %[[RESIZE:.+]] = linalg.generic
72   // CHECK-SAME: {indexing_maps = [#map, #map], iterator_types = ["parallel", "parallel"]}
73   // CHECK-SAME: ins(%[[COLLAPSE]] : tensor<3x7xi8>) outs(%[[EMPTY]] : tensor<3x7xi32>)
74   // CHECK: ^bb0(%[[IN:.+]]: i8, %[[OUT:.+]]: i32):
75   // CHECK:   %[[EXT:.+]] = arith.extsi %[[IN]] : i8 to i32
76   // CHECK-DAG:   %[[C2:.+]] = arith.constant 2 : i32
77   // CHECK:   %[[MUL:.+]] = arith.muli %[[EXT]], %[[C2]] : i32
78   // CHECK-DAG:   %[[C3:.+]] = arith.constant 3 : i32
79   // CHECK:   %[[OUT:.+]] = arith.muli %[[MUL]], %[[C3]] : i32
80   // CHECK:   linalg.yield %[[OUT]] : i32
81   // CHECK: } -> tensor<3x7xi32>
82   // CHECK: %[[EXPAND:.+]] = tensor.expand_shape %1
83   // CHECK-SAME{literal}: [[0], [1, 2, 3]] : tensor<3x7xi32> into tensor<3x1x1x7xi32>
84   // CHECK: %[[COLLAPSE:.+]] = tensor.collapse_shape %expanded
85   // CHECK-SAME{literal}:[[0], [1, 2, 3]] : tensor<3x1x1x7xi32> into tensor<3x7xi32>
86   // CHECK: %[[EMPTY:.+]] = tensor.empty() : tensor<3x4x5x7xi32>
87   // CHECK: %[[BROADCAST:.+]] = linalg.generic
88   // CHECK-SAME: indexing_maps = [#map1, #map2], iterator_types = ["parallel", "parallel", "parallel", "parallel"]}
89   // CHECK-SAME: ins(%[[COLLAPSE]] : tensor<3x7xi32>) outs(%[[EMPTY]] : tensor<3x4x5x7xi32>) {
90   // CHECK: ^bb0(%[[IN:.+]]: i32, %[[OUT:.+]]: i32):
91   // CHECK:   linalg.yield %[[IN]] : i32
92   %resize = "tosa.resize"(%arg0) {mode = "BILINEAR", scale = array<i64: 2, 1, 3, 1>, offset = array<i64: 0, 0>, border = array<i64: 0, 0>} : (tensor<3x1x1x7xi8>) -> tensor<3x4x5x7xi32>
94   // CHECK: return %[[BROADCAST]]
95   return %resize : tensor<3x4x5x7xi32>
98 // -----
100 // CHECK-LABEL: @unary_resize_bilinear_i32
101 func.func @unary_resize_bilinear_i32(%arg0 : tensor<3x1x1x7xi8>) -> tensor<3x1x1x7xi32> {
102   // CHECK: %[[COLLAPSE:.+]] = tensor.collapse_shape %arg0
103   // CHECK-SAME{literal}: [[0], [1, 2, 3]] : tensor<3x1x1x7xi8> into tensor<3x7xi8>
104   // CHECK: %[[EMPTY:.+]] = tensor.empty() : tensor<3x7xi32>
105   // CHECK: %[[GENERIC:.+]] = linalg.generic 
106   // CHECK-SAME: indexing_maps = [#map, #map]
107   // CHECK-SAME: iterator_types = ["parallel", "parallel"]}
108   // CHECK-SAME: ins(%[[COLLAPSE]] : tensor<3x7xi8>) outs(%[[EMPTY]] : tensor<3x7xi32>) {
109   // CHECK: ^bb0(%[[IN:.+]]: i8, %[[OUT:.+]]: i32):
110   // CHECK:   %[[EXT:.+]] = arith.extsi %[[IN]] : i8 to i32
111   // CHECK-DAG:   %[[C2:.+]] = arith.constant 2 : i32
112   // CHECK:   %[[MUL0:.+]] = arith.muli %[[EXT]], %[[C2]] : i32
113   // CHECK-DAG:   %[[C1:.+]] = arith.constant 2 : i32
114   // CHECK:   %4 = arith.muli %3, %[[C1]] : i32
115   // CHECK:   linalg.yield %4 : i32
116   // CHECK: } -> tensor<3x7xi32>
117   // CHECK: %[[EXPAND:.+]] = tensor.expand_shape %[[GENERIC:.+]]
118   // CHECK-SAME{literal} [[0], [1, 2, 3]] : tensor<3x7xi32> into tensor<3x1x1x7xi32>
119   %resize = "tosa.resize"(%arg0) {mode = "BILINEAR", scale = array<i64: 2, 1, 2, 1>, offset = array<i64: 0, 0>, border = array<i64: 0, 0>} : (tensor<3x1x1x7xi8>) -> tensor<3x1x1x7xi32>
121   // CHECK: return %[[EXPAND]]
122   return %resize : tensor<3x1x1x7xi32>
125 // -----
127 // CHECK-LABEL:  @resize_nearest_int
128 func.func @resize_nearest_int(%arg0: tensor<1x15x13x1xi8>) -> () {
129   // CHECK: %[[INIT:.+]] = tensor.empty() : tensor<1x23x179x1xi8>
130   // CHECK: %[[GENERIC:.+]] = linalg.generic
131   // CHECK: %[[IDX_0:.+]] = linalg.index 0
132   // CHECK: %[[IDX_1:.+]] = linalg.index 1
133   // CHECK: %[[IDX_2:.+]] = linalg.index 2
134   // CHECK: %[[IDX_3:.+]] = linalg.index 3
135   // CHECK-DAG: %[[ZERO:.+]] = arith.constant 0
136   // CHECK-DAG: %[[Y_MAX:.+]] = arith.constant 14
137   // CHECK-DAG: %[[X_MAX:.+]] = arith.constant 12
139   // CHECK: %[[Y:.+]] = arith.index_cast %[[IDX_1]]
140   // CHECK: %[[X:.+]] = arith.index_cast %[[IDX_2]]
141   // CHECK-DAG: %[[SCALE_Y_N:.*]] = arith.constant 11
142   // CHECK-DAG: %[[SCALE_Y_D:.*]] = arith.constant 7
143   // CHECK-DAG: %[[SCALE_X_N:.*]] = arith.constant 89
144   // CHECK-DAG: %[[SCALE_X_D:.*]] = arith.constant 6
145   // CHECK-DAG: %[[OFFSET_Y:.*]] = arith.constant 0
146   // CHECK-DAG: %[[OFFSET_X:.*]] = arith.constant 0
147   // CHECK-DAG: %[[BORDER_Y:.*]] = arith.constant 0
148   // CHECK-DAG: %[[BORDER_X:.*]] = arith.constant 0
150   // find the remainder and integer component of the target index.
152   // CHECK: %[[TEMP_Y:.*]] = arith.muli %[[Y]], %[[SCALE_Y_D]]
153   // CHECK: %[[Y:.*]] = arith.addi %[[TEMP_Y]], %[[OFFSET_Y]]
154   // CHECK: %[[I_Y:.*]] = arith.divsi %[[Y]], %[[SCALE_Y_N]]
155   // CHECK: %[[TEMP_Y:.*]] = arith.muli %[[I_Y]], %[[SCALE_Y_N]]
156   // CHECK: %[[D_Y:.*]] = arith.subi %[[Y]], %[[TEMP_Y]]
158   // CHECK: %[[TEMP_X:.*]] = arith.muli %[[X]], %[[SCALE_X_D]]
159   // CHECK: %[[X:.*]] = arith.addi %[[TEMP_X]], %[[OFFSET_X]]
160   // CHECK: %[[I_X:.*]] = arith.divsi %[[X]], %[[SCALE_X_N]]
161   // CHECK: %[[TEMP_X:.*]] = arith.muli %[[I_X]], %[[SCALE_X_N]]
162   // CHECK: %[[D_X:.*]] = arith.subi %[[X]], %[[TEMP_X]]
164   // Compute the offset and bound for the Y position.
165   // CHECK-DAG: %[[ONE:.*]] = arith.constant 1
166   // CHECK: %[[D_Y_DOUBLE:.*]] = arith.shli %[[D_Y]], %[[ONE]]
167   // CHECK: %[[PRED_Y:.*]] = arith.cmpi sge, %[[D_Y_DOUBLE]], %[[SCALE_Y_N]]
168   // CHECK: %[[VAL_37:.*]] = arith.select %[[PRED_Y]], %[[ONE]], %[[ZERO]]
169   // CHECK: %[[VAL_39:.*]] = arith.addi %[[I_Y]], %[[VAL_37]]
170   // CHECK: %[[LOWER:.*]] = arith.maxsi %[[ZERO]], %[[VAL_39]]
171   // CHECK: %[[CLAMPED:.*]] = arith.minsi %[[Y_MAX]], %[[LOWER]]
172   // CHECK: %[[IDY:.+]] = arith.index_cast %[[CLAMPED]]
174   // Compute the offset and bound for the X position.
175   // CHECK: %[[D_X_DOUBLE:.*]] = arith.shli %[[D_X]], %[[ONE]]
176   // CHECK: %[[PRED_X:.*]] = arith.cmpi sge, %[[D_X_DOUBLE]], %[[SCALE_X_N]]
177   // CHECK: %[[VAL_38:.*]] = arith.select %[[PRED_X]], %[[ONE]], %[[ZERO]]
178   // CHECK: %[[VAL_40:.*]] = arith.addi %[[I_X]], %[[VAL_38]]
179   // CHECK: %[[LOWER:.*]] = arith.maxsi %[[ZERO]], %[[VAL_40]]
180   // CHECK: %[[CLAMPED:.*]] = arith.minsi %[[X_MAX]], %[[LOWER]]
181   // CHECK: %[[IDX:.+]] = arith.index_cast %[[CLAMPED]]
183   // CHECK: %[[EXTRACT:.+]] = tensor.extract %arg0[%[[IDX_0]], %[[IDY]], %[[IDX]], %[[IDX_3]]]
184   // CHECK: linalg.yield %[[EXTRACT]]
186   // Round to the nearest index.
187   %0 = "tosa.resize"(%arg0) {mode = "NEAREST_NEIGHBOR", scale = array<i64: 11, 7, 89, 6>, offset = array<i64: 0, 0>, border = array<i64: 0, 0>} : (tensor<1x15x13x1xi8>) -> tensor<1x23x179x1xi8>
188   return
191 // -----
193 // CHECK-LABEL:  @resize_bilinear_int
194 // CHECK-SAME: (%[[ARG0:[0-9a-zA-Z_]*]]:
195 func.func @resize_bilinear_int(%arg0: tensor<1x19x20x1xi8>) {
196   // CHECK: %[[INIT:.+]] = tensor.empty() : tensor<1x304x320x1xi48>
197   // CHECK: %[[GENERIC:.+]] = linalg.generic
198   // CHECK: %[[IDX_0:.+]] = linalg.index 0
199   // CHECK: %[[IDX_1:.+]] = linalg.index 1
200   // CHECK: %[[IDX_2:.+]] = linalg.index 2
201   // CHECK: %[[IDX_3:.+]] = linalg.index 3
202   // CHECK-DAG: %[[ZERO:.+]] = arith.constant 0
203   // CHECK-DAG: %[[Y_MAX:.+]] = arith.constant 18
204   // CHECK-DAG: %[[X_MAX:.+]] = arith.constant 19
205   // CHECK: %[[Y:.+]] = arith.index_cast %[[IDX_1]]
206   // CHECK: %[[X:.+]] = arith.index_cast %[[IDX_2]]
207   // CHECK-DAG: %[[SCALE_Y_N:.*]] = arith.constant 16
208   // CHECK-DAG: %[[SCALE_Y_D:.*]] = arith.constant 1
209   // CHECK-DAG: %[[SCALE_X_N:.*]] = arith.constant 16
210   // CHECK-DAG: %[[SCALE_X_D:.*]] = arith.constant 1
211   // CHECK-DAG: %[[OFFSET_Y:.*]] = arith.constant 0
212   // CHECK-DAG: %[[OFFSET_X:.*]] = arith.constant 0
213   // CHECK-DAG: %[[BORDER_Y:.*]] = arith.constant 0
214   // CHECK-DAG: %[[BORDER_X:.*]] = arith.constant 0
216   // CHECK: %[[TEMP_Y:.*]] = arith.muli %[[Y]], %[[SCALE_Y_D]]
217   // CHECK: %[[Y:.*]] = arith.addi %[[TEMP_Y]], %[[OFFSET_Y]]
218   // CHECK: %[[I_Y:.*]] = arith.divsi %[[Y]], %[[SCALE_Y_N]]
219   // CHECK: %[[TEMP_Y:.*]] = arith.muli %[[I_Y]], %[[SCALE_Y_N]]
220   // CHECK: %[[D_Y:.*]] = arith.subi %[[Y]], %[[TEMP_Y]]
222   // CHECK: %[[TEMP_X:.*]] = arith.muli %[[X]], %[[SCALE_X_D]]
223   // CHECK: %[[X:.*]] = arith.addi %[[TEMP_X]], %[[OFFSET_X]]
224   // CHECK: %[[I_X:.*]] = arith.divsi %[[X]], %[[SCALE_X_N]]
225   // CHECK: %[[TEMP_X:.*]] = arith.muli %[[I_X]], %[[SCALE_X_N]]
226   // CHECK: %[[D_X:.*]] = arith.subi %[[X]], %[[TEMP_X]]
228   // Compute the left, right, and top indices for the bilinear interpolation.
230   // CHECK-DAG: %[[ONE:.*]] = arith.constant 1
231   // CHECK: %[[Y1:.*]] = arith.addi %[[I_Y]], %[[ONE]]
233   // Bound check each dimension.
235   // CHECK: %[[BOUND:.*]] = arith.maxsi %[[ZERO]], %[[I_Y]]
236   // CHECK: %[[YLO:.*]] = arith.minsi %[[Y_MAX]], %[[BOUND]]
238   // CHECK: %[[BOUND:.*]] = arith.maxsi %[[ZERO]], %[[Y1]]
239   // CHECK: %[[YHI:.*]] = arith.minsi %[[Y_MAX]], %[[BOUND]]
241   // CHECK: %[[YLOI:.+]] = arith.index_cast %[[YLO]]
242   // CHECK: %[[YHII:.+]] = arith.index_cast %[[YHI]]
244   // CHECK: %[[X1:.*]] = arith.addi %[[I_X]], %[[ONE]]
245   // CHECK: %[[BOUND:.*]] = arith.maxsi %[[ZERO]], %[[I_X]]
246   // CHECK: %[[XLO:.*]] = arith.minsi %[[X_MAX]], %[[BOUND]]
248   // CHECK: %[[BOUND:.*]] = arith.maxsi %[[ZERO]], %[[X1]]
249   // CHECK: %[[XHI:.*]] = arith.minsi %[[X_MAX]], %[[BOUND]]
251   // CHECK: %[[XLOI:.+]] = arith.index_cast %[[XLO]]
252   // CHECK: %[[XHII:.+]] = arith.index_cast %[[XHI]]
254   // Extract each corner of the bilinear interpolation.
256   // CHECK: %[[LOLO:.+]] = tensor.extract %[[ARG0]][%[[IDX_0]], %[[YLOI]], %[[XLOI]], %[[IDX_3]]]
257   // CHECK: %[[LOHI:.+]] = tensor.extract %[[ARG0]][%[[IDX_0]], %[[YLOI]], %[[XHII]], %[[IDX_3]]]
258   // CHECK: %[[HILO:.+]] = tensor.extract %[[ARG0]][%[[IDX_0]], %[[YHII]], %[[XLOI]], %[[IDX_3]]]
259   // CHECK: %[[HIHI:.+]] = tensor.extract %[[ARG0]][%[[IDX_0]], %[[YHII]], %[[XHII]], %[[IDX_3]]]
261   // CHECK: %[[XLOLO:.+]] = arith.extsi %[[LOLO]]
262   // CHECK: %[[XLOHI:.+]] = arith.extsi %[[LOHI]]
263   // CHECK: %[[XHILO:.+]] = arith.extsi %[[HILO]]
264   // CHECK: %[[XHIHI:.+]] = arith.extsi %[[HIHI]]
266   // CHECK-NEXT: %[[D_X_EXT:.+]] = arith.extsi %[[D_X]]
267   // CHECK-NEXT: %[[D_Y_EXT:.+]] = arith.extsi %[[D_Y]]
268   // CHECK-NEXT: %[[Y_N_EXT:.+]] = arith.extsi %[[SCALE_Y_N]]
269   // CHECK-NEXT: %[[X_N_EXT:.+]] = arith.extsi %[[SCALE_X_N]]
271   // Compute the bilinear interpolation.
273   // CHECK: %[[NDX:.+]] = arith.subi %[[X_N_EXT]], %[[D_X_EXT]]
274   // CHECK: %[[WLOLO:.+]] = arith.muli %[[XLOLO]], %[[NDX]]
275   // CHECK: %[[WLOHI:.+]] = arith.muli %[[XLOHI]], %[[D_X_EXT]]
276   // CHECK: %[[LO:.+]] = arith.addi %[[WLOLO]], %[[WLOHI]]
277   // CHECK: %[[NDX:.+]] = arith.subi %[[X_N_EXT]], %[[D_X_EXT]]
278   // CHECK: %[[WHILO:.+]] = arith.muli %[[XHILO]], %[[NDX]]
279   // CHECK: %[[WHIHI:.+]] = arith.muli %[[XHIHI]], %[[D_X_EXT]]
280   // CHECK: %[[HI:.+]] = arith.addi %[[WHILO]], %[[WHIHI]]
281   // CHECK: %[[NDY:.+]] = arith.subi %[[Y_N_EXT]], %[[D_Y_EXT]]
282   // CHECK: %[[WLO:.+]] = arith.muli %[[LO]], %[[NDY]]
283   // CHECK: %[[WHI:.+]] = arith.muli %[[HI]], %[[D_Y_EXT]]
284   // CHECK: %[[RESULT:.+]] = arith.addi %[[WLO]], %[[WHI]]
285   // CHECK: linalg.yield %[[RESULT]]
287   // Round to the nearest index.
288   %0 = "tosa.resize"(%arg0) {mode = "BILINEAR", scale = array<i64: 16, 1, 16, 1>, offset = array<i64: 0, 0>, border = array<i64: 0, 0>} : (tensor<1x19x20x1xi8>) -> tensor<1x304x320x1xi48>
289   return
292 // -----
294 // CHECK-LABEL: @resize_nearest_fp32
295 func.func @resize_nearest_fp32(%input: tensor<1x50x48x1xf32>) -> () {
296   // CHECK: %[[INIT:.+]] = tensor.empty() : tensor<1x1600x1536x1xf32>
297   // CHECK: %[[GENERIC:.+]] = linalg.generic
298   // CHECK: %[[IDX0:.+]] = linalg.index 0
299   // CHECK: %[[IDX1:.+]] = linalg.index 1
300   // CHECK: %[[IDX2:.+]] = linalg.index 2
301   // CHECK: %[[IDX3:.+]] = linalg.index 3
302   // CHECK-DAG: %[[ZERO:.*]] = arith.constant 0
303   // CHECK-DAG: %[[YMAX:.*]] = arith.constant 49
304   // CHECK-DAG: %[[XMAX:.*]] = arith.constant 47
305   // CHECK: %[[Y:.+]] = arith.index_cast %[[IDX1]]
306   // CHECK: %[[X:.+]] = arith.index_cast %[[IDX2]]
307   // CHECK-DAG: %[[SCALE_Y_N:.*]] = arith.constant 64
308   // CHECK-DAG: %[[SCALE_Y_D:.*]] = arith.constant 2
309   // CHECK-DAG: %[[SCALE_X_N:.*]] = arith.constant 64
310   // CHECK-DAG: %[[SCALE_X_D:.*]] = arith.constant 2
311   // CHECK-DAG: %[[OFFSET_Y:.*]] = arith.constant -31
312   // CHECK-DAG: %[[OFFSET_X:.*]] = arith.constant -31
313   // CHECK-DAG: %[[BORDER_Y:.*]] = arith.constant 31
314   // CHECK-DAG: %[[BORDER_X:.*]] = arith.constant 31
316   // CHECK: %[[VAL_29:.*]] = arith.muli %[[Y]], %[[SCALE_Y_D]]
317   // CHECK: %[[Y_TEMP:.*]] = arith.addi %[[VAL_29]], %[[OFFSET_Y]]
318   // CHECK: %[[IY_TEMP:.*]] = arith.floordivsi %[[Y_TEMP]], %[[SCALE_Y_N]]
319   // CHECK: %[[RY:.*]] = arith.remsi %[[Y_TEMP]], %[[SCALE_Y_N]]
320   // CHECK: %[[RY_FP:.*]] = arith.sitofp %[[RY]]
321   // CHECK: %[[SCALE_Y_N_FP:.*]] = arith.uitofp %[[SCALE_Y_N]]
322   // CHECK: %[[D_Y:.*]] = arith.divf %[[RY_FP]], %[[SCALE_Y_N_FP]]
324   // CHECK: %[[VAL_30:.*]] = arith.muli %[[X]], %[[SCALE_X_D]]
325   // CHECK: %[[X_TEMP:.*]] = arith.addi %[[VAL_30]], %[[OFFSET_X]]
326   // CHECK: %[[IX_TEMP:.*]] = arith.floordivsi %[[X_TEMP]], %[[SCALE_X_N]]
327   // CHECK: %[[RX:.*]] = arith.remsi %[[X_TEMP]], %[[SCALE_X_N]]
328   // CHECK: %[[RX_FP:.*]] = arith.sitofp %[[RX]]
329   // CHECK: %[[SCALE_X_N_FP:.*]] = arith.uitofp %[[SCALE_X_N]]
330   // CHECK: %[[D_X:.*]] = arith.divf %[[RX_FP]], %[[SCALE_X_N_FP]]
332   // CHECK-DAG: %[[ONE:.*]] = arith.constant 1
333   // CHECK-DAG: %[[HALF:.*]] = arith.constant 5.000000e-01
334   // CHECK: %[[PRED_Y:.*]] = arith.cmpf oge, %[[D_Y]], %[[HALF]]
335   // CHECK: %[[ROUND_Y:.*]] = arith.select %[[PRED_Y]], %[[ONE]], %[[ZERO]]
336   // CHECK: %[[VAL_48:.*]] = arith.addi %[[IY_TEMP]], %[[ROUND_Y]]
337   // CHECK: %[[LOWER:.*]] = arith.maxsi %[[ZERO]], %[[VAL_48]]
338   // CHECK: %[[CLAMPED:.*]] = arith.minsi %[[YMAX]], %[[LOWER]]
339   // CHECK: %[[IDY:.*]] = arith.index_cast %[[CLAMPED]]
341   // CHECK-DAG: %[[HALF:.*]] = arith.constant 5.000000e-01
342   // CHECK: %[[PRED_X:.*]] = arith.cmpf oge, %[[D_X]], %[[HALF]]
343   // CHECK: %[[ROUND_X:.*]] = arith.select %[[PRED_X]], %[[ONE]], %[[ZERO]]
344   // CHECK: %[[VAL_49:.*]] = arith.addi %[[IX_TEMP]], %[[ROUND_X]]
345   // CHECK: %[[LOWER:.*]] = arith.maxsi %[[ZERO]], %[[VAL_49]]
346   // CHECK: %[[CLAMPED:.*]] = arith.minsi %[[XMAX]], %[[LOWER]]
347   // CHECK: %[[IDX:.*]] = arith.index_cast %[[CLAMPED]]
349   // CHECK: %[[EXTRACT:.+]] = tensor.extract %arg0[%[[IDX0]], %[[IDY]], %[[IDX]], %[[IDX3]]]
350   // CHECK: linalg.yield %[[EXTRACT]]
352   %output = "tosa.resize"(%input) {mode = "NEAREST_NEIGHBOR", scale = array<i64: 64, 2, 64, 2>, offset = array<i64: -31, -31>, border = array<i64: 31, 31>} : (tensor<1x50x48x1xf32>) -> tensor<1x1600x1536x1xf32>
353   return
356 // -----
358 // CHECK-LABEL: @resize_bilinear_fp
359 func.func @resize_bilinear_fp(%input: tensor<1x23x24x1xf32>) -> () {
360   // CHECK: %[[INIT:.+]] = tensor.empty() : tensor<1x92x96x1xf32>
361   // CHECK: %[[GENERIC:.+]] = linalg.generic
362   // CHECK: %[[IDX_0:.+]] = linalg.index 0
363   // CHECK: %[[IDX_1:.+]] = linalg.index 1
364   // CHECK: %[[IDX_2:.+]] = linalg.index 2
365   // CHECK: %[[IDX_3:.+]] = linalg.index 3
366   // CHECK-DAG: %[[ZERO:.*]] = arith.constant 0
367   // CHECK-DAG: %[[Y_MAX:.*]] = arith.constant 22
368   // CHECK-DAG: %[[X_MAX:.*]] = arith.constant 23
369   // CHECK: %[[Y:.+]] = arith.index_cast %[[IDX_1]]
370   // CHECK: %[[X:.+]] = arith.index_cast %[[IDX_2]]
371   // CHECK-DAG: %[[SCALE_Y_N:.*]] = arith.constant 4
372   // CHECK-DAG: %[[SCALE_Y_D:.*]] = arith.constant 1
373   // CHECK-DAG: %[[SCALE_X_N:.*]] = arith.constant 4
374   // CHECK-DAG: %[[SCALE_X_D:.*]] = arith.constant 1
375   // CHECK-DAG: %[[OFFSET_Y:.*]] = arith.constant 0
376   // CHECK-DAG: %[[OFFSET_X:.*]] = arith.constant 0
377   // CHECK-DAG: %[[BORDER_Y:.*]] = arith.constant 0
378   // CHECK-DAG: %[[BORDER_X:.*]] = arith.constant 0
380   // CHECK: %[[VAL_29:.*]] = arith.muli %[[Y]], %[[SCALE_Y_D]]
381   // CHECK: %[[Y_TEMP:.*]] = arith.addi %[[VAL_29]], %[[OFFSET_Y]]
382   // CHECK: %[[I_Y:.*]] = arith.floordivsi %[[Y_TEMP]], %[[SCALE_Y_N]]
383   // CHECK: %[[RY:.*]] = arith.remsi %[[Y_TEMP]], %[[SCALE_Y_N]]
384   // CHECK: %[[RY_FP:.*]] = arith.sitofp %[[RY]]
385   // CHECK: %[[SCALE_Y_N_FP:.*]] = arith.uitofp %[[SCALE_Y_N]]
386   // CHECK: %[[D_Y:.*]] = arith.divf %[[RY_FP]], %[[SCALE_Y_N_FP]]
388   // CHECK: %[[VAL_30:.*]] = arith.muli %[[X]], %[[SCALE_X_D]]
389   // CHECK: %[[X_TEMP:.*]] = arith.addi %[[VAL_30]], %[[OFFSET_X]]
390   // CHECK: %[[I_X:.*]] = arith.floordivsi %[[X_TEMP]], %[[SCALE_X_N]]
391   // CHECK: %[[RX:.*]] = arith.remsi %[[X_TEMP]], %[[SCALE_X_N]]
392   // CHECK: %[[RX_FP:.*]] = arith.sitofp %[[RX]]
393   // CHECK: %[[SCALE_X_N_FP:.*]] = arith.uitofp %[[SCALE_X_N]]
394   // CHECK: %[[D_X:.*]] = arith.divf %[[RX_FP]], %[[SCALE_X_N_FP]]
396   // Compute the left, right, and top indices for the bilinear interpolation.
398   // CHECK: %[[ONE:.*]] = arith.constant 1
400   // Bound check each dimension.
402   // CHECK: %[[Y1:.*]] = arith.addi %[[I_Y]], %[[ONE]]
404   // CHECK: %[[BOUND:.*]] = arith.maxsi %[[ZERO]], %[[I_Y]]
405   // CHECK: %[[YLO:.*]] = arith.minsi %[[Y_MAX]], %[[BOUND]]
407   // CHECK: %[[BOUND:.*]] = arith.maxsi %[[ZERO]], %[[Y1]]
408   // CHECK: %[[YHI:.*]] = arith.minsi %[[Y_MAX]], %[[BOUND]]
410   // CHECK: %[[YLOI:.+]] = arith.index_cast %[[YLO]]
411   // CHECK: %[[YHII:.+]] = arith.index_cast %[[YHI]]
413   // CHECK: %[[X1:.*]] = arith.addi %[[I_X]], %[[ONE]]
414   // CHECK: %[[BOUND:.*]] = arith.maxsi %[[ZERO]], %[[I_X]]
415   // CHECK: %[[XLO:.*]] = arith.minsi %[[X_MAX]], %[[BOUND]]
417   // CHECK: %[[BOUND:.*]] = arith.maxsi %[[ZERO]], %[[X1]]
418   // CHECK: %[[XHI:.*]] = arith.minsi %[[X_MAX]], %[[BOUND]]
420   // CHECK: %[[XLOI:.+]] = arith.index_cast %[[XLO]]
421   // CHECK: %[[XHII:.+]] = arith.index_cast %[[XHI]]
423   // CHECK: %[[LOLO:.+]] = tensor.extract %arg0[%[[IDX_0]], %[[YLOI]], %[[XLOI]], %[[IDX_3]]]
424   // CHECK: %[[LOHI:.+]] = tensor.extract %arg0[%[[IDX_0]], %[[YLOI]], %[[XHII]], %[[IDX_3]]]
425   // CHECK: %[[HILO:.+]] = tensor.extract %arg0[%[[IDX_0]], %[[YHII]], %[[XLOI]], %[[IDX_3]]]
426   // CHECK: %[[HIHI:.+]] = tensor.extract %arg0[%[[IDX_0]], %[[YHII]], %[[XHII]], %[[IDX_3]]]
428   // CHECK-DAG: %[[ONE:.+]] = arith.constant 1.000000e+00 : f32
429   // CHECK: %[[NDX:.+]] = arith.subf %[[ONE]], %[[D_X]]
430   // CHECK: %[[WLOLO:.+]] = arith.mulf %[[LOLO]], %[[NDX]]
431   // CHECK: %[[WLOHI:.+]] = arith.mulf %[[LOHI]], %[[D_X]]
432   // CHECK: %[[LO:.+]] = arith.addf %[[WLOLO]], %[[WLOHI]]
433   // CHECK: %[[NDX:.+]] = arith.subf %[[ONE]], %[[D_X]]
434   // CHECK: %[[WHILO:.+]] = arith.mulf %[[HILO]], %[[NDX]]
435   // CHECK: %[[WHIHI:.+]] = arith.mulf %[[HIHI]], %[[D_X]]
436   // CHECK: %[[HI:.+]] = arith.addf %[[WHILO]], %[[WHIHI]]
437   // CHECK: %[[NDY:.+]] = arith.subf %[[ONE]], %[[D_Y]]
438   // CHECK: %[[WLO:.+]] = arith.mulf %[[LO]], %[[NDY]]
439   // CHECK: %[[WHI:.+]] = arith.mulf %[[HI]], %[[D_Y]]
440   // CHECK: %[[RESULT:.+]] = arith.addf %[[WLO]], %[[WHI]]
441   // CHECK: linalg.yield %[[RESULT]]
443   // Round by bilinear interpolation
444   %output = "tosa.resize"(%input) {mode = "BILINEAR", scale = array<i64: 4, 1, 4, 1>, offset = array<i64: 0, 0>, border = array<i64: 0, 0>} : (tensor<1x23x24x1xf32>) -> tensor<1x92x96x1xf32>
446   return
449 // -----
451 // CHECK-LABEL: @resize_dyn
452 // CHECK-SAME: (%[[ARG0:[0-9a-zA-Z_]*]]:
453 func.func @resize_dyn(%input: tensor<?x2x2x1xi8>) -> () {
454   // CHECK-DAG: %[[C0:.+]] = arith.constant 0
455   // CHECK: %[[BATCH:.+]] = tensor.dim %arg0, %[[C0]]
456   // CHECK: %[[INIT:.+]] = tensor.empty(%[[BATCH]]) : tensor<?x4x4x1xi32>
457   // CHECK: %[[GENERIC:.+]] = linalg.generic
458   %output = "tosa.resize"(%input) { scale = array<i64: 4, 2, 4, 2>, offset = array<i64: -1, -1>, border = array<i64: 1, 1>, mode = "BILINEAR" } : (tensor<?x2x2x1xi8>)  -> (tensor<?x4x4x1xi32>)
459   return
462 // -----
464 // CHECK-LABEL: @resize_bilinear_int48
465 func.func @resize_bilinear_int48(%arg0: tensor<1x19x19x1xi16>) {
466   %0 = "tosa.resize"(%arg0) {mode = "BILINEAR", scale = array<i64: 16, 1, 16, 1>, offset = array<i64: 0, 0>, border = array<i64: 0, 0>} : (tensor<1x19x19x1xi16>) -> tensor<1x289x289x1xi48>
467            return
470 // -----
472 // CHECK-LABEL: skip_interpolate_bilinear_i8
473 func.func @skip_interpolate_bilinear_i8(%arg0 : tensor<3x1x2x7xi8>) -> tensor<3x1x5x7xi32> {
474   // CHECK:  %[[GENERIC:.+]] = linalg.generic
475   // CHECK:    %[[BATCH:.+]] = linalg.index 0
476   // CHECK:    %[[CHANNEL:.+]] = linalg.index 3
477   // CHECK-DAG:    %[[C3:.+]] = arith.constant 3
478   // CHECK-DAG:    %[[C2:.+]] = arith.constant 2
479   // CHECK:    %[[EXTRACT0:.+]] = tensor.extract %arg0[%[[BATCH]], %{{.+}}, %{{.+}}, %[[CHANNEL]]] : tensor<3x1x2x7xi8>
480   // CHECK:    %[[EXTRACT1:.+]] = tensor.extract %arg0[%[[BATCH]], %{{.+}}, %{{.+}}, %[[CHANNEL]]] : tensor<3x1x2x7xi8>
481   // CHECK:    %[[EXT0:.+]] = arith.extsi %[[EXTRACT0]] : i8 to i32
482   // CHECK:    %[[EXT1:.+]] = arith.extsi %[[EXTRACT1]] : i8 to i32
483   // CHECK:    %[[SUB:.+]] = arith.subi %[[C3]], %[[DX:.+]]
484   // CHECK:    %[[MUL0:.+]] = arith.muli %[[EXT0]], %[[SUB]]
485   // CHECK:    %[[MUL1:.+]] = arith.muli %[[EXT1]], %[[DX]]
486   // CHECK:    %[[ADD:.+]] = arith.addi %[[MUL0]], %[[MUL1]]
487   // CHECK:    %[[RES:.+]] = arith.muli %[[ADD]], %[[C2]]
488   // CHECK:    linalg.yield %[[RES]]
489   %resize = "tosa.resize"(%arg0) {mode = "BILINEAR", scale = array<i64: 2, 1, 3, 1>, offset = array<i64: 0, 0>, border = array<i64: 0, 0>} : (tensor<3x1x2x7xi8>) -> tensor<3x1x5x7xi32>
491   // CHECK:  return %[[GENERIC]]
492   return %resize : tensor<3x1x5x7xi32>
495 // CHECK-LABEL: skip_interpolate_bilinear_f32
496 func.func @skip_interpolate_bilinear_f32(%arg0 : tensor<3x1x2x7xf32>) -> tensor<3x1x5x7xf32> {
497   // CHECK:  %[[GENERIC:.+]] = linalg.generic
498   // CHECK:    %[[BATCH:.+]] = linalg.index 0 : index
499   // CHECK:    %[[CHANNEL:.+]] = linalg.index 3 : index
500   // CHECK:    %[[EXTRACT0:.+]] = tensor.extract %arg0[%[[BATCH]], %{{.+}}, %{{.+}}, %[[CHANNEL]]] : tensor<3x1x2x7xf32>
501   // CHECK:    %[[EXTRACT1:.+]] = tensor.extract %arg0[%[[BATCH]], %{{.+}}, %{{.+}}, %[[CHANNEL]]] : tensor<3x1x2x7xf32>
502   // CHECK:    %[[C1:.+]] = arith.constant 1.000000e+00
503   // CHECK:    %[[SUB:.+]] = arith.subf %[[C1]], %[[DX:.+]]
504   // CHECK:    %[[MUL0:.+]] = arith.mulf %[[EXTRACT0]], %[[SUB]]
505   // CHECK:    %[[MUL1:.+]] = arith.mulf %[[EXTRACT1]], %[[DX]]
506   // CHECK:    %[[ADD:.+]] = arith.addf %[[MUL0]], %[[MUL1]]
507   // CHECK:    linalg.yield %[[ADD]]
508   %resize = "tosa.resize"(%arg0) {mode = "BILINEAR", scale = array<i64: 2, 1, 3, 1>, offset = array<i64: 0, 0>, border = array<i64: 0, 0>} : (tensor<3x1x2x7xf32>) -> tensor<3x1x5x7xf32>
510   // CHECK:  return %[[GENERIC]]
511   return %resize : tensor<3x1x5x7xf32>