1469 lines · plain
1// RUN: mlir-opt --split-input-file -canonicalize="test-convergence" %s | FileCheck %s2 3// CHECK-LABEL: @argmax_nofold4func.func @argmax_nofold(%arg0: tensor<?x1xf32>) -> tensor<1xi32> {5 // CHECK: tosa.argmax6 %0 = tosa.argmax %arg0 {axis = 0 : i32}: (tensor<?x1xf32>) -> tensor<1xi32>7 return %0 : tensor<1xi32>8}9 10// -----11 12// CHECK-LABEL: @test_argmax_fold_i64_index13func.func @test_argmax_fold_i64_index(%arg0: tensor<1xi8>) -> tensor<i64> {14 // CHECK: "tosa.const"() <{values = dense<0> : tensor<i64>}> : () -> tensor<i64>15 %0 = tosa.argmax %arg0 {axis = 0 : i32} : (tensor<1xi8>) -> tensor<i64>16 return %0 : tensor<i64>17}18 19// -----20 21// CHECK-LABEL: @pad_wh_avg_pool2d_nofold22func.func @pad_wh_avg_pool2d_nofold(%input: tensor<1x10x8x3xf32>) -> tensor<1x6x5x3xf32> {23 // CHECK: tosa.pad24 // CHECK: tosa.avg_pool2d25 // CHECK-SAME: pad = array<i64: 0, 1, 0, 1>26 %pad_shape = tosa.const_shape { values = dense<[0, 0, 1, 0, 1, 0, 0, 0]> : tensor<8xindex>} : () -> !tosa.shape<8>27 %pad_const = "tosa.const"() <{values = dense<0.0> : tensor<1xf32>}> : ()-> tensor<1xf32>28 %input_zp = "tosa.const"() <{values = dense<0.0> : tensor<1xf32>}> : ()-> tensor<1xf32>29 %output_zp = "tosa.const"() <{values = dense<0.0> : tensor<1xf32>}> : ()-> tensor<1xf32>30 %padded = tosa.pad %input, %pad_shape, %pad_const : (tensor<1x10x8x3xf32>, !tosa.shape<8>, tensor<1xf32>) -> tensor<1x11x9x3xf32>31 %pool = tosa.avg_pool2d %padded, %input_zp, %output_zp {acc_type = f32, kernel = array<i64: 2, 2>, pad = array<i64: 0, 1, 0, 1>, stride = array<i64: 2, 2>} : (tensor<1x11x9x3xf32>, tensor<1xf32>, tensor<1xf32>) -> tensor<1x6x5x3xf32>32 return %pool : tensor<1x6x5x3xf32>33}34 35// -----36 37// CHECK-LABEL: @pad_wh_avg_pool2d_nofold_pad_const38func.func @pad_wh_avg_pool2d_nofold_pad_const(%input: tensor<1x10x8x3xi8>) -> tensor<1x6x5x3xi8> {39 // CHECK: tosa.pad40 // CHECK: tosa.avg_pool2d41 // CHECK-SAME: pad = array<i64: 0, 1, 0, 1>42 %pad_shape = tosa.const_shape { values = dense<[0, 0, 1, 0, 1, 0, 0, 0]> : tensor<8xindex>} : () -> !tosa.shape<8>43 %pad_const = "tosa.const"() <{values = dense<15> : tensor<1xi8>}> : ()-> tensor<1xi8>44 %input_zp = "tosa.const"() <{values = dense<10> : tensor<1xi8>}> : ()-> tensor<1xi8>45 %output_zp = "tosa.const"() <{values = dense<20> : tensor<1xi8>}> : ()-> tensor<1xi8>46 %padded = tosa.pad %input, %pad_shape, %pad_const : (tensor<1x10x8x3xi8>, !tosa.shape<8>, tensor<1xi8>) -> tensor<1x11x9x3xi8>47 %pool = tosa.avg_pool2d %padded, %input_zp, %output_zp {acc_type = i32, kernel = array<i64: 2, 2>, pad = array<i64: 0, 1, 0, 1>, stride = array<i64: 2, 2>} : (tensor<1x11x9x3xi8>, tensor<1xi8>, tensor<1xi8>) -> tensor<1x6x5x3xi8>48 return %pool : tensor<1x6x5x3xi8>49}50 51// -----52 53// CHECK-LABEL: @pad_wh_avg_pool2d_nofold_pad_larger_than_kernel54func.func @pad_wh_avg_pool2d_nofold_pad_larger_than_kernel(%input: tensor<1x10x8x3xf32>) -> tensor<1x7x5x3xf32> {55 // CHECK: tosa.pad56 // CHECK: tosa.avg_pool2d57 %pad_shape = tosa.const_shape { values = dense<[0, 0, 3, 0, 1, 0, 0, 0]> : tensor<8xindex>} : () -> !tosa.shape<8>58 %pad_const = "tosa.const"() <{values = dense<0.0> : tensor<1xf32>}> : ()-> tensor<1xf32>59 %input_zp = "tosa.const"() <{values = dense<0.0> : tensor<1xf32>}> : ()-> tensor<1xf32>60 %output_zp = "tosa.const"() <{values = dense<0.0> : tensor<1xf32>}> : ()-> tensor<1xf32>61 %padded = tosa.pad %input, %pad_shape, %pad_const : (tensor<1x10x8x3xf32>, !tosa.shape<8>, tensor<1xf32>) -> tensor<1x13x9x3xf32>62 %pool = tosa.avg_pool2d %padded, %input_zp, %output_zp {acc_type = f32, kernel = array<i64: 2, 2>, pad = array<i64: 0, 1, 0, 1>, stride = array<i64: 2, 2>} : (tensor<1x13x9x3xf32>, tensor<1xf32>, tensor<1xf32>) -> tensor<1x7x5x3xf32>63 return %pool : tensor<1x7x5x3xf32>64}65 66// -----67 68// CHECK-LABEL: @pad_wh_conv2d_fold69func.func @pad_wh_conv2d_fold(%input: tensor<1x8x4x3xf32>, %weight: tensor<1x3x3x3xf32>, %bias: tensor<1xf32>) -> tensor<1x10x8x1xf32> {70 // CHECK-NOT: tosa.pad71 // CHECK: tosa.conv2d72 // CHECK-SAME: pad = array<i64: 2, 2, 3, 3>73 %pad_shape = tosa.const_shape { values = dense<[0, 0, 1, 1, 2, 2, 0, 0]> : tensor<8xindex>} : () -> !tosa.shape<8>74 %pad_const = "tosa.const"() <{values = dense<0.0> : tensor<1xf32>}> : ()-> tensor<1xf32>75 %input_zp = "tosa.const"() <{values = dense<0.0> : tensor<1xf32>}> : ()-> tensor<1xf32>76 %weight_zp = "tosa.const"() <{values = dense<0.0> : tensor<1xf32>}> : ()-> tensor<1xf32>77 %padded = tosa.pad %input, %pad_shape, %pad_const : (tensor<1x8x4x3xf32>, !tosa.shape<8>, tensor<1xf32>) -> tensor<1x10x8x3xf32>78 %conv = tosa.conv2d %padded, %weight, %bias, %input_zp, %weight_zp {acc_type = f32, pad = array<i64: 1, 1, 1, 1>, stride = array<i64: 1, 1>, dilation = array<i64: 1, 1>} : (tensor<1x10x8x3xf32>, tensor<1x3x3x3xf32>, tensor<1xf32>, tensor<1xf32>, tensor<1xf32>) -> tensor<1x10x8x1xf32>79 return %conv : tensor<1x10x8x1xf32>80}81 82// -----83 84// CHECK-LABEL: @pad_bwh_conv2d_nofold85func.func @pad_bwh_conv2d_nofold(%input: tensor<1x8x4x3xf32>, %weight: tensor<1x3x3x3xf32>, %bias: tensor<1xf32>) -> tensor<3x10x8x1xf32> {86 // CHECK: tosa.pad87 // CHECK: tosa.conv2d88 // CHECK-SAME: pad = array<i64: 1, 1, 1, 1>89 %pad_shape = tosa.const_shape { values = dense<[1, 1, 1, 1, 2, 2, 0, 0]> : tensor<8xindex>} : () -> !tosa.shape<8>90 %pad_const = "tosa.const"() <{values = dense<0.0> : tensor<1xf32>}> : ()-> tensor<1xf32>91 %input_zp = "tosa.const"() <{values = dense<0.0> : tensor<1xf32>}> : ()-> tensor<1xf32>92 %weight_zp = "tosa.const"() <{values = dense<0.0> : tensor<1xf32>}> : ()-> tensor<1xf32>93 %padded = tosa.pad %input, %pad_shape, %pad_const : (tensor<1x8x4x3xf32>, !tosa.shape<8>, tensor<1xf32>) -> tensor<3x10x8x3xf32>94 %conv = tosa.conv2d %padded, %weight, %bias, %input_zp, %weight_zp {acc_type = f32, pad = array<i64: 1, 1, 1, 1>, stride = array<i64: 1, 1>, dilation = array<i64: 1, 1>} : (tensor<3x10x8x3xf32>, tensor<1x3x3x3xf32>, tensor<1xf32>, tensor<1xf32>, tensor<1xf32>) -> tensor<3x10x8x1xf32>95 return %conv : tensor<3x10x8x1xf32>96}97 98// -----99 100// CHECK-LABEL: @pad_wh_conv2d_nofold_pad_const101func.func @pad_wh_conv2d_nofold_pad_const(%input: tensor<1x8x4x3xf32>, %weight: tensor<1x3x3x3xf32>, %bias: tensor<1xf32>) -> tensor<1x10x8x1xf32> {102 // CHECK: tosa.pad103 // CHECK: tosa.conv2d104 // CHECK-SAME: pad = array<i64: 1, 1, 1, 1>105 %pad_shape = tosa.const_shape { values = dense<[0, 0, 1, 1, 2, 2, 0, 0]> : tensor<8xindex>} : () -> !tosa.shape<8>106 %pad_const = "tosa.const"() <{values = dense<1.0> : tensor<1xf32>}> : ()-> tensor<1xf32>107 %input_zp = "tosa.const"() <{values = dense<0.0> : tensor<1xf32>}> : ()-> tensor<1xf32>108 %weight_zp = "tosa.const"() <{values = dense<0.0> : tensor<1xf32>}> : ()-> tensor<1xf32>109 %padded = tosa.pad %input, %pad_shape, %pad_const : (tensor<1x8x4x3xf32>, !tosa.shape<8>, tensor<1xf32>) -> tensor<1x10x8x3xf32>110 %conv = tosa.conv2d %padded, %weight, %bias, %input_zp, %weight_zp {acc_type = f32, pad = array<i64: 1, 1, 1, 1>, stride = array<i64: 1, 1>, dilation = array<i64: 1, 1>} : (tensor<1x10x8x3xf32>, tensor<1x3x3x3xf32>, tensor<1xf32>, tensor<1xf32>, tensor<1xf32>) -> tensor<1x10x8x1xf32>111 return %conv : tensor<1x10x8x1xf32>112}113 114// -----115 116// CHECK-LABEL: @pad_wh_depthwise_conv2d_fold117func.func @pad_wh_depthwise_conv2d_fold(%input: tensor<1x8x4x3xf32>, %weight: tensor<3x3x3x1xf32>, %bias: tensor<3xf32>) -> tensor<1x10x8x3xf32> {118 // CHECK-NOT: tosa.pad119 // CHECK: tosa.depthwise_conv2d120 // CHECK-SAME: pad = array<i64: 2, 2, 3, 3>121 %pad_shape = tosa.const_shape { values = dense<[0, 0, 1, 1, 2, 2, 0, 0]> : tensor<8xindex>} : () -> !tosa.shape<8>122 %pad_const = "tosa.const"() <{values = dense<0.0> : tensor<1xf32>}> : ()-> tensor<1xf32>123 %input_zp = "tosa.const"() <{values = dense<0.0> : tensor<1xf32>}> : ()-> tensor<1xf32>124 %weight_zp = "tosa.const"() <{values = dense<0.0> : tensor<1xf32>}> : ()-> tensor<1xf32>125 %padded = tosa.pad %input, %pad_shape, %pad_const : (tensor<1x8x4x3xf32>, !tosa.shape<8>, tensor<1xf32>) -> tensor<1x10x8x3xf32>126 %conv = tosa.depthwise_conv2d %padded, %weight, %bias, %input_zp, %weight_zp {acc_type = f32, pad = array<i64: 1, 1, 1, 1>, stride = array<i64: 1, 1>, dilation = array<i64: 1, 1>} : (tensor<1x10x8x3xf32>, tensor<3x3x3x1xf32>, tensor<3xf32>, tensor<1xf32>, tensor<1xf32>) -> tensor<1x10x8x3xf32>127 return %conv : tensor<1x10x8x3xf32>128}129 130// -----131 132// CHECK-LABEL: @pad_wh_max_pool2d_fold133func.func @pad_wh_max_pool2d_fold(%input: tensor<1x10x8x3xf32>) -> tensor<1x6x5x3xf32> {134 // CHECK-NOT: tosa.pad135 // CHECK: tosa.max_pool2d136 // CHECK-SAME: pad = array<i64: 1, 1, 1, 1>137 %pad_shape = tosa.const_shape { values = dense<[0, 0, 1, 0, 1, 0, 0, 0]> : tensor<8xindex>} : () -> !tosa.shape<8>138 %pad_const = "tosa.const"() <{values = dense<-3.4028235e+38> : tensor<1xf32>}> : ()-> tensor<1xf32>139 %padded = tosa.pad %input, %pad_shape, %pad_const : (tensor<1x10x8x3xf32>, !tosa.shape<8>, tensor<1xf32>) -> tensor<1x11x9x3xf32>140 %pool = tosa.max_pool2d %padded {kernel = array<i64: 2, 2>, pad = array<i64: 0, 1, 0, 1>, stride = array<i64: 2, 2>} : (tensor<1x11x9x3xf32>) -> tensor<1x6x5x3xf32>141 return %pool : tensor<1x6x5x3xf32>142}143 144// -----145 146// CHECK-LABEL: @pad_wh_max_pool2d_nofold_pad_const147func.func @pad_wh_max_pool2d_nofold_pad_const(%input: tensor<1x10x8x3xf32>) -> tensor<1x6x5x3xf32> {148 // CHECK: tosa.pad149 // CHECK: tosa.max_pool2d150 // CHECK-SAME: pad = array<i64: 0, 1, 0, 1>151 %pad_shape = tosa.const_shape { values = dense<[0, 0, 1, 0, 1, 0, 0, 0]> : tensor<8xindex>} : () -> !tosa.shape<8>152 %pad_const = "tosa.const"() <{values = dense<0.0> : tensor<1xf32>}> : ()-> tensor<1xf32>153 %padded = tosa.pad %input, %pad_shape, %pad_const : (tensor<1x10x8x3xf32>, !tosa.shape<8>, tensor<1xf32>) -> tensor<1x11x9x3xf32>154 %pool = tosa.max_pool2d %padded {kernel = array<i64: 2, 2>, pad = array<i64: 0, 1, 0, 1>, stride = array<i64: 2, 2>} : (tensor<1x11x9x3xf32>) -> tensor<1x6x5x3xf32>155 return %pool : tensor<1x6x5x3xf32>156}157 158// -----159 160// CHECK-LABEL: @pad_wh_max_pool2d_no_fold_8k_limit161func.func @pad_wh_max_pool2d_no_fold_8k_limit(%input: tensor<1x10x8x3xf32>) -> tensor<1x6x4101x3xf32> {162 // CHECK: tosa.pad163 // CHECK: tosa.max_pool2d164 %pad_shape = tosa.const_shape { values = dense<[0, 0, 1, 0, 8193, 0, 0, 0]> : tensor<8xindex>} : () -> !tosa.shape<8>165 %pad_const = "tosa.const"() <{values = dense<0.0> : tensor<1xf32>}> : ()-> tensor<1xf32>166 %padded = tosa.pad %input, %pad_shape, %pad_const : (tensor<1x10x8x3xf32>, !tosa.shape<8>, tensor<1xf32>) -> tensor<1x11x8201x3xf32>167 %pool = tosa.max_pool2d %padded {kernel = array<i64: 2, 2>, pad = array<i64: 0, 1, 0, 1>, stride = array<i64: 2, 2>} : (tensor<1x11x8201x3xf32>) -> tensor<1x6x4101x3xf32>168 return %pool : tensor<1x6x4101x3xf32>169}170 171// -----172 173// CHECK-LABEL: @add_bcast_zero_int174func.func @add_bcast_zero_int(%arg0: tensor<4x2x3xi32>) -> tensor<4x2x3xi32> {175 // CHECK-NOT: tosa.add176 // CHECK: return %arg0177 %zeros = "tosa.const"() {values = dense<0> : tensor<1x1x1xi32>} : () -> tensor<1x1x1xi32>178 %1 = tosa.add %arg0, %zeros : (tensor<4x2x3xi32>, tensor<1x1x1xi32>) -> tensor<4x2x3xi32>179 return %1 : tensor<4x2x3xi32>180}181 182// -----183 184// CHECK-LABEL: @add_zero_int185func.func @add_zero_int(%arg0: tensor<2x3xi32>) -> tensor<2x3xi32> {186 // CHECK: return %arg0187 // CHECK-NOT: tosa.add188 %zeros = "tosa.const"() {values = dense<0> : tensor<2x3xi32>} : () -> tensor<2x3xi32>189 %1 = tosa.add %arg0, %zeros : (tensor<2x3xi32>, tensor<2x3xi32>) -> tensor<2x3xi32>190 return %1 : tensor<2x3xi32>191}192 193// -----194 195// CHECK-LABEL: @cast_fold196func.func @cast_fold(%arg0: tensor<?x1xf32>) -> tensor<?x1xf32> {197 // CHECK: return %arg0198 %0 = tosa.cast %arg0 : (tensor<?x1xf32>) -> tensor<?x1xf32>199 return %0 : tensor<?x1xf32>200}201 202// -----203 204// CHECK-LABEL: @cast_nofold205func.func @cast_nofold(%arg0: tensor<?x1xf32>) -> tensor<?x1xi32> {206 // CHECK: tosa.cast207 %0 = tosa.cast %arg0 : (tensor<?x1xf32>) -> tensor<?x1xi32>208 return %0 : tensor<?x1xi32>209}210 211// -----212 213// CHECK-LABEL: @clamp_i32_not_noop214func.func @clamp_i32_not_noop(%arg0: tensor<4xi32>) -> tensor<4xi32> {215 // CHECK: tosa.clamp216 %0 = tosa.clamp %arg0 {min_val = 1 : i32, max_val = 4 : i32} : (tensor<4xi32>) -> tensor<4xi32>217 return %0 : tensor<4xi32>218}219 220// -----221 222// CHECK-LABEL: @clamp_f32_not_noop223func.func @clamp_f32_not_noop(%arg0: tensor<4xf32>) -> tensor<4xf32> {224 // CHECK: tosa.clamp225 %0 = tosa.clamp %arg0 {min_val = -3.40282347E+38 : f32, max_val = 3.40282347E+38 : f32} : (tensor<4xf32>) -> tensor<4xf32>226 return %0 : tensor<4xf32>227}228 229// -----230 231// CHECK-LABEL: @clamp_f16_is_noop232func.func @clamp_f16_is_noop(%arg0: tensor<4xf16>) -> tensor<4xf16> {233 // CHECK: return %arg0234 // CHECK-NOT: "tosa.clamp"235 // 0x7C00 and 0xFC00 are respectively positive and negative F32 infinity.236 %0 = tosa.clamp %arg0 {max_val = 0x7C00 : f16, min_val = 0xFC00 : f16} : (tensor<4xf16>) -> tensor<4xf16>237 return %0 : tensor<4xf16>238}239 240// -----241 242// CHECK-LABEL: @clamp_f32_is_noop243func.func @clamp_f32_is_noop(%arg0: tensor<4xf32>) -> tensor<4xf32> {244 // CHECK: return %arg0245 // CHECK-NOT: "tosa.clamp"246 // 0xFF800000 and 0x7F800000 are respectively negative and positive F32 infinity.247 %0 = tosa.clamp %arg0 {min_val = 0xFF800000 : f32, max_val = 0x7F800000 : f32} : (tensor<4xf32>) -> tensor<4xf32>248 return %0 : tensor<4xf32>249}250 251// -----252 253// CHECK-LABEL: @clamp_boolean_is_noop254func.func @clamp_boolean_is_noop(%arg0: tensor<4xi1>) -> tensor<4xi1> {255 // CHECK: return %arg0256 // CHECK-NOT: tosa.clamp257 %0 = tosa.clamp %arg0 {min_val = false, max_val = true} : (tensor<4xi1>) -> tensor<4xi1>258 return %0 : tensor<4xi1>259}260 261// -----262 263// CHECK-LABEL: @clamp_boolean_dynamic_is_noop264func.func @clamp_boolean_dynamic_is_noop(%arg0: tensor<?xi1>) -> tensor<?xi1> {265 // CHECK: return %arg0266 // CHECK-NOT: tosa.clamp267 %0 = tosa.clamp %arg0 {min_val = false, max_val = true} : (tensor<?xi1>) -> tensor<?xi1>268 return %0 : tensor<?xi1>269}270 271// -----272 273// CHECK-LABEL: @clamp_int8_is_noop274func.func @clamp_int8_is_noop(%arg0: tensor<4xi8>) -> tensor<4xi8> {275 // CHECK: return %arg0276 // CHECK-NOT: tosa.clamp277 %0 = tosa.clamp %arg0 {min_val = -128 : i8, max_val = 127 : i8} : (tensor<4xi8>) -> tensor<4xi8>278 return %0 : tensor<4xi8>279}280 281// -----282 283// CHECK-LABEL: @clamp_int16_is_noop284func.func @clamp_int16_is_noop(%arg0: tensor<4xi16>) -> tensor<4xi16> {285 // CHECK: return %arg0286 // CHECK-NOT: tosa.clamp287 %0 = tosa.clamp %arg0 {min_val = -32768 : i16, max_val = 32767 : i16} : (tensor<4xi16>) -> tensor<4xi16>288 return %0 : tensor<4xi16>289}290 291// -----292 293// CHECK-LABEL: @clamp_uint8_is_noop294func.func @clamp_uint8_is_noop(%arg0: tensor<4xui8>) -> tensor<4xui8> {295 // CHECK: return %arg0296 // CHECK-NOT: tosa.clamp297 %0 = tosa.clamp %arg0 {min_val = 0 : ui8, max_val = 255 : ui8} : (tensor<4xui8>) -> tensor<4xui8>298 return %0 : tensor<4xui8>299}300 301// -----302 303// CHECK-LABEL: @clamp_twice_is_single_clamp304func.func @clamp_twice_is_single_clamp(%arg0: tensor<4xi8>) -> tensor<4xi8> {305 // CHECK: tosa.clamp %arg0 {max_val = 2 : i8, min_val = -2 : i8}306 %0 = tosa.clamp %arg0 {max_val = 4 : i8, min_val = -2 : i8} : (tensor<4xi8>) -> tensor<4xi8>307 %1 = tosa.clamp %0 {max_val = 2 : i8, min_val = -4 : i8} : (tensor<4xi8>) -> tensor<4xi8>308 return %1 : tensor<4xi8>309}310 311// -----312 313// CHECK: @disjoint_clamp_twice_is_not_single_clamp(%[[INPUT:.*]]: tensor<4xi8>)314func.func @disjoint_clamp_twice_is_not_single_clamp(%arg0: tensor<4xi8>) -> tensor<4xi8> {315 // CHECK: %[[CLAMP_1:.*]] = tosa.clamp %[[INPUT]] {max_val = -5 : i8, min_val = -10 : i8} : (tensor<4xi8>) -> tensor<4xi8>316 // CHECK-NEXT: tosa.clamp %[[CLAMP_1]] {max_val = 5 : i8, min_val = 1 : i8} : (tensor<4xi8>) -> tensor<4xi8>317 %0 = tosa.clamp %arg0 {max_val = -5 : i8, min_val = -10 : i8} : (tensor<4xi8>) -> tensor<4xi8>318 %1 = tosa.clamp %0 {max_val = 5 : i8, min_val = 1 : i8} : (tensor<4xi8>) -> tensor<4xi8>319 return %1 : tensor<4xi8>320}321 322// -----323 324// CHECK-LABEL: @clamp_twice_with_nan_propagate_is_single_clamp325func.func @clamp_twice_with_nan_propagate_is_single_clamp(%arg0: tensor<4xi8>) -> tensor<4xi8> {326 // CHECK: tosa.clamp %arg0 {max_val = 2 : i8, min_val = -2 : i8}327 %0 = tosa.clamp %arg0 {max_val = 4 : i8, min_val = -2 : i8, nan_mode = PROPAGATE} : (tensor<4xi8>) -> tensor<4xi8>328 %1 = tosa.clamp %0 {max_val = 2 : i8, min_val = -4 : i8, nan_mode = PROPAGATE} : (tensor<4xi8>) -> tensor<4xi8>329 return %1 : tensor<4xi8>330}331 332// -----333 334// CHECK-LABEL: @clamp_twice_with_nan_ignore_is_single_clamp335func.func @clamp_twice_with_nan_ignore_is_single_clamp(%arg0: tensor<4xi8>) -> tensor<4xi8> {336 // CHECK: tosa.clamp %arg0 {max_val = 2 : i8, min_val = -2 : i8, nan_mode = IGNORE}337 %0 = tosa.clamp %arg0 {max_val = 4 : i8, min_val = -2 : i8, nan_mode = IGNORE} : (tensor<4xi8>) -> tensor<4xi8>338 %1 = tosa.clamp %0 {max_val = 2 : i8, min_val = -4 : i8, nan_mode = IGNORE} : (tensor<4xi8>) -> tensor<4xi8>339 return %1 : tensor<4xi8>340}341 342// -----343 344// CHECK-LABEL: @clamp_twice_with_nan_ignore_propagate_is_single_clamp345func.func @clamp_twice_with_nan_ignore_propagate_is_single_clamp(%arg0: tensor<4xi8>) -> tensor<4xi8> {346 // CHECK: tosa.clamp %arg0 {max_val = 2 : i8, min_val = -2 : i8, nan_mode = IGNORE}347 %0 = tosa.clamp %arg0 {max_val = 4 : i8, min_val = -2 : i8, nan_mode = IGNORE} : (tensor<4xi8>) -> tensor<4xi8>348 %1 = tosa.clamp %0 {max_val = 2 : i8, min_val = -4 : i8, nan_mode = PROPAGATE} : (tensor<4xi8>) -> tensor<4xi8>349 return %1 : tensor<4xi8>350}351 352// -----353 354// CHECK: @clamp_twice_with_nan_propagate_ignore_is_not_single_clamp(%[[INPUT:.*]]: tensor<4xi8>)355func.func @clamp_twice_with_nan_propagate_ignore_is_not_single_clamp(%arg0: tensor<4xi8>) -> tensor<4xi8> {356 // CHECK: %[[CLAMP_1:.*]] = tosa.clamp %[[INPUT]] {max_val = 4 : i8, min_val = -2 : i8} : (tensor<4xi8>) -> tensor<4xi8>357 // CHECK-NEXT: tosa.clamp %[[CLAMP_1]] {max_val = 2 : i8, min_val = -4 : i8, nan_mode = IGNORE} : (tensor<4xi8>) -> tensor<4xi8>358 %0 = tosa.clamp %arg0 {max_val = 4 : i8, min_val = -2 : i8, nan_mode = PROPAGATE} : (tensor<4xi8>) -> tensor<4xi8>359 %1 = tosa.clamp %0 {max_val = 2 : i8, min_val = -4 : i8, nan_mode = IGNORE} : (tensor<4xi8>) -> tensor<4xi8>360 return %1 : tensor<4xi8>361}362 363// -----364 365// CHECK-LABEL: @clamp_twice_with_unsigned_quantized_is_single_clamp366// CHECK: tosa.clamp %arg0 {max_val = 230 : ui8, min_val = 10 : ui8}367func.func @clamp_twice_with_unsigned_quantized_is_single_clamp(%arg0:tensor<?x112x112x32x!quant.uniform<u8:f32, 0.023529412224888802:-128>>) -> (tensor<?x112x112x32x!quant.uniform<u8:f32, 0.023529412224888802:-128>>) {368 %0 = tosa.clamp %arg0 {max_val = 240 : ui8, min_val = 10 : ui8} : (tensor<?x112x112x32x!quant.uniform<u8:f32, 0.023529412224888802:-128>>) -> tensor<?x112x112x32x!quant.uniform<u8:f32, 0.023529412224888802:-128>>369 %1 = tosa.clamp %0 {max_val = 230 : ui8, min_val = 5 : ui8} : (tensor<?x112x112x32x!quant.uniform<u8:f32, 0.023529412224888802:-128>>) -> tensor<?x112x112x32x!quant.uniform<u8:f32, 0.023529412224888802:-128>>370 return %1 : tensor<?x112x112x32x!quant.uniform<u8:f32, 0.023529412224888802:-128>>371}372 373// -----374 375// CHECK-LABEL: @clamp_twice_with_signed_quantized_is_single_clamp376// CHECK: tosa.clamp %arg0 {max_val = 110 : i8, min_val = -5 : i8}377func.func @clamp_twice_with_signed_quantized_is_single_clamp(%arg0:tensor<?x112x112x32x!quant.uniform<i8:f32, 0.023529412224888802:-128>>) -> (tensor<?x112x112x32x!quant.uniform<i8:f32, 0.023529412224888802:-128>>) {378 %0 = tosa.clamp %arg0 {max_val = 110 : i8, min_val = -10 : i8} : (tensor<?x112x112x32x!quant.uniform<i8:f32, 0.023529412224888802:-128>>) -> tensor<?x112x112x32x!quant.uniform<i8:f32, 0.023529412224888802:-128>>379 %1 = tosa.clamp %0 {max_val = 120 : i8, min_val = -5 : i8} : (tensor<?x112x112x32x!quant.uniform<i8:f32, 0.023529412224888802:-128>>) -> tensor<?x112x112x32x!quant.uniform<i8:f32, 0.023529412224888802:-128>>380 return %1 : tensor<?x112x112x32x!quant.uniform<i8:f32, 0.023529412224888802:-128>>381}382 383// CHECK-LABEL: @clamp_twice_with_signed_quantized_non_overlap_is_not_single_clamp384// CHECK: %[[CLAMP_1:.*]] = tosa.clamp %arg0 {max_val = 50 : i8, min_val = -10 : i8}385// CHECK-NEXT: tosa.clamp %[[CLAMP_1]] {max_val = 120 : i8, min_val = 60 : i8}386func.func @clamp_twice_with_signed_quantized_non_overlap_is_not_single_clamp(%arg0:tensor<?x112x112x32x!quant.uniform<i8:f32, 0.023529412224888802:-128>>) -> (tensor<?x112x112x32x!quant.uniform<i8:f32, 0.023529412224888802:-128>>) {387 %0 = tosa.clamp %arg0 {max_val = 50 : i8, min_val = -10 : i8} : (tensor<?x112x112x32x!quant.uniform<i8:f32, 0.023529412224888802:-128>>) -> tensor<?x112x112x32x!quant.uniform<i8:f32, 0.023529412224888802:-128>>388 %1 = tosa.clamp %0 {max_val = 120 : i8, min_val = 60 : i8} : (tensor<?x112x112x32x!quant.uniform<i8:f32, 0.023529412224888802:-128>>) -> tensor<?x112x112x32x!quant.uniform<i8:f32, 0.023529412224888802:-128>>389 return %1 : tensor<?x112x112x32x!quant.uniform<i8:f32, 0.023529412224888802:-128>>390}391 392 393// -----394 395// CHECK-LABEL: @concat_fold396func.func @concat_fold(%arg0: tensor<?x1xf32>) -> tensor<?x1xf32> {397 // CHECK: return %arg0398 %0 = tosa.concat %arg0 {axis = 0 : i32}: (tensor<?x1xf32>) -> tensor<?x1xf32>399 return %0 : tensor<?x1xf32>400}401 402// -----403 404// CHECK-LABEL: @concat_fold_cast405func.func @concat_fold_cast(%arg0: tensor<?x1xf32>) -> tensor<?x?xf32> {406 // CHECK: %[[VAR0:.*]] = tensor.cast %arg0407 // CHECK: return %[[VAR0]]408 %0 = tosa.concat %arg0 {axis = 0 : i32}: (tensor<?x1xf32>) -> tensor<?x?xf32>409 return %0 : tensor<?x?xf32>410}411 412// -----413 414// CHECK-LABEL: @conv2d_stride_2415func.func @conv2d_stride_2(%arg0: tensor<4x11x11x2xf32>) -> tensor<4x6x6x3xf32> {416 // CHECK: tosa.conv2d417 %weight = "tosa.const"() {values = dense<[[[[1.0, 1.0]]], [[[1.0, 1.0]]], [[[1.0, 1.0]]]]> : tensor<3x1x1x2xf32>} : ()-> tensor<3x1x1x2xf32>418 %bias = "tosa.const"() {values = dense<0.0> : tensor<3xf32>} : ()-> tensor<3xf32>419 %input_zp = "tosa.const"() <{values = dense<0.0> : tensor<1xf32>}> : ()-> tensor<1xf32>420 %weight_zp = "tosa.const"() <{values = dense<0.0> : tensor<1xf32>}> : ()-> tensor<1xf32>421 %0 = tosa.conv2d %arg0, %weight, %bias, %input_zp, %weight_zp {acc_type = f32, pad = array<i64: 0, 0, 0, 0>, stride = array<i64: 2, 2>, dilation = array<i64: 1, 1>} : (tensor<4x11x11x2xf32>, tensor<3x1x1x2xf32>, tensor<3xf32>, tensor<1xf32>, tensor<1xf32>) -> tensor<4x6x6x3xf32>422 return %0 : tensor<4x6x6x3xf32>423}424 425// -----426 427// CHECK-LABEL: @conv2d_weight_2x2428func.func @conv2d_weight_2x2(%arg0: tensor<4x10x10x1xf32>) -> tensor<4x9x9x1xf32> {429 // CHECK: tosa.conv2d430 %weight = "tosa.const"() {values = dense<[[[[1.0], [1.0]], [[1.0], [1.0]]]]> : tensor<1x2x2x1xf32>} : ()-> tensor<1x2x2x1xf32>431 %bias = "tosa.const"() {values = dense<0.0> : tensor<1xf32>} : ()-> tensor<1xf32>432 %input_zp = "tosa.const"() <{values = dense<0.0> : tensor<1xf32>}> : ()-> tensor<1xf32>433 %weight_zp = "tosa.const"() <{values = dense<0.0> : tensor<1xf32>}> : ()-> tensor<1xf32>434 %0 = tosa.conv2d %arg0, %weight, %bias, %input_zp, %weight_zp {acc_type = f32, pad = array<i64: 0, 0, 0, 0>, stride = array<i64: 1, 1>, dilation = array<i64: 1, 1>} : (tensor<4x10x10x1xf32>, tensor<1x2x2x1xf32>, tensor<1xf32>, tensor<1xf32>, tensor<1xf32>) -> tensor<4x9x9x1xf32>435 return %0 : tensor<4x9x9x1xf32>436}437 438// -----439 440// CHECK-LABEL: @depthwise_conv2d_stride_2441func.func @depthwise_conv2d_stride_2(%arg0: tensor<4x11x11x2xf32>, %arg1: tensor<1x1x2x3xf32>, %arg2: tensor<6xf32>, %arg3: tensor<1xf32>, %arg4: tensor<1xf32>) -> tensor<4x6x6x6xf32> {442 // CHECK: tosa.depthwise_conv2d443 %0 = tosa.depthwise_conv2d %arg0, %arg1, %arg2, %arg3, %arg4 {acc_type = f32, pad = array<i64: 0, 0, 0, 0>, stride = array<i64: 2, 2>, dilation = array<i64: 1, 1>} : (tensor<4x11x11x2xf32>, tensor<1x1x2x3xf32>, tensor<6xf32>, tensor<1xf32>, tensor<1xf32>) -> tensor<4x6x6x6xf32>444 return %0 : tensor<4x6x6x6xf32>445}446 447// -----448 449// CHECK-LABEL: @depthwise_conv2d_weight_2x2450func.func @depthwise_conv2d_weight_2x2(%arg0: tensor<4x10x10x2xf32>, %arg1: tensor<2x2x2x3xf32>, %arg2: tensor<6xf32>, %arg3: tensor<1xf32>, %arg4: tensor<1xf32>) -> tensor<4x9x9x6xf32> {451 // CHECK: tosa.depthwise_conv2d452 %0 = tosa.depthwise_conv2d %arg0, %arg1, %arg2, %arg3, %arg4 {acc_type = f32, pad = array<i64: 0, 0, 0, 0>, stride = array<i64: 1, 1>, dilation = array<i64: 1, 1>} : (tensor<4x10x10x2xf32>, tensor<2x2x2x3xf32>, tensor<6xf32>, tensor<1xf32>, tensor<1xf32>) -> tensor<4x9x9x6xf32>453 return %0 : tensor<4x9x9x6xf32>454}455 456// -----457 458// CHECK-LABEL: @max_pool2d_is_noop459func.func @max_pool2d_is_noop(%arg0: tensor<10x1x1x3xf32>) -> tensor<10x1x1x3xf32> {460 // CHECK-NOT: tosa.max_pool2d461 // CHECK: return %arg0462 %0 = tosa.max_pool2d %arg0 {kernel = array<i64: 1, 1>, pad = array<i64: 0, 0, 0, 0>, stride = array<i64: 1, 1>, dilation = array<i64: 1, 1>} : (tensor<10x1x1x3xf32>) -> tensor<10x1x1x3xf32>463 return %0 : tensor<10x1x1x3xf32>464}465 466// -----467 468// CHECK-LABEL: @pad_noop469func.func @pad_noop(%arg0: tensor<?x?xf32>) -> tensor<?x?xf32> {470 // CHECK: return %arg0471 %0 = tosa.const_shape { values = dense<0> : tensor<4xindex>} : () -> !tosa.shape<4>472 %pad_const = "tosa.const"() {values = dense<3.14> : tensor<1xf32>} : () -> tensor<1xf32>473 %1 = tosa.pad %arg0, %0, %pad_const : (tensor<?x?xf32>, !tosa.shape<4>, tensor<1xf32>) -> tensor<?x?xf32>474 return %1 : tensor<?x?xf32>475}476 477// -----478 479// CHECK-LABEL: @pad_noop_padding_mismatch_nofold480func.func @pad_noop_padding_mismatch_nofold(%arg0: tensor<?x?xf32>) -> tensor<?x?xf32> {481 // CHECK: %[[PAD:.+]] = tosa.pad482 // CHECK: return %[[PAD]]483 %shape = tosa.const_shape { values = dense<[1, 0, 0, 1]> : tensor<4xindex>} : () -> !tosa.shape<4>484 %pad_const = "tosa.const"() {values = dense<3.14> : tensor<1xf32>} : () -> tensor<1xf32>485 %1 = tosa.pad %arg0, %shape, %pad_const : (tensor<?x?xf32>, !tosa.shape<4>, tensor<1xf32>) -> tensor<?x?xf32>486 return %1 : tensor<?x?xf32>487}488 489// -----490 491// CHECK-LABEL: @pad_noop_type_mismatch_nofold492func.func @pad_noop_type_mismatch_nofold(%arg0: tensor<10xf32>) -> tensor<?xf32> {493 // CHECK: %[[PAD:.+]] = tosa.pad494 // CHECK: return %[[PAD]]495 %shape = tosa.const_shape { values = dense<[1, 2]> : tensor<2xindex>} : () -> !tosa.shape<2>496 %pad_const = "tosa.const"() {values = dense<3.14> : tensor<1xf32>} : () -> tensor<1xf32>497 %0 = tosa.pad %arg0, %shape, %pad_const : (tensor<10xf32>, !tosa.shape<2>, tensor<1xf32>) -> tensor<?xf32>498 return %0 : tensor<?xf32>499}500 501// -----502 503// CHECK-LABEL: @pad_determine_val_i32504func.func @pad_determine_val_i32(%arg0: tensor<?x?xi32>, %arg1 : tensor<2x2xi32>) -> tensor<?x?xi32> {505 // CHECK-DAG: %[[ZERO:.+]] = "tosa.const"() <{values = dense<0> : tensor<1xi32>}506 // CHECK-DAG: %[[PADDING:.+]] = tosa.const_shape {values = dense<[1, 0, 0, 1]> : tensor<4xindex>} : () -> !tosa.shape<4>507 // CHECK: tosa.pad %arg0, %[[PADDING]], %[[ZERO]]508 %pad_const = "tosa.const"() {values = dense<0> : tensor<1xi32>} : () -> tensor<1xi32>509 %0 = tosa.const_shape { values = dense<[1, 0, 0, 1]> : tensor<4xindex>} : () -> !tosa.shape<4>510 %1 = tosa.pad %arg0, %0, %pad_const : (tensor<?x?xi32>, !tosa.shape<4>, tensor<1xi32>) -> tensor<?x?xi32>511 return %1 : tensor<?x?xi32>512}513 514// -----515 516// CHECK-LABEL: @pad_determine_val_f32517func.func @pad_determine_val_f32(%arg0: tensor<?x?xf32>, %arg1 : tensor<2x2xi32>) -> tensor<?x?xf32> {518 // CHECK-DAG: %[[ZERO:.+]] = "tosa.const"() <{values = dense<3.140000e+00> : tensor<1xf32>}519 // CHECK-DAG: %[[PADDING:.+]] = tosa.const_shape {values = dense<[1, 0, 0, 1]> : tensor<4xindex>} : () -> !tosa.shape<4>520 // CHECK: tosa.pad %arg0, %[[PADDING]], %[[ZERO]]521 %pad_const = "tosa.const"() {values = dense<3.14> : tensor<1xf32>} : () -> tensor<1xf32>522 %0 = tosa.const_shape { values = dense<[1, 0, 0, 1]> : tensor<4xindex>} : () -> !tosa.shape<4>523 %1 = tosa.pad %arg0, %0, %pad_const : (tensor<?x?xf32>, !tosa.shape<4>, tensor<1xf32>) -> tensor<?x?xf32>524 return %1 : tensor<?x?xf32>525}526 527// -----528 529// CHECK-LABEL: @pad_determine_val_quant530func.func @pad_determine_val_quant(%arg0: tensor<?x?xi32>, %arg1 : tensor<2x2xi32>) -> tensor<?x?xi32> {531 // CHECK-DAG: %[[ZERO:.+]] = "tosa.const"() <{values = dense<3> : tensor<1xi32>}532 // CHECK-DAG: %[[PADDING:.+]] = tosa.const_shape {values = dense<[1, 0, 0, 1]> : tensor<4xindex>} : () -> !tosa.shape<4>533 // CHECK: tosa.pad %arg0, %[[PADDING]], %[[ZERO]]534 %pad_const = "tosa.const"() {values =dense<3> : tensor<1xi32>} : () -> tensor<1xi32>535 %0 = tosa.const_shape { values = dense<[1, 0, 0, 1]> : tensor<4xindex>} : () -> !tosa.shape<4>536 %1 = tosa.pad %arg0, %0, %pad_const {input_zp = 42 : i32} : (tensor<?x?xi32>, !tosa.shape<4>, tensor<1xi32>) -> tensor<?x?xi32>537 return %1 : tensor<?x?xi32>538}539 540// -----541 542// CHECK-LABEL: @mul_one_float543func.func @mul_one_float(%arg0: tensor<2x3xf32>) -> tensor<2x3xf32> {544 // CHECK: return %arg0545 // CHECK-NOT: tosa.mul546 %shift = "tosa.const"() <{values = dense<0> : tensor<1xi8>}> : () -> tensor<1xi8>547 %ones = "tosa.const"() {values = dense<1.0> : tensor<2x3xf32>} : () -> tensor<2x3xf32>548 %1 = tosa.mul %arg0, %ones, %shift : (tensor<2x3xf32>, tensor<2x3xf32>, tensor<1xi8>) -> tensor<2x3xf32>549 return %1 : tensor<2x3xf32>550}551 552// -----553 554// CHECK-LABEL: @mul_bcast_one_float555func.func @mul_bcast_one_float(%arg0: tensor<2x3xf32>) -> tensor<2x3xf32> {556 // CHECK: return %arg0557 // CHECK-NOT: tosa.mul558 %ones = "tosa.const"() {values = dense<1.0> : tensor<1x1xf32>} : () -> tensor<1x1xf32>559 %shift = "tosa.const"() <{values = dense<0> : tensor<1xi8>}> : () -> tensor<1xi8>560 %1 = tosa.mul %ones, %arg0, %shift : (tensor<1x1xf32>, tensor<2x3xf32>, tensor<1xi8>) -> tensor<2x3xf32>561 return %1 : tensor<2x3xf32>562}563 564// -----565 566// CHECK-LABEL: @mul_one_int567func.func @mul_one_int(%arg0: tensor<2x3xi32>) -> tensor<2x3xi32> {568 // CHECK: return %arg0569 // CHECK-NOT: tosa.mul570 %shift = "tosa.const"() <{values = dense<0> : tensor<1xi8>}> : () -> tensor<1xi8>571 %ones = "tosa.const"() {values = dense<1> : tensor<2x3xi32>} : () -> tensor<2x3xi32>572 %1 = tosa.mul %arg0, %ones, %shift : (tensor<2x3xi32>, tensor<2x3xi32>, tensor<1xi8>) -> tensor<2x3xi32>573 return %1 : tensor<2x3xi32>574}575 576// -----577 578// CHECK-LABEL: @mul_one_int_and_shift579func.func @mul_one_int_and_shift(%arg0: tensor<2x3xi32>) -> tensor<2x3xi32> {580 // CHECK-DAG: %[[VAL_1:.*]] = "tosa.const"() <{values = dense<1> : tensor<2x3xi32>}>581 // CHECK-DAG: %[[VAL_2:.*]] = "tosa.const"() <{values = dense<31> : tensor<1xi8>}>582 // CHECK: %[[VAL_3:.*]] = tosa.mul %arg0, %[[VAL_1]], %[[VAL_2]] : (tensor<2x3xi32>, tensor<2x3xi32>, tensor<1xi8>)583 %ones = "tosa.const"() {values = dense<1> : tensor<2x3xi32>} : () -> tensor<2x3xi32>584 %shift = "tosa.const"() <{values = dense<31> : tensor<1xi8>}> : () -> tensor<1xi8>585 %1 = tosa.mul %arg0, %ones, %shift : (tensor<2x3xi32>, tensor<2x3xi32>, tensor<1xi8>) -> tensor<2x3xi32>586 return %1 : tensor<2x3xi32>587}588 589// -----590 591// CHECK-LABEL: @mul_zero_broadcast592func.func @mul_zero_broadcast(%arg0: tensor<2x3xf32>) -> (tensor<2x3xf32>, tensor<2x3xf32>) {593 // CHECK: %[[ZERO:.*]] = "tosa.const"() <{values = dense<0.000000e+00> : tensor<2x3xf32>}594 // CHECK-NOT: tosa.mul595 %zeros = "tosa.const"() {values = dense<0.0> : tensor<1x1xf32>} : () -> tensor<1x1xf32>596 %shift = "tosa.const"() <{values = dense<0> : tensor<1xi8>}> : () -> tensor<1xi8>597 %1 = tosa.mul %arg0, %zeros, %shift : (tensor<2x3xf32>, tensor<1x1xf32>, tensor<1xi8>) -> tensor<2x3xf32>598 599 // CHECK-NOT: tosa.mul600 // CHECK: return %[[ZERO]], %[[ZERO]]601 %2 = tosa.mul %zeros, %arg0, %shift : (tensor<1x1xf32>, tensor<2x3xf32>, tensor<1xi8>) -> tensor<2x3xf32>602 return %1, %2 : tensor<2x3xf32>, tensor<2x3xf32>603}604 605// -----606 607// CHECK-LABEL: @mul_zero_dynamic_nofold608// CHECK-SAME: %[[ARG0:.*]]: tensor<?x17xf32>) -> tensor<?x17xf32> {609// CHECK: %[[ZERO:.*]] = "tosa.const"() <{values = dense<0.000000e+00> : tensor<1x1xf32>}> : () -> tensor<1x1xf32>610// CHECK: %[[SHIFT:.*]] = "tosa.const"() <{values = dense<0> : tensor<1xi8>}> : () -> tensor<1xi8>611// CHECK: %[[MUL:.*]] = tosa.mul %[[ARG0]], %[[ZERO]], %[[SHIFT]] : (tensor<?x17xf32>, tensor<1x1xf32>, tensor<1xi8>) -> tensor<?x17xf32>612// CHECK: return %[[MUL]]613func.func @mul_zero_dynamic_nofold(%arg0: tensor<?x17xf32>) -> tensor<?x17xf32> {614 %0 = "tosa.const"() <{values = dense<0.000000e+00> : tensor<1x1xf32>}> : () -> tensor<1x1xf32>615 %1 = "tosa.const"() <{values = dense<0> : tensor<1xi8>}> : () -> tensor<1xi8>616 %2 = tosa.mul %arg0, %0, %1 : (tensor<?x17xf32>, tensor<1x1xf32>, tensor<1xi8>) -> tensor<?x17xf32>617 return %2 : tensor<?x17xf32>618}619 620// -----621 622// CHECK-LABEL: @mul_one_dynamic_fold623// CHECK-SAME: %[[ARG0:.*]]: tensor<?x17xf32>) -> tensor<?x17xf32> {624// CHECK: return %[[ARG0]]625func.func @mul_one_dynamic_fold(%arg0: tensor<?x17xf32>) -> tensor<?x17xf32> {626 %0 = "tosa.const"() <{values = dense<1.000000e+00> : tensor<1x1xf32>}> : () -> tensor<1x1xf32>627 %1 = "tosa.const"() <{values = dense<0> : tensor<1xi8>}> : () -> tensor<1xi8>628 %2 = tosa.mul %arg0, %0, %1 : (tensor<?x17xf32>, tensor<1x1xf32>, tensor<1xi8>) -> tensor<?x17xf32>629 return %2 : tensor<?x17xf32>630}631 632// -----633 634// CHECK-LABEL: @select_same_value635func.func @select_same_value(%arg0: tensor<2x3xi1>, %arg1: tensor<2x3xi32>) -> tensor<2x3xi32> {636 %0 = tosa.select %arg0, %arg1, %arg1 : (tensor<2x3xi1>, tensor<2x3xi32>, tensor<2x3xi32>) -> tensor<2x3xi32>637 // CHECK: return %arg1638 // CHECK-NOT: tosa.select639 return %0 : tensor<2x3xi32>640}641 642// -----643 644// CHECK-LABEL: @select_true_value645func.func @select_true_value(%arg0: tensor<2x3xi32>, %arg1: tensor<2x3xi32>) -> tensor<2x3xi32> {646 %c1 = "tosa.const"() {values = dense<1> : tensor<2x3xi1>} : () -> tensor<2x3xi1>647 %0 = tosa.select %c1, %arg0, %arg1 : (tensor<2x3xi1>, tensor<2x3xi32>, tensor<2x3xi32>) -> tensor<2x3xi32>648 // CHECK: return %arg0649 // CHECK-NOT: tosa.select650 return %0 : tensor<2x3xi32>651}652 653// -----654 655// CHECK-LABEL: @select_false_value656func.func @select_false_value(%arg0: tensor<2x3xi32>, %arg1: tensor<2x3xi32>) -> tensor<2x3xi32> {657 %c0 = "tosa.const"() {values = dense<0> : tensor<2x3xi1>} : () -> tensor<2x3xi1>658 %0 = tosa.select %c0, %arg0, %arg1 : (tensor<2x3xi1>, tensor<2x3xi32>, tensor<2x3xi32>) -> tensor<2x3xi32>659 // CHECK: return %arg1660 // CHECK-NOT: tosa.select661 return %0 : tensor<2x3xi32>662}663 664// -----665 666// CHECK-LABEL: @select_not_pred667func.func @select_not_pred(%arg0: tensor<2x3xi1>, %arg1: tensor<2x3xi32>, %arg2: tensor<2x3xi32>) -> tensor<2x3xi32> {668 %0 = tosa.logical_not %arg0 : (tensor<2x3xi1>) -> tensor<2x3xi1>669 %1 = tosa.select %0, %arg1, %arg2 : (tensor<2x3xi1>, tensor<2x3xi32>, tensor<2x3xi32>) -> tensor<2x3xi32>670 // CHECK: tosa.select %arg0, %arg2, %arg1671 return %1 : tensor<2x3xi32>672}673 674// -----675 676// CHECK-LABEL: @select_broadcast_same_value_no_fold677func.func @select_broadcast_same_value_no_fold(%arg0: tensor<2x2xi1>, %arg1: tensor<1x1xf32>) -> tensor<2x2xf32> {678 // CHECK: tosa.select %arg0, %arg1, %arg1679 %0 = tosa.select %arg0, %arg1, %arg1 : (tensor<2x2xi1>, tensor<1x1xf32>, tensor<1x1xf32>) -> tensor<2x2xf32>680 return %0 : tensor<2x2xf32>681}682 683// -----684 685// CHECK-LABEL: @select_broadcast_true_value_no_fold686func.func @select_broadcast_true_value_no_fold(%arg0: tensor<1x1xf32>, %arg1: tensor<2x2xf32>) -> tensor<?x?xf32> {687 // CHECK: %[[CONST:.*]] = "tosa.const"688 %0 = "tosa.const"() {values = dense<1> : tensor<2x2xi1>} : () -> tensor<2x2xi1>689 // CHECK: tosa.select %[[CONST]], %arg0, %arg1690 %1 = tosa.select %0, %arg0, %arg1 : (tensor<2x2xi1>, tensor<1x1xf32>, tensor<2x2xf32>) -> tensor<?x?xf32>691 return %1 : tensor<?x?xf32>692}693 694// -----695 696// CHECK-LABEL: @select_broadcast_false_value_no_fold697func.func @select_broadcast_false_value_no_fold(%arg0: tensor<2x2xf32>, %arg1: tensor<1x1xf32>) -> tensor<2x2xf32> {698 // CHECK: %[[CONST:.*]] = "tosa.const"699 %0 = "tosa.const"() {values = dense<0> : tensor<2x2xi1>} : () -> tensor<2x2xi1>700 // CHECK: tosa.select %[[CONST]], %arg0, %arg1701 %1 = tosa.select %0, %arg0, %arg1 : (tensor<2x2xi1>, tensor<2x2xf32>, tensor<1x1xf32>) -> tensor<2x2xf32>702 return %1 : tensor<2x2xf32>703}704 705// -----706 707// CHECK-LABEL: @select_broadcast_false_value_dynamic_operand_no_fold708func.func @select_broadcast_false_value_dynamic_operand_no_fold(%arg0: tensor<2x?xf32>, %arg1: tensor<2x2xf32>) -> tensor<2x2xf32> {709 // CHECK: %[[CONST:.*]] = "tosa.const"710 %0 = "tosa.const"() {values = dense<0> : tensor<2x2xi1>} : () -> tensor<2x2xi1>711 // CHECK: tosa.select %[[CONST]], %arg0, %arg1712 %1 = tosa.select %0, %arg0, %arg1 : (tensor<2x2xi1>, tensor<2x?xf32>, tensor<2x2xf32>) -> tensor<2x2xf32>713 return %1 : tensor<2x2xf32>714}715 716// -----717 718// CHECK-LABEL: @reduce_all_fold719func.func @reduce_all_fold(%arg0: tensor<?x1xf32>) -> tensor<?x1xf32> {720 // CHECK: return %arg0721 %0 = tosa.reduce_all %arg0 {axis = 1 : i32}: (tensor<?x1xf32>) -> tensor<?x1xf32>722 return %0 : tensor<?x1xf32>723}724 725// -----726 727// CHECK-LABEL: @reduce_all_nofold728func.func @reduce_all_nofold(%arg0: tensor<?x1xf32>) -> tensor<?x1xf32> {729 // CHECK: tosa.reduce_all730 %0 = tosa.reduce_all %arg0 {axis = 0 : i32}: (tensor<?x1xf32>) -> tensor<?x1xf32>731 return %0 : tensor<?x1xf32>732}733 734// -----735 736// CHECK-LABEL: @reduce_any_fold737func.func @reduce_any_fold(%arg0: tensor<?x1xf32>) -> tensor<?x1xf32> {738 // CHECK: return %arg0739 %0 = tosa.reduce_any %arg0 {axis = 1 : i32}: (tensor<?x1xf32>) -> tensor<?x1xf32>740 return %0 : tensor<?x1xf32>741}742 743// -----744 745// CHECK-LABEL: @reduce_any_nofold746func.func @reduce_any_nofold(%arg0: tensor<?x1xf32>) -> tensor<?x1xf32> {747 // CHECK: tosa.reduce_any748 %0 = tosa.reduce_any %arg0 {axis = 0 : i32}: (tensor<?x1xf32>) -> tensor<?x1xf32>749 return %0 : tensor<?x1xf32>750}751 752// -----753 754// CHECK-LABEL: @reduce_max_fold755func.func @reduce_max_fold(%arg0: tensor<?x1xf32>) -> tensor<?x1xf32> {756 // CHECK: return %arg0757 %0 = tosa.reduce_max %arg0 {axis = 1 : i32}: (tensor<?x1xf32>) -> tensor<?x1xf32>758 return %0 : tensor<?x1xf32>759}760 761// -----762 763// CHECK-LABEL: @reduce_max_nofold764func.func @reduce_max_nofold(%arg0: tensor<?x1xf32>) -> tensor<?x1xf32> {765 // CHECK: tosa.reduce_max766 %0 = tosa.reduce_max %arg0 {axis = 0 : i32}: (tensor<?x1xf32>) -> tensor<?x1xf32>767 return %0 : tensor<?x1xf32>768}769 770// -----771 772// CHECK-LABEL: @reduce_min_fold773func.func @reduce_min_fold(%arg0: tensor<?x1xf32>) -> tensor<?x1xf32> {774 // CHECK: return %arg0775 %0 = tosa.reduce_min %arg0 {axis = 1 : i32}: (tensor<?x1xf32>) -> tensor<?x1xf32>776 return %0 : tensor<?x1xf32>777}778 779// -----780 781// CHECK-LABEL: @reduce_min_nofold782func.func @reduce_min_nofold(%arg0: tensor<?x1xf32>) -> tensor<?x1xf32> {783 // CHECK: tosa.reduce_min784 %0 = tosa.reduce_min %arg0 {axis = 0 : i32}: (tensor<?x1xf32>) -> tensor<?x1xf32>785 return %0 : tensor<?x1xf32>786}787 788// -----789 790// CHECK-LABEL: @reduce_product_fold791func.func @reduce_product_fold(%arg0: tensor<?x1xf32>) -> tensor<?x1xf32> {792 // CHECK: return %arg0793 %0 = tosa.reduce_product %arg0 {axis = 1 : i32}: (tensor<?x1xf32>) -> tensor<?x1xf32>794 return %0 : tensor<?x1xf32>795}796 797// -----798 799// CHECK-LABEL: @reduce_product_nofold800func.func @reduce_product_nofold(%arg0: tensor<?x1xf32>) -> tensor<?x1xf32> {801 // CHECK: tosa.reduce_product802 %0 = tosa.reduce_product %arg0 {axis = 0 : i32}: (tensor<?x1xf32>) -> tensor<?x1xf32>803 return %0 : tensor<?x1xf32>804}805 806// -----807 808// CHECK-LABEL: @reduce_sum_fold809func.func @reduce_sum_fold(%arg0: tensor<?x1xf32>) -> tensor<?x1xf32> {810 // CHECK: return %arg0811 %0 = tosa.reduce_sum %arg0 {axis = 1 : i32}: (tensor<?x1xf32>) -> tensor<?x1xf32>812 return %0 : tensor<?x1xf32>813}814 815// -----816 817// CHECK-LABEL: @reduce_sum_nofold818func.func @reduce_sum_nofold(%arg0: tensor<?x1xf32>) -> tensor<?x1xf32> {819 // CHECK: tosa.reduce_sum820 %0 = tosa.reduce_sum %arg0 {axis = 0 : i32}: (tensor<?x1xf32>) -> tensor<?x1xf32>821 return %0 : tensor<?x1xf32>822}823 824// -----825 826// CHECK-LABEL: @reshape_canonicalize827func.func @reshape_canonicalize(%arg0: tensor<?x10xf32>) -> tensor<?x10xf32> {828 // CHECK: return %arg0829 %0 = "tosa.const_shape"() {values = dense<[-1, 10]> : tensor<2xindex>} : () -> !tosa.shape<2>830 %1 = tosa.reshape %arg0, %0 : (tensor<?x10xf32>, !tosa.shape<2>) -> tensor<?x10xf32>831 return %1 : tensor<?x10xf32>832}833 834// -----835 836// CHECK-LABEL: @reshape_canonicalize_dyn_nofold837func.func @reshape_canonicalize_dyn_nofold(%arg0: tensor<?x?x10xf32>) -> tensor<?x?x10xf32> {838 // CHECK: %[[SHAPE:.+]] = tosa.const_shape {values = dense<[-1, 2, 10]> : tensor<3xindex>} : () -> !tosa.shape<3>839 // CHECK: %[[VAR0:.+]] = tosa.reshape %arg0, %[[SHAPE]] : (tensor<?x?x10xf32>, !tosa.shape<3>) -> tensor<?x?x10xf32>840 // CHECK: return %[[VAR0]] : tensor<?x?x10xf32>841 %s = "tosa.const_shape"() {values = dense<[-1, 2, 10]> : tensor<3xindex>} : () -> !tosa.shape<3>842 %0 = tosa.reshape %arg0, %s : (tensor<?x?x10xf32>, !tosa.shape<3>) -> tensor<?x?x10xf32>843 return %0 : tensor<?x?x10xf32>844}845 846// -----847 848// CHECK-LABEL: @reshape_canonicalize_double849func.func @reshape_canonicalize_double(%arg0: tensor<?x10xf32>) -> tensor<?x5xf32> {850 // CHECK: %[[VAL_0:.*]] = tosa.const_shape {values = dense<[-1, 5]> : tensor<2xindex>} : () -> !tosa.shape<2>851 // CHECK: %[[VAL_1:.*]] = tosa.reshape %arg0, %[[VAL_0]]852 // CHECK: return %[[VAL_1]]853 %cst0 = "tosa.const_shape"() <{values = dense<[5, -1]> : tensor<2xindex>}> : () -> !tosa.shape<2>854 %0 = tosa.reshape %arg0, %cst0 : (tensor<?x10xf32>, !tosa.shape<2>) -> tensor<5x?xf32>855 %cst1 = "tosa.const_shape"() <{values = dense<[-1, 5]> : tensor<2xindex>}> : () -> !tosa.shape<2>856 %1 = tosa.reshape %0, %cst1 : (tensor<5x?xf32>, !tosa.shape<2>) -> tensor<?x5xf32>857 return %1 : tensor<?x5xf32>858}859 860// -----861 862// CHECK-LABEL: @reshape_canonicalize_const863func.func @reshape_canonicalize_const() -> tensor<1x5xi32> {864 // CHECK: %[[VAR0:.+]] = "tosa.const"() <{values = dense<{{\[\[}}0, 1, 2, 3, 4]]> : tensor<1x5xi32>}865 // CHECK: return %[[VAR0]]866 %0 = "tosa.const"() {values = dense<[0, 1, 2, 3, 4]> : tensor<5xi32>} : () -> tensor<5xi32>867 %1 = "tosa.const_shape"() {values = dense<[1, 5]> : tensor<2xindex>} : () -> !tosa.shape<2>868 %2 = tosa.reshape %0, %1 : (tensor<5xi32>, !tosa.shape<2>) -> tensor<1x5xi32>869 return %2 : tensor<1x5xi32>870}871 872// -----873 874// CHECK-LABEL: @reshape_canonicalize_const_dynamic875func.func @reshape_canonicalize_const_dynamic() -> tensor<1x?xi32> {876 // CHECK: tosa.reshape877 %0 = "tosa.const"() {values = dense<[0, 1, 2, 3, 4]> : tensor<5xi32>} : () -> tensor<5xi32>878 %2 = "tosa.const_shape"() {values = dense<[1, 5]> : tensor<2xindex>} : () -> !tosa.shape<2>879 %1 = tosa.reshape %0, %2 : (tensor<5xi32>, !tosa.shape<2>) -> tensor<1x?xi32>880 return %1 : tensor<1x?xi32>881}882 883// -----884 885// CHECK-LABEL: @reshape_canonicalize_const_splat886func.func @reshape_canonicalize_const_splat() -> (tensor<10xi32>, tensor<1x10xi32>) {887 // CHECK-DAG: %[[VAR0:.+]] = "tosa.const"() <{values = dense<0> : tensor<10xi32>}888 // CHECK-DAG: %[[VAR1:.+]] = "tosa.const"() <{values = dense<0> : tensor<1x10xi32>}889 // CHECK: return %[[VAR0]], %[[VAR1]]890 %0 = "tosa.const"() {values = dense<0> : tensor<10xi32>} : () -> tensor<10xi32>891 %2 = "tosa.const_shape"() {values = dense<[1, 10]> : tensor<2xindex>} : () -> !tosa.shape<2>892 %1 = tosa.reshape %0, %2 : (tensor<10xi32>, !tosa.shape<2>) -> tensor<1x10xi32>893 return %0 , %1 : tensor<10xi32>, tensor<1x10xi32>894}895 896// -----897 898// CHECK-LABEL: @reshape_canonicalize_const_sparse899func.func @reshape_canonicalize_const_sparse() -> (tensor<3xi32>, tensor<1x3xi32>) {900 // CHECK: tosa.reshape901 %0 = "tosa.const"() {values = dense<[1, 2, 3]> : tensor<3xi32>} : ()-> tensor<3xi32>902 %2 = "tosa.const_shape"() {values = dense<[1, 3]> : tensor<2xindex>} : () -> !tosa.shape<2>903 %1 = tosa.reshape %0, %2 : (tensor<3xi32>, !tosa.shape<2>) -> tensor<1x3xi32>904 return %0 , %1 : tensor<3xi32>, tensor<1x3xi32>905}906 907// -----908 909// CHECK-LABEL: @reshape_canonicalize_quant_nofold910func.func @reshape_canonicalize_quant_nofold() -> (tensor<1x3x!quant.uniform<i8:f32, 1.000000e+00>>) {911 // disabled folding for quantized element types912 // CHECK{LITERAL}: "tosa.const"() <{values = dense<[1, 2, 3]> : tensor<3xi8>}> : () -> tensor<3x!quant.uniform<i8:f32, 1.000000e+00>>913 // CHECK{LITERAL}: tosa.reshape %0, %1 : (tensor<3x!quant.uniform<i8:f32, 1.000000e+00>>, !tosa.shape<2>) -> tensor<1x3x!quant.uniform<i8:f32, 1.000000e+00>>914 %0 = "tosa.const"() {values = dense<[1, 2, 3]> : tensor<3xi8>} : ()-> tensor<3x!quant.uniform<i8:f32, 1.000000e+00>>915 %2 = "tosa.const_shape"() {values = dense<[1, 3]> : tensor<2xindex>} : () -> !tosa.shape<2>916 %1 = tosa.reshape %0, %2 : (tensor<3x!quant.uniform<i8:f32, 1.000000e+00>>, !tosa.shape<2>) -> tensor<1x3x!quant.uniform<i8:f32, 1.000000e+00>>917 return %1 : tensor<1x3x!quant.uniform<i8:f32, 1.000000e+00>>918}919 920// -----921 922// CHECK-LABEL: @transpose_canonicalize_strip_quant923func.func @transpose_canonicalize_strip_quant() -> (tensor<2x1x3x!quant.uniform<i8:f32, 1.000000e+00>>) {924 // CHECK-DAG: %[[SHAPE:.*]] = tosa.const_shape {values = dense<[2, 1, 3]> : tensor<3xindex>} : () -> !tosa.shape<3>925 // CHECK-DAG: %[[CONST:.*]] = "tosa.const"() <{values = dense<0> : tensor<1x2x3xi8>}> : () -> tensor<1x2x3x!quant.uniform<i8:f32, 1.000000e+00>>926 // CHECK: tosa.reshape %[[CONST]], %[[SHAPE]] : (tensor<1x2x3x!quant.uniform<i8:f32, 1.000000e+00>>, !tosa.shape<3>) -> tensor<2x1x3x!quant.uniform<i8:f32, 1.000000e+00>>927 %0 = "tosa.const"() {values = dense<0> : tensor<1x2x3xi8>} : ()-> tensor<1x2x3x!quant.uniform<i8:f32, 1.000000e+00>>928 %1 = tosa.transpose %0 { perms = array<i32: 1, 0, 2> }: (tensor<1x2x3x!quant.uniform<i8:f32, 1.000000e+00>>) -> tensor<2x1x3x!quant.uniform<i8:f32, 1.000000e+00>>929 return %1 : tensor<2x1x3x!quant.uniform<i8:f32, 1.000000e+00>>930}931 932// -----933 934// CHECK-LABEL: @slice_fold935func.func @slice_fold(%arg0: tensor<3x4xf32>) -> tensor<3x4xf32> {936 %0 = tosa.const_shape {values = dense<[0, 0]> : tensor<2xindex>} : () -> !tosa.shape<2>937 %1 = tosa.const_shape {values = dense<[3, 4]> : tensor<2xindex>} : () -> !tosa.shape<2>938 // CHECK: return %arg0939 %3 = tosa.slice %arg0, %0, %1 : (tensor<3x4xf32>, !tosa.shape<2>, !tosa.shape<2>) -> tensor<3x4xf32>940 return %3 : tensor<3x4xf32>941}942 943// -----944 945// CHECK-LABEL: @slice_nofold946func.func @slice_nofold(%arg0: tensor<?x4xf32>) -> tensor<?x4xf32> {947 %0 = tosa.const_shape {values = dense<[0, 0]> : tensor<2xindex>} : () -> !tosa.shape<2>948 %1 = tosa.const_shape {values = dense<[3, 4]> : tensor<2xindex>} : () -> !tosa.shape<2>949 // CHECK: tosa.slice950 %3 = tosa.slice %arg0, %0, %1 : (tensor<?x4xf32>, !tosa.shape<2>, !tosa.shape<2>) -> tensor<?x4xf32>951 return %3 : tensor<?x4xf32>952}953 954// -----955 956// CHECK-LABEL: @tile_fold957func.func @tile_fold(%arg0: tensor<3x4xf32>) -> tensor<3x4xf32> {958 // CHECK: return %arg0959 %cst = tosa.const_shape { values = dense<1> : tensor<2xindex> } : () -> !tosa.shape<2>960 %0 = tosa.tile %arg0, %cst: (tensor<3x4xf32>, !tosa.shape<2>) -> tensor<3x4xf32>961 return %0 : tensor<3x4xf32>962}963 964// -----965 966// CHECK-LABEL: @tile_nofold967func.func @tile_nofold(%arg0: tensor<3x4xf32>) -> tensor<3x8xf32> {968 // CHECK: tosa.tile969 %cst = tosa.const_shape { values = dense<[1, 2]> : tensor<2xindex> } : () -> !tosa.shape<2>970 %0 = tosa.tile %arg0, %cst: (tensor<3x4xf32>, !tosa.shape<2>) -> tensor<3x8xf32>971 return %0 : tensor<3x8xf32>972}973 974// -----975 976// CHECK-LABEL: @transpose_no_op977func.func @transpose_no_op(%arg0: tensor<3x4x5x6xf32>) -> tensor<3x4x5x6xf32> {978 // CHECK: return %arg0979 // CHECK-NOT: tosa.transpose980 %1 = tosa.transpose %arg0 { perms = array<i32: 0, 1, 2, 3> }: (tensor<3x4x5x6xf32>) -> tensor<3x4x5x6xf32>981 return %1 : tensor<3x4x5x6xf32>982}983 984// -----985 986// CHECK-LABEL: @transpose_is_reshape987func.func @transpose_is_reshape(%arg0: tensor<1x4x5x1xf32>) -> tensor<1x4x1x5xf32> {988 // CHECK: %[[CONST0:.+]] = tosa.const_shape {values = dense<[1, 4, 1, 5]> : tensor<4xindex>} : () -> !tosa.shape<4>989 // CHECK: tosa.reshape %arg0, %[[CONST0]]990 %0 = tosa.transpose %arg0 { perms = array<i32: 3, 1, 0, 2> }: (tensor<1x4x5x1xf32>) -> tensor<1x4x1x5xf32>991 return %0 : tensor<1x4x1x5xf32>992}993 994// -----995 996// CHECK-LABEL: @transpose_is_reshape_unknown_dim997func.func @transpose_is_reshape_unknown_dim(%arg0: tensor<1x4x?x1xf32>) -> tensor<1x4x1x?xf32> {998 // CHECK: %[[CONST0:.+]] = tosa.const_shape {values = dense<[1, 4, 1, -1]> : tensor<4xindex>} : () -> !tosa.shape<4>999 // CHECK: tosa.reshape %arg0, %[[CONST0]]1000 %0 = tosa.transpose %arg0 { perms = array<i32: 3, 1, 0, 2> }: (tensor<1x4x?x1xf32>) -> tensor<1x4x1x?xf32>1001 return %0 : tensor<1x4x1x?xf32>1002}1003 1004// -----1005 1006// CHECK-LABEL: @single_bit_reshape1007// https://github.com/llvm/llvm-project/issues/554401008func.func @single_bit_reshape() -> tensor<1xi1> {1009 // CHECK: "tosa.const"() <{values = dense<true> : tensor<1xi1>}1010 %0 = arith.constant dense<true> : tensor<1x1xi1>1011 %2 = "tosa.const_shape"() <{values = dense<1> : tensor<1xindex>}> : () -> !tosa.shape<1>1012 %1 = tosa.reshape %0, %2 : (tensor<1x1xi1>, !tosa.shape<1>) -> tensor<1xi1>1013 return %1 : tensor<1xi1>1014}1015 1016// -----1017 1018// CHECK-LABEL: @fold_resize_nearest1019func.func @fold_resize_nearest(%arg0 : tensor<1x15x13x1xi8>) -> tensor<1x15x13x1xi8> {1020 // CHECK: return %arg01021 %scale = tosa.const_shape { values = dense<[2, 2, 1, 1]> : tensor<4xindex> } : () -> !tosa.shape<4>1022 %offset = tosa.const_shape { values = dense<0> : tensor<2xindex> } : () -> !tosa.shape<2>1023 %border = tosa.const_shape { values = dense<0> : tensor<2xindex> } : () -> !tosa.shape<2>1024 %resize = tosa.resize %arg0, %scale, %offset, %border {mode = NEAREST_NEIGHBOR} : (tensor<1x15x13x1xi8>, !tosa.shape<4>, !tosa.shape<2>, !tosa.shape<2>) -> tensor<1x15x13x1xi8>1025 return %resize : tensor<1x15x13x1xi8>1026}1027 1028// -----1029 1030// CHECK-LABEL: @fold_resize_bilinear1031func.func @fold_resize_bilinear(%arg0 : tensor<1x15x13x1xi8>) -> tensor<1x15x13x1xi8> {1032 // CHECK: return %arg01033 %scale = tosa.const_shape { values = dense<[2, 2, 1, 1]> : tensor<4xindex> } : () -> !tosa.shape<4>1034 %offset = tosa.const_shape { values = dense<0> : tensor<2xindex> } : () -> !tosa.shape<2>1035 %border = tosa.const_shape { values = dense<0> : tensor<2xindex> } : () -> !tosa.shape<2>1036 %resize = tosa.resize %arg0, %scale, %offset, %border {mode = NEAREST_NEIGHBOR} : (tensor<1x15x13x1xi8>, !tosa.shape<4>, !tosa.shape<2>, !tosa.shape<2>) -> tensor<1x15x13x1xi8>1037 return %resize : tensor<1x15x13x1xi8>1038}1039 1040// -----1041 1042// CHECK-LABEL: @canonicalize_concat_slice_final_axis1043// CHECK-SAME: %[[VAL_0:.*]]: tensor<1x12x12x1xf32>, %[[VAL_1:.*]]: tensor<1x12x12x1xf32>1044// CHECK: return %[[VAL_0]], %[[VAL_1]] : tensor<1x12x12x1xf32>, tensor<1x12x12x1xf32>1045func.func @canonicalize_concat_slice_final_axis(%arg0 : tensor<1x12x12x1xf32>, %arg1 : tensor<1x12x12x1xf32>) -> (tensor<1x12x12x1xf32>, tensor<1x12x12x1xf32>) {1046 %0 = tosa.concat %arg0, %arg1 {axis = 3 : i32} : (tensor<1x12x12x1xf32>, tensor<1x12x12x1xf32>) -> tensor<1x12x12x2xf32>1047 %1 = tosa.const_shape {values = dense<[0, 0, 0, 0]> : tensor<4xindex>} : () -> !tosa.shape<4>1048 %2 = tosa.const_shape {values = dense<[0, 0, 0, 1]> : tensor<4xindex>} : () -> !tosa.shape<4>1049 %3 = tosa.const_shape {values = dense<[1, 12, 12, 1]> : tensor<4xindex>} : () -> !tosa.shape<4>1050 %4 = tosa.slice %0, %1, %3 : (tensor<1x12x12x2xf32>, !tosa.shape<4>, !tosa.shape<4>) -> tensor<1x12x12x1xf32>1051 %5 = tosa.slice %0, %2, %3 : (tensor<1x12x12x2xf32>, !tosa.shape<4>, !tosa.shape<4>) -> tensor<1x12x12x1xf32>1052 return %4, %5 : tensor<1x12x12x1xf32>, tensor<1x12x12x1xf32>1053}1054 1055// -----1056 1057// CHECK-LABEL: @canonicalize_concat_slice_middle_axis1058// CHECK-SAME: %[[VAL_0:.*]]: tensor<1x12x12xf32>, %[[VAL_1:.*]]: tensor<1x12x12xf32>1059// CHECK: return %[[VAL_0]], %[[VAL_1]] : tensor<1x12x12xf32>, tensor<1x12x12xf32>1060func.func @canonicalize_concat_slice_middle_axis(%arg0 : tensor<1x12x12xf32>, %arg1 : tensor<1x12x12xf32>) -> (tensor<1x12x12xf32>, tensor<1x12x12xf32>) {1061 %0 = tosa.concat %arg0, %arg1 {axis = 1 : i32} : (tensor<1x12x12xf32>, tensor<1x12x12xf32>) -> tensor<1x24x12xf32>1062 %1 = tosa.const_shape {values = dense<[0, 0, 0]> : tensor<3xindex>} : () -> !tosa.shape<3>1063 %2 = tosa.const_shape {values = dense<[0, 12, 0]> : tensor<3xindex>} : () -> !tosa.shape<3>1064 %3 = tosa.const_shape {values = dense<[1, 12, 12]> : tensor<3xindex>} : () -> !tosa.shape<3>1065 %4 = tosa.slice %0, %1, %3 : (tensor<1x24x12xf32>, !tosa.shape<3>, !tosa.shape<3>) -> tensor<1x12x12xf32>1066 %5 = tosa.slice %0, %2, %3 : (tensor<1x24x12xf32>, !tosa.shape<3>, !tosa.shape<3>) -> tensor<1x12x12xf32>1067 return %4, %5 : tensor<1x12x12xf32>, tensor<1x12x12xf32>1068}1069 1070// -----1071 1072// CHECK-LABEL: @canonicalize_cross_concat_inputs1073// CHECK-SAME: %[[VAL_0:.*]]: tensor<1x12x12xf32>, %[[VAL_1:.*]]: tensor<1x12x12xf32>1074// CHECK-DAG: %[[VAL_2:.*]] = tosa.const_shape {values = dense<[1, 12, 20]> : tensor<3xindex>}1075// CHECK-DAG: %[[VAL_3:.*]] = tosa.const_shape {values = dense<[1, 12, 15]> : tensor<3xindex>}1076// CHECK-DAG: %[[VAL_4:.*]] = tosa.const_shape {values = dense<[0, 0, 4]> : tensor<3xindex>}1077// CHECK-DAG: %[[VAL_5:.*]] = tosa.const_shape {values = dense<0> : tensor<3xindex>}1078// CHECK: %[[VAL_6:.*]] = tosa.concat %[[VAL_0]], %[[VAL_1]] {axis = 2 : i32} : (tensor<1x12x12xf32>, tensor<1x12x12xf32>) -> tensor<1x12x24xf32>1079// CHECK: %[[VAL_7:.*]] = tosa.slice %[[VAL_6]], %[[VAL_5]], %[[VAL_3]]1080// CHECK: %[[VAL_8:.*]] = tosa.slice %[[VAL_6]], %[[VAL_4]], %[[VAL_2]]1081// CHECK: return %[[VAL_7]], %[[VAL_8]] : tensor<1x12x15xf32>, tensor<1x12x20xf32>1082func.func @canonicalize_cross_concat_inputs(%arg0 : tensor<1x12x12xf32>, %arg1 : tensor<1x12x12xf32>) -> (tensor<1x12x15xf32>, tensor<1x12x20xf32>) {1083 %0 = tosa.concat %arg0, %arg1 {axis = 2 : i32} : (tensor<1x12x12xf32>, tensor<1x12x12xf32>) -> tensor<1x12x24xf32>1084 %1 = tosa.const_shape {values = dense<[0, 0, 0]> : tensor<3xindex>} : () -> !tosa.shape<3>1085 %2 = tosa.const_shape {values = dense<[0, 0, 4]> : tensor<3xindex>} : () -> !tosa.shape<3>1086 %3 = tosa.const_shape {values = dense<[1, 12, 15]> : tensor<3xindex>} : () -> !tosa.shape<3>1087 %4 = tosa.const_shape {values = dense<[1, 12, 20]> : tensor<3xindex>} : () -> !tosa.shape<3>1088 %5 = tosa.slice %0, %1, %3 : (tensor<1x12x24xf32>, !tosa.shape<3>, !tosa.shape<3>) -> tensor<1x12x15xf32>1089 %6 = tosa.slice %0, %2, %4 : (tensor<1x12x24xf32>, !tosa.shape<3>, !tosa.shape<3>) -> tensor<1x12x20xf32>1090 return %5, %6 : tensor<1x12x15xf32>, tensor<1x12x20xf32>1091}1092 1093// -----1094 1095// CHECK-LABEL: @canonicalize_concat_slice_on_non_concat_axis1096// CHECK-SAME: %[[VAL_0:.*]]: tensor<1x12x12xf32>, %[[VAL_1:.*]]: tensor<1x12x12xf32>1097// CHECK-DAG: %[[VAL_2:.*]] = tosa.const_shape {values = dense<[1, 3, 0]> : tensor<3xindex>}1098// CHECK-DAG: %[[VAL_3:.*]] = tosa.const_shape {values = dense<[1, 3, 12]> : tensor<3xindex>}1099// CHECK-DAG: %[[VAL_4:.*]] = tosa.const_shape {values = dense<0> : tensor<3xindex>}1100// CHECK-DAG: %[[VAL_5:.*]] = tosa.const_shape {values = dense<[1, 6, 12]> : tensor<3xindex>}1101// CHECK: %[[VAL_6:.*]] = tosa.slice %[[VAL_0]], %[[VAL_4]], %[[VAL_5]]1102// CHECK: %[[VAL_7:.*]] = tosa.slice %[[VAL_1]], %[[VAL_2]], %[[VAL_3]]1103// CHECK: return %[[VAL_6]], %[[VAL_7]] : tensor<1x6x12xf32>, tensor<1x3x12xf32>1104func.func @canonicalize_concat_slice_on_non_concat_axis(%arg0 : tensor<1x12x12xf32>, %arg1 : tensor<1x12x12xf32>) -> (tensor<1x6x12xf32>, tensor<1x3x12xf32>) {1105 %0 = tosa.concat %arg0, %arg1 {axis = 2 : i32} : (tensor<1x12x12xf32>, tensor<1x12x12xf32>) -> tensor<1x12x24xf32>1106 %1 = tosa.const_shape {values = dense<[0, 0, 0]> : tensor<3xindex>} : () -> !tosa.shape<3>1107 %2 = tosa.const_shape {values = dense<[1, 6, 12]> : tensor<3xindex>} : () -> !tosa.shape<3>1108 %3 = tosa.const_shape {values = dense<[1, 3, 12]> : tensor<3xindex>} : () -> !tosa.shape<3>1109 %4 = tosa.slice %0, %1, %2 : (tensor<1x12x24xf32>, !tosa.shape<3>, !tosa.shape<3>) -> tensor<1x6x12xf32>1110 %5 = tosa.slice %0, %3, %3 : (tensor<1x12x24xf32>, !tosa.shape<3>, !tosa.shape<3>) -> tensor<1x3x12xf32>1111 return %4, %5 : tensor<1x6x12xf32>, tensor<1x3x12xf32>1112}1113 1114// -----1115 1116// CHECK-LABEL: @canonicalize_pad_slice_overlap1117// CHECK-DAG: %[[PAD_CONST:.*]] = "tosa.const"() <{values = dense<0.000000e+00> : tensor<1xf32>}> : () -> tensor<1xf32>1118// CHECK-DAG: %[[ZERO:.*]] = tosa.const_shape {values = dense<0> : tensor<4xindex>} : () -> !tosa.shape<4>1119// CHECK-DAG: %[[PADDING:.*]] = tosa.const_shape {values = dense<[0, 0, 0, 0, 1, 1, 0, 0]> : tensor<8xindex>}1120// CHECK-DAG: %[[SLICE_SIZE:.*]] = tosa.const_shape {values = dense<[-1, 14, 18, 3]> : tensor<4xindex>}1121// CHECK: %[[PADDED:.*]] = tosa.pad %arg0, %[[PADDING]], %[[PAD_CONST]]1122// CHECK: %[[SLICED:.*]] = tosa.slice %[[PADDED]], %[[ZERO]], %[[SLICE_SIZE]]1123func.func @canonicalize_pad_slice_overlap(%arg0: tensor<?x16x16x3xf32>) -> tensor<?x14x18x3xf32> {1124 %pad_const = "tosa.const"() <{values = dense<0.000000e+00> : tensor<1xf32>}> : () -> tensor<1xf32>1125 %padding = tosa.const_shape {values = dense<[0, 0, 0, 0, 2, 2, 0, 0]> : tensor<8xindex>} : () -> !tosa.shape<8>1126 %padded = tosa.pad %arg0, %padding, %pad_const : (tensor<?x16x16x3xf32>, !tosa.shape<8>, tensor<1xf32>) -> tensor<?x16x20x3xf32>1127 %start = tosa.const_shape {values = dense<[0, 0, 1, 0]> : tensor<4xindex>} : () -> !tosa.shape<4>1128 %size = tosa.const_shape {values = dense<[-1, 14, 18, 3]> : tensor<4xindex>} : () -> !tosa.shape<4>1129 %sliced = tosa.slice %padded, %start, %size : (tensor<?x16x20x3xf32>, !tosa.shape<4>, !tosa.shape<4>) -> tensor<?x14x18x3xf32>1130 return %sliced : tensor<?x14x18x3xf32>1131}1132 1133// -----1134 1135// CHECK-LABEL: @canonicalize_pad_slice_inside1136// CHECK-DAG: %[[SLICE_START:.*]] = tosa.const_shape {values = dense<[0, 1, 2, 0]> : tensor<4xindex>}1137// CHECK-DAG: %[[SLICE_SIZE:.*]] = tosa.const_shape {values = dense<[1, 14, 10, 3]> : tensor<4xindex>}1138// CHECK-NOT: tosa.pad1139// CHECK: %[[SLICED:.*]] = tosa.slice %arg0, %[[SLICE_START]], %[[SLICE_SIZE]]1140func.func @canonicalize_pad_slice_inside(%arg0: tensor<1x16x16x3xf32>) -> tensor<1x14x14x3xf32> {1141 %pad_const = "tosa.const"() <{values = dense<0.000000e+00> : tensor<1xf32>}> : () -> tensor<1xf32>1142 %padding = tosa.const_shape {values = dense<[0, 0, 0, 0, 2, 2, 0, 0]> : tensor<8xindex>} : () -> !tosa.shape<8>1143 %padded = tosa.pad %arg0, %padding, %pad_const : (tensor<1x16x16x3xf32>, !tosa.shape<8>, tensor<1xf32>) -> tensor<1x16x20x3xf32>1144 %start = tosa.const_shape {values = dense<[0, 1, 4, 0]> : tensor<4xindex>} : () -> !tosa.shape<4>1145 %size = tosa.const_shape {values = dense<[1, 14, 10, 3]> : tensor<4xindex>} : () -> !tosa.shape<4>1146 %sliced = tosa.slice %padded, %start, %size : (tensor<1x16x20x3xf32>, !tosa.shape<4>, !tosa.shape<4>) -> tensor<1x14x14x3xf32>1147 return %sliced : tensor<1x14x14x3xf32>1148}1149 1150// -----1151 1152// CHECK-LABEL: func @canonicalize_pad_slice_exact1153// CHECK-DAG: %[[PAD_CONST:.*]] = "tosa.const"() <{values = dense<0.000000e+00> : tensor<1xf32>}> : () -> tensor<1xf32>1154// CHECK-DAG: %[[ZERO:.*]] = tosa.const_shape {values = dense<0> : tensor<4xindex>} : () -> !tosa.shape<4>1155// CHECK-DAG: %[[PADDING:.*]] = tosa.const_shape {values = dense<[0, 0, 0, 0, 2, 2, 0, 0]> : tensor<8xindex>}1156// CHECK-DAG: %[[SLICE_SIZE:.*]] = tosa.const_shape {values = dense<[1, 16, 20, 2]> : tensor<4xindex>}1157// CHECK: %[[PADDED:.*]] = tosa.pad %arg0, %[[PADDING]], %[[PAD_CONST]]1158// CHECK: %[[SLICED:.*]] = tosa.slice %[[PADDED]], %[[ZERO]], %[[SLICE_SIZE]]1159func.func @canonicalize_pad_slice_exact(%arg0: tensor<1x16x16x3xf32>) -> tensor<1x16x20x2xf32> {1160 %pad_const = "tosa.const"() <{values = dense<0.000000e+00> : tensor<1xf32>}> : () -> tensor<1xf32>1161 %padding = tosa.const_shape {values = dense<[0, 0, 0, 0, 2, 2, 0, 0]> : tensor<8xindex>} : () -> !tosa.shape<8>1162 %padded = tosa.pad %arg0, %padding, %pad_const : (tensor<1x16x16x3xf32>, !tosa.shape<8>, tensor<1xf32>) -> tensor<1x16x20x3xf32>1163 %start = tosa.const_shape {values = dense<[0, 0, 0, 0]> : tensor<4xindex>} : () -> !tosa.shape<4>1164 %size = tosa.const_shape {values = dense<[1, 16, 20, 2]> : tensor<4xindex>} : () -> !tosa.shape<4>1165 %sliced = tosa.slice %padded, %start, %size : (tensor<1x16x20x3xf32>, !tosa.shape<4>, !tosa.shape<4>) -> tensor<1x16x20x2xf32>1166 return %sliced : tensor<1x16x20x2xf32>1167}1168 1169// -----1170 1171// CHECK-LABEL: func @canonicalize_pad_slice_dynamic_noupdate1172// CHECK-DAG: tosa.const_shape {values = dense<[0, 0, 0, 0, 2, 2, 0, 0]> : tensor<8xindex>}1173// CHECK-DAG: tosa.const_shape {values = dense<[1, 16, 15, 2]> : tensor<4xindex>}1174// CHECK: tosa.pad1175// CHECK: tosa.slice1176func.func @canonicalize_pad_slice_dynamic_noupdate(%arg0: tensor<1x16x?x3xf32>) -> tensor<1x16x?x2xf32> {1177 %pad_const = "tosa.const"() <{values = dense<0.000000e+00> : tensor<1xf32>}> : () -> tensor<1xf32>1178 %padding = tosa.const_shape {values = dense<[0, 0, 0, 0, 2, 2, 0, 0]> : tensor<8xindex>} : () -> !tosa.shape<8>1179 %padded = tosa.pad %arg0, %padding, %pad_const : (tensor<1x16x?x3xf32>, !tosa.shape<8>, tensor<1xf32>) -> tensor<1x16x?x3xf32>1180 %start = tosa.const_shape {values = dense<[0, 0, 0, 0]> : tensor<4xindex>} : () -> !tosa.shape<4>1181 %size = tosa.const_shape {values = dense<[1, 16, 15, 2]> : tensor<4xindex>} : () -> !tosa.shape<4>1182 %sliced = tosa.slice %padded, %start, %size : (tensor<1x16x?x3xf32>, !tosa.shape<4>, !tosa.shape<4>) -> tensor<1x16x?x2xf32>1183 return %sliced : tensor<1x16x?x2xf32>1184}1185 1186// -----1187 1188// CHECK-LABEL: @fold_negate_negate1189func.func @fold_negate_negate(%arg0: tensor<?x1xf32>) -> tensor<?x1xf32> {1190 // CHECK: return %arg{{.*}} : tensor<?x1xf32>1191 %in_zp = "tosa.const"() <{values = dense<0.0> : tensor<1xf32>}> : () -> tensor<1xf32>1192 %out_zp = "tosa.const"() <{values = dense<0.0> : tensor<1xf32>}> : () -> tensor<1xf32>1193 %0 = tosa.negate %arg0, %in_zp, %out_zp : (tensor<?x1xf32>, tensor<1xf32>, tensor<1xf32>) -> tensor<?x1xf32>1194 %1 = tosa.negate %0, %in_zp, %out_zp : (tensor<?x1xf32>, tensor<1xf32>, tensor<1xf32>) -> tensor<?x1xf32>1195 return %1 : tensor<?x1xf32>1196}1197 1198// -----1199 1200// CHECK-LABEL: @no_fold_negate_negate_non_const_zp1201func.func @no_fold_negate_negate_non_const_zp(%arg0: tensor<?x1xf32>, %in_zp: tensor<1xf32>) -> tensor<?x1xf32> {1202 // cannot fold if any zp is not constant1203 // CHECK: tosa.negate1204 // CHECK: tosa.negate1205 // CHECK: tosa.negate1206 // CHECK: tosa.negate1207 // CHECK: tosa.negate1208 %zero = "tosa.const"() <{values = dense<0.0> : tensor<1xf32>}> : () -> tensor<1xf32>1209 %0 = tosa.negate %arg0, %in_zp, %zero : (tensor<?x1xf32>, tensor<1xf32>, tensor<1xf32>) -> tensor<?x1xf32>1210 %1 = tosa.negate %0, %zero, %zero : (tensor<?x1xf32>, tensor<1xf32>, tensor<1xf32>) -> tensor<?x1xf32>1211 %2 = tosa.negate %1, %zero, %in_zp : (tensor<?x1xf32>, tensor<1xf32>, tensor<1xf32>) -> tensor<?x1xf32>1212 %3 = tosa.negate %2, %zero, %zero : (tensor<?x1xf32>, tensor<1xf32>, tensor<1xf32>) -> tensor<?x1xf32>1213 %4 = tosa.negate %3, %in_zp, %zero : (tensor<?x1xf32>, tensor<1xf32>, tensor<1xf32>) -> tensor<?x1xf32>1214 return %4 : tensor<?x1xf32>1215}1216 1217// -----1218 1219// CHECK-LABEL: @no_fold_negate_negate_non_zero_zp1220func.func @no_fold_negate_negate_non_zero_zp(%arg0: tensor<?x1xi8>) -> tensor<?x1xi8> {1221 // cannot fold if any zp is not constant 01222 // CHECK: tosa.negate1223 // CHECK: tosa.negate1224 // CHECK: tosa.negate1225 // CHECK: tosa.negate1226 // CHECK: tosa.negate1227 %zero = "tosa.const"() <{values = dense<0> : tensor<1xi8>}> : () -> tensor<1xi8>1228 %one = "tosa.const"() <{values = dense<1> : tensor<1xi8>}> : () -> tensor<1xi8>1229 %0 = tosa.negate %arg0, %zero, %one : (tensor<?x1xi8>, tensor<1xi8>, tensor<1xi8>) -> tensor<?x1xi8>1230 %1 = tosa.negate %0, %zero, %zero : (tensor<?x1xi8>, tensor<1xi8>, tensor<1xi8>) -> tensor<?x1xi8>1231 %2 = tosa.negate %1, %one, %zero : (tensor<?x1xi8>, tensor<1xi8>, tensor<1xi8>) -> tensor<?x1xi8>1232 %3 = tosa.negate %2, %zero, %zero : (tensor<?x1xi8>, tensor<1xi8>, tensor<1xi8>) -> tensor<?x1xi8>1233 %4 = tosa.negate %3, %zero, %one : (tensor<?x1xi8>, tensor<1xi8>, tensor<1xi8>) -> tensor<?x1xi8>1234 return %4 : tensor<?x1xi8>1235}1236 1237// -----1238 1239// CHECK-LABEL: @fold_abs_abs1240func.func @fold_abs_abs(%arg0: tensor<?x1xf32>) -> tensor<?x1xf32> {1241 // CHECK: %[[ABS:.*]] = tosa.abs %arg{{.*}} : (tensor<?x1xf32>) -> tensor<?x1xf32>1242 // CHECK: return %[[ABS]] : tensor<?x1xf32>1243 %0 = tosa.abs %arg0 : (tensor<?x1xf32>) -> tensor<?x1xf32>1244 %1 = tosa.abs %0 : (tensor<?x1xf32>) -> tensor<?x1xf32>1245 return %1 : tensor<?x1xf32>1246}1247 1248// -----1249 1250// CHECK-LABEL: @reshape_quant_nofold1251// check that segfault is fixed1252func.func @reshape_quant_nofold() -> tensor<1x1x1x1xi32> {1253 %0 = "tosa.const"() {values = dense<127> : tensor<i8>} : () -> tensor<!quant.uniform<i8:f32, 3.0757404601899907E-5:-128>>1254 %cst0 = "tosa.const_shape"() {values = dense<[1, 1, 1, 1]> : tensor<4xindex>} : () -> !tosa.shape<4>1255 %1 = tosa.reshape %0, %cst0 : (tensor<!quant.uniform<i8:f32, 3.0757404601899907E-5:-128>>, !tosa.shape<4>) -> tensor<1x1x1x1x!quant.uniform<i8:f32, 3.0757404601899907E-5:-128>>1256 %multiplier = "tosa.const"() {values = dense<1073741824> : tensor<1xi32> } : () -> tensor<1xi32>1257 %shift = "tosa.const"() {values = dense<30> : tensor<1xi8> } : () -> tensor<1xi8>1258 %input_zp = "tosa.const"() {values = dense<-128> : tensor<1xi8>} : () -> tensor<1xi8>1259 %output_zp = "tosa.const"() {values = dense<0> : tensor<1xi32>} : () -> tensor<1xi32>1260 %2 = tosa.rescale %1, %multiplier, %shift, %input_zp, %output_zp {rounding_mode = DOUBLE_ROUND, scale32 = true, per_channel = false, input_unsigned = false, output_unsigned = false} : (tensor<1x1x1x1x!quant.uniform<i8:f32, 3.0757404601899907E-5:-128>>, tensor<1xi32>, tensor<1xi8>, tensor<1xi8>, tensor<1xi32>) -> tensor<1x1x1x1xi32>1261 return %2 : tensor<1x1x1x1xi32>1262}1263 1264// -----1265 1266// CHECK-LABEL: @add_quant_nofold1267// check that segfault is fixed1268func.func @add_quant_nofold() -> tensor<!quant.uniform<i8:f32, 3.0757404601899907E-5:-128>> {1269 %0 = "tosa.const"() {values = dense<127> : tensor<i8>} : () -> tensor<!quant.uniform<i8:f32, 3.0757404601899907E-5:-128>>1270 %1 = tosa.add %0, %0 : (tensor<!quant.uniform<i8:f32, 3.0757404601899907E-5:-128>>, tensor<!quant.uniform<i8:f32, 3.0757404601899907E-5:-128>>) -> tensor<!quant.uniform<i8:f32, 3.0757404601899907E-5:-128>>1271 return %1 : tensor<!quant.uniform<i8:f32, 3.0757404601899907E-5:-128>>1272}1273 1274// -----1275 1276// CHECK-LABEL: @sub_quant_nofold1277// check that segfault is fixed1278func.func @sub_quant_nofold() -> tensor<!quant.uniform<i8:f32, 3.0757404601899907E-5:-128>> {1279 %0 = "tosa.const"() {values = dense<127> : tensor<i8>} : () -> tensor<!quant.uniform<i8:f32, 3.0757404601899907E-5:-128>>1280 %1 = tosa.sub %0, %0 : (tensor<!quant.uniform<i8:f32, 3.0757404601899907E-5:-128>>, tensor<!quant.uniform<i8:f32, 3.0757404601899907E-5:-128>>) -> tensor<!quant.uniform<i8:f32, 3.0757404601899907E-5:-128>>1281 return %1 : tensor<!quant.uniform<i8:f32, 3.0757404601899907E-5:-128>>1282}1283 1284// -----1285 1286// CHECK-LABEL: @greater_quant_fold1287func.func @greater_quant_fold() -> tensor<i1> {1288 %0 = "tosa.const"() {values = dense<0> : tensor<i8>} : () -> tensor<!quant.uniform<i8:f32, 3.0757404601899907E-5:-128>>1289 // CHECK: "tosa.const"() <{values = dense<false>1290 %2 = "tosa.greater"(%0, %0) : (tensor<!quant.uniform<i8:f32, 3.0757404601899907E-5:-128>>, tensor<!quant.uniform<i8:f32, 3.0757404601899907E-5:-128>>) -> tensor<i1>1291 return %2 : tensor<i1>1292}1293 1294// -----1295 1296// CHECK-LABEL: @greater_equal_quant_fold1297func.func @greater_equal_quant_fold() -> tensor<i1> {1298 %0 = "tosa.const"() {values = dense<0> : tensor<i8>} : () -> tensor<!quant.uniform<i8:f32, 3.0757404601899907E-5:-128>>1299 // CHECK: "tosa.const"() <{values = dense<true>1300 %2 = "tosa.greater_equal"(%0, %0) : (tensor<!quant.uniform<i8:f32, 3.0757404601899907E-5:-128>>, tensor<!quant.uniform<i8:f32, 3.0757404601899907E-5:-128>>) -> tensor<i1>1301 return %2 : tensor<i1>1302}1303 1304// -----1305 1306// CHECK-LABEL: @equal_quant_fold1307func.func @equal_quant_fold() -> tensor<i1> {1308 %0 = "tosa.const"() {values = dense<0> : tensor<i8>} : () -> tensor<!quant.uniform<i8:f32, 3.0757404601899907E-5:-128>>1309 // CHECK: "tosa.const"() <{values = dense<true>1310 %2 = "tosa.equal"(%0, %0) : (tensor<!quant.uniform<i8:f32, 3.0757404601899907E-5:-128>>, tensor<!quant.uniform<i8:f32, 3.0757404601899907E-5:-128>>) -> tensor<i1>1311 return %2 : tensor<i1>1312}1313 1314// -----1315 1316// CHECK-LABEL: @cast_quant_nofold1317func.func @cast_quant_nofold() -> tensor<!quant.uniform<i8:f32, 3.0757404601899907E-5:3>> {1318 // CHECK: tosa.cast1319 %0 = "tosa.const"() {values = dense<0> : tensor<i8>} : () -> tensor<!quant.uniform<i8:f32, 3.0757404601899907E-5:-128>>1320 %1 = "tosa.cast"(%0) : (tensor<!quant.uniform<i8:f32, 3.0757404601899907E-5:-128>>) -> tensor<!quant.uniform<i8:f32, 3.0757404601899907E-5:3>>1321 return %1 : tensor<!quant.uniform<i8:f32, 3.0757404601899907E-5:3>>1322}1323 1324// -----1325 1326// CHECK-LABEL: @reverse_quant_fold1327func.func @reverse_quant_fold() -> tensor<1x!quant.uniform<i8:f32, 3.0757404601899907E-5:-128>> {1328 // CHECK: %[[CST:.*]] = "tosa.const"() <{values = dense<0> : tensor<1xi8>}> : () -> tensor<1x!quant.uniform<i8:f32, 3.0757404601899907E-5:-128>>1329 // CHECK: return %[[CST]]1330 %0 = "tosa.const"() {values = dense<0> : tensor<1xi8>} : () -> tensor<1x!quant.uniform<i8:f32, 3.0757404601899907E-5:-128>>1331 %1 = "tosa.reverse"(%0) { axis = 0 : i32 } : (tensor<1x!quant.uniform<i8:f32, 3.0757404601899907E-5:-128>>) -> tensor<1x!quant.uniform<i8:f32, 3.0757404601899907E-5:-128>>1332 return %1 : tensor<1x!quant.uniform<i8:f32, 3.0757404601899907E-5:-128>>1333}1334 1335// -----1336 1337// CHECK-LABEL: @select_quant_fold1338func.func @select_quant_fold() -> tensor<!quant.uniform<i8:f32, 3.0757404601899907E-5:-128>> {1339 // CHECK: %[[CONST_0:.*]] = "tosa.const"() <{values = dense<0> : tensor<i8>}> : () -> tensor<!quant.uniform<i8:f32, 3.0757404601899907E-5:-128>>1340 // CHECK: return %[[CONST_0]]1341 %0 = "tosa.const"() {values = dense<true> : tensor<i1>} : () -> tensor<i1>1342 %1 = "tosa.const"() {values = dense<0> : tensor<i8>} : () -> tensor<!quant.uniform<i8:f32, 3.0757404601899907E-5:-128>>1343 %2 = "tosa.const"() {values = dense<127> : tensor<i8>} : () -> tensor<!quant.uniform<i8:f32, 3.0757404601899907E-5:-128>>1344 %3 = "tosa.select"(%0, %1, %2) : (tensor<i1>, tensor<!quant.uniform<i8:f32, 3.0757404601899907E-5:-128>>, tensor<!quant.uniform<i8:f32, 3.0757404601899907E-5:-128>>) -> tensor<!quant.uniform<i8:f32, 3.0757404601899907E-5:-128>>1345 return %3 : tensor<!quant.uniform<i8:f32, 3.0757404601899907E-5:-128>>1346}1347 1348// -----1349 1350// CHECK-LABEL: @mul_quant_nofold1351func.func @mul_quant_nofold() -> tensor<1x!quant.uniform<i8:f32, 3.0757404601899907E-5:-128>> {1352 // CHECK: tosa.mul1353 %0 = "tosa.const"() {values = dense<0> : tensor<1xi8>} : () -> tensor<1x!quant.uniform<i8:f32, 3.0757404601899907E-5:-128>>1354 %1 = "tosa.const"() {values = dense<1> : tensor<1xi8>} : () -> tensor<1x!quant.uniform<i8:f32, 3.0757404601899907E-5:-128>>1355 %shift = "tosa.const"() <{values = dense<0> : tensor<1xi8>}> : () -> tensor<1xi8>1356 %2 = tosa.mul %0, %1, %shift : (tensor<1x!quant.uniform<i8:f32, 3.0757404601899907E-5:-128>>, tensor<1x!quant.uniform<i8:f32, 3.0757404601899907E-5:-128>>, tensor<1xi8>) -> tensor<1x!quant.uniform<i8:f32, 3.0757404601899907E-5:-128>>1357 return %2 : tensor<1x!quant.uniform<i8:f32, 3.0757404601899907E-5:-128>>1358}1359 1360 1361// -----1362 1363// CHECK-LABEL: @fold_reciprocal1364func.func nested @fold_reciprocal() -> tensor<3x600x1200xf32> {1365 // CHECK: %[[VAL_0:.*]] = "tosa.const"() <{values = dense<8.620690e-03> : tensor<3x600x1200xf32>}> : () -> tensor<3x600x1200xf32>1366 // CHECK: return %[[VAL_0]] : tensor<3x600x1200xf32>1367 // CHECK: }1368 %0 = "tosa.const"(){ values = dense<116.0>: tensor<3x600x1200xf32> }: () -> tensor<3x600x1200xf32>1369 %1 = "tosa.reciprocal"(%0): (tensor<3x600x1200xf32>) -> tensor<3x600x1200xf32>1370 return %1 : tensor<3x600x1200xf32>1371}1372 1373// -----1374 1375// CHECK-LABEL: @do_not_fold_reciprocal_int1376func.func nested @do_not_fold_reciprocal_int() -> tensor<3x600x1200xi32> {1377 // CHECK: tosa.reciprocal1378 %0 = "tosa.const"(){ values = dense<11>: tensor<3x600x1200xi32> }: () -> tensor<3x600x1200xi32>1379 %1 = "tosa.reciprocal"(%0): (tensor<3x600x1200xi32>) -> tensor<3x600x1200xi32>1380 return %1 : tensor<3x600x1200xi32>1381}1382 1383// -----1384 1385// CHECK-LABEL: @do_not_fold_intdiv_division_by_01386func.func @do_not_fold_intdiv_division_by_0() -> tensor<1x24x2xi32> {1387 // CHECK: tosa.intdiv1388 %1 = "tosa.const"() <{values = dense<0> : tensor<1x24x2xi32>}> : () -> tensor<1x24x2xi32>1389 %4 = "tosa.const"() <{values = dense<20> : tensor<1x24x2xi32>}> : () -> tensor<1x24x2xi32>1390 %16 = tosa.intdiv %4, %1 : (tensor<1x24x2xi32>, tensor<1x24x2xi32>) -> tensor<1x24x2xi32>1391 return %16 : tensor<1x24x2xi32>1392}1393 1394 1395// -----1396// CHECK-LABEL: func.func @slice_dynamic_size_static_output_canonicalize(1397// CHECK-SAME: %[[ARG0:.*]]: tensor<2x60x59x?xf32>) -> tensor<2x60x58x?xf32> {1398// CHECK: %[[START:.*]] = tosa.const_shape {values = dense<0> : tensor<4xindex>} : () -> !tosa.shape<4>1399// CHECK: %[[SIZE:.*]] = tosa.const_shape {values = dense<[2, 60, 58, -1]> : tensor<4xindex>} : () -> !tosa.shape<4>1400// CHECK: %[[SLICE:.*]] = tosa.slice %[[ARG0]], %[[START]], %[[SIZE]] : (tensor<2x60x59x?xf32>, !tosa.shape<4>, !tosa.shape<4>) -> tensor<2x60x58x?xf32>1401// CHECK: return %[[SLICE]]1402func.func @slice_dynamic_size_static_output_canonicalize(%arg0: tensor<2x60x59x?xf32>) -> tensor<2x60x58x?xf32> {1403 %0 = tosa.const_shape {values = dense<0> : tensor<4xindex>} : () -> !tosa.shape<4>1404 %1 = tosa.const_shape {values = dense<[-1, 60, 58, -1]> : tensor<4xindex>} : () -> !tosa.shape<4>1405 %2 = tosa.slice %arg0, %0, %1 : (tensor<2x60x59x?xf32>, !tosa.shape<4>, !tosa.shape<4>) -> tensor<2x60x58x?xf32>1406 return %2 : tensor<2x60x58x?xf32>1407}1408 1409// -----1410 1411// CHECK-LABEL: @fold_mul_shift1412// CHECK-DAG: "tosa.const"() <{values = dense<1> : tensor<i32>}> : () -> tensor<i32>1413func.func @fold_mul_shift() -> tensor<i32> {1414 %0 = "tosa.const"() <{values = dense<-23661> : tensor<i32>}> : () -> tensor<i32>1415 %1 = "tosa.const"() <{values = dense<-33022> : tensor<i32>}> : () -> tensor<i32>1416 %2 = "tosa.const"() <{values = dense<30> : tensor<1xi8>}> : () -> tensor<1xi8>1417 %3 = tosa.mul %0, %1, %2 : (tensor<i32>, tensor<i32>, tensor<1xi8>) -> tensor<i32>1418 return %3 : tensor<i32>1419}1420 1421// -----1422 1423// CHECK-LABEL: @fold_mul_no_shift1424// CHECK-DAG: "tosa.const"() <{values = dense<781333542> : tensor<i32>}> : () -> tensor<i32>1425func.func @fold_mul_no_shift() -> tensor<i32> {1426 %0 = "tosa.const"() <{values = dense<-23661> : tensor<i32>}> : () -> tensor<i32>1427 %1 = "tosa.const"() <{values = dense<-33022> : tensor<i32>}> : () -> tensor<i32>1428 %2 = "tosa.const"() <{values = dense<0> : tensor<1xi8>}> : () -> tensor<1xi8>1429 %3 = tosa.mul %0, %1, %2 : (tensor<i32>, tensor<i32>, tensor<1xi8>) -> tensor<i32>1430 return %3 : tensor<i32>1431}1432 1433// -----1434 1435// CHECK-LABEL: @no_fold_mul_result_exceeds_i321436// CHECK-DAG: %[[LHS:.*]] = "tosa.const"() <{values = dense<23661> : tensor<i32>}> : () -> tensor<i32>1437// CHECK-DAG: %[[RHS:.*]] = "tosa.const"() <{values = dense<330222> : tensor<i32>}> : () -> tensor<i32>1438// CHECK-DAG: %[[SHIFT:.*]] = "tosa.const"() <{values = dense<1> : tensor<1xi8>}> : () -> tensor<1xi8>1439// CHECK: tosa.mul %[[LHS]], %[[RHS]], %[[SHIFT]] : (tensor<i32>, tensor<i32>, tensor<1xi8>) -> tensor<i32>1440func.func @no_fold_mul_result_exceeds_i32() -> tensor<i32> {1441 %0 = "tosa.const"() <{values = dense<23661> : tensor<i32>}> : () -> tensor<i32>1442 %1 = "tosa.const"() <{values = dense<330222> : tensor<i32>}> : () -> tensor<i32>1443 %2 = "tosa.const"() <{values = dense<1> : tensor<1xi8>}> : () -> tensor<1xi8>1444 %3 = tosa.mul %0, %1, %2 : (tensor<i32>, tensor<i32>, tensor<1xi8>) -> tensor<i32>1445 return %3 : tensor<i32>1446}1447 1448// -----1449 1450// CHECK-LABEL: @test_fold_i1_to_i32_cast1451// CHECK: %[[OUT:.*]] = "tosa.const"() <{values = dense<1> : tensor<i32>}> : () -> tensor<i32>1452// CHECK: return %[[OUT]] : tensor<i32>1453func.func @test_fold_i1_to_i32_cast() -> tensor<i32> {1454 %0 = "tosa.const"() <{values = dense<1> : tensor<i1>}> : () -> tensor<i1>1455 %1 = "tosa.cast"(%0) : (tensor<i1>) -> tensor<i32>1456 return %1 : tensor<i32>1457}1458 1459// -----1460 1461// CHECK-LABEL: @test_fold_i32_to_i1_cast1462// CHECK: %[[OUT:.*]] = "tosa.const"() <{values = dense<true> : tensor<i1>}> : () -> tensor<i1>1463// CHECK: return %[[OUT]] : tensor<i1>1464func.func @test_fold_i32_to_i1_cast() -> tensor<i1> {1465 %0 = "tosa.const"() <{values = dense<10> : tensor<i32>}> : () -> tensor<i32>1466 %1 = "tosa.cast"(%0) : (tensor<i32>) -> tensor<i1>1467 return %1 : tensor<i1>1468}1469