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