brintos

brintos / llvm-project-archived public Read only

0
0
Text · 44.4 KiB · 8e02c06 Raw
1251 lines · plain
1// RUN: mlir-opt -allow-unregistered-dialect %s -pass-pipeline='builtin.module(func.func(canonicalize{test-convergence}))' -split-input-file | FileCheck %s2 3// CHECK-LABEL: func @test_subi_zero4func.func @test_subi_zero(%arg0: i32) -> i32 {5  // CHECK-NEXT: %c0_i32 = arith.constant 0 : i326  // CHECK-NEXT: return %c07  %y = arith.subi %arg0, %arg0 : i328  return %y: i329}10 11// CHECK-LABEL: func @test_subi_zero_vector12func.func @test_subi_zero_vector(%arg0: vector<4xi32>) -> vector<4xi32> {13  //CHECK-NEXT: %cst = arith.constant dense<0> : vector<4xi32>14  %y = arith.subi %arg0, %arg0 : vector<4xi32>15  // CHECK-NEXT: return %cst16  return %y: vector<4xi32>17}18 19// CHECK-LABEL: func @test_subi_zero_tensor20func.func @test_subi_zero_tensor(%arg0: tensor<4x5xi32>) -> tensor<4x5xi32> {21  //CHECK-NEXT: %cst = arith.constant dense<0> : tensor<4x5xi32>22  %y = arith.subi %arg0, %arg0 : tensor<4x5xi32>23  // CHECK-NEXT: return %cst24  return %y: tensor<4x5xi32>25}26 27// CHECK-LABEL: func @dim28func.func @dim(%arg0: tensor<8x4xf32>) -> index {29 30  // CHECK: %c4 = arith.constant 4 : index31  %c1 = arith.constant 1 : index32  %0 = tensor.dim %arg0, %c1 : tensor<8x4xf32>33 34  // CHECK-NEXT: return %c435  return %0 : index36}37 38// CHECK-LABEL: func @test_commutative39func.func @test_commutative(%arg0: i32) -> (i32, i32) {40  // CHECK: %c42_i32 = arith.constant 42 : i3241  %c42_i32 = arith.constant 42 : i3242  // CHECK-NEXT: %0 = arith.addi %arg0, %c42_i32 : i3243  %y = arith.addi %c42_i32, %arg0 : i3244 45  // This should not be swapped.46  // CHECK-NEXT: %1 = arith.subi %c42_i32, %arg0 : i3247  %z = arith.subi %c42_i32, %arg0 : i3248 49  // CHECK-NEXT: return %0, %150  return %y, %z: i32, i3251}52 53// CHECK-LABEL: func @trivial_dce54func.func @trivial_dce(%arg0: tensor<8x4xf32>) {55  %c1 = arith.constant 1 : index56  %0 = tensor.dim %arg0, %c1 : tensor<8x4xf32>57  // CHECK-NEXT: return58  return59}60 61// CHECK-LABEL: func @load_dce62func.func @load_dce(%arg0: index) {63  %c4 = arith.constant 4 : index64  %a = memref.alloc(%c4) : memref<?xf32>65  %2 = memref.load %a[%arg0] : memref<?xf32>66  memref.dealloc %a: memref<?xf32>67  // CHECK-NEXT: return68  return69}70 71// CHECK-LABEL: func @addi_zero72func.func @addi_zero(%arg0: i32) -> i32 {73  // CHECK-NEXT: return %arg074  %c0_i32 = arith.constant 0 : i3275  %y = arith.addi %c0_i32, %arg0 : i3276  return %y: i3277}78 79// CHECK-LABEL: func @addi_zero_index80func.func @addi_zero_index(%arg0: index) -> index {81  // CHECK-NEXT: return %arg082  %c0_index = arith.constant 0 : index83  %y = arith.addi %c0_index, %arg0 : index84  return %y: index85}86 87 88// CHECK-LABEL: func @addi_zero_vector89func.func @addi_zero_vector(%arg0: vector<4 x i32>) -> vector<4 x i32> {90  // CHECK-NEXT: return %arg091  %c0_v4i32 = arith.constant dense<0> : vector<4 x i32>92  %y = arith.addi %c0_v4i32, %arg0 : vector<4 x i32>93  return %y: vector<4 x i32>94}95 96// CHECK-LABEL: func @addi_zero_tensor97func.func @addi_zero_tensor(%arg0: tensor<4 x 5 x i32>) -> tensor<4 x 5 x i32> {98  // CHECK-NEXT: return %arg099  %c0_t45i32 = arith.constant dense<0> : tensor<4 x 5 x i32>100  %y = arith.addi %arg0, %c0_t45i32 : tensor<4 x 5 x i32>101  return %y: tensor<4 x 5 x i32>102}103 104// CHECK-LABEL: func @muli_zero105func.func @muli_zero(%arg0: i32) -> i32 {106  // CHECK-NEXT: %c0_i32 = arith.constant 0 : i32107  %c0_i32 = arith.constant 0 : i32108 109  %y = arith.muli %c0_i32, %arg0 : i32110 111  // CHECK-NEXT: return %c0_i32112  return %y: i32113}114 115// CHECK-LABEL: func @muli_zero_index116func.func @muli_zero_index(%arg0: index) -> index {117  // CHECK-NEXT: %[[CST:.*]] = arith.constant 0 : index118  %c0_index = arith.constant 0 : index119 120  %y = arith.muli %c0_index, %arg0 : index121 122  // CHECK-NEXT: return %[[CST]]123  return %y: index124}125 126// CHECK-LABEL: func @muli_zero_vector127func.func @muli_zero_vector(%arg0: vector<4 x i32>) -> vector<4 x i32> {128  // CHECK-NEXT: %cst = arith.constant dense<0> : vector<4xi32>129  %cst = arith.constant dense<0> : vector<4 x i32>130 131  %y = arith.muli %cst, %arg0 : vector<4 x i32>132 133  // CHECK-NEXT: return %cst134  return %y: vector<4 x i32>135}136 137// CHECK-LABEL: func @muli_zero_tensor138func.func @muli_zero_tensor(%arg0: tensor<4 x 5 x i32>) -> tensor<4 x 5 x i32> {139  // CHECK-NEXT: %cst = arith.constant dense<0> : tensor<4x5xi32>140  %cst = arith.constant dense<0> : tensor<4 x 5 x i32>141 142  %y = arith.muli %arg0, %cst : tensor<4 x 5 x i32>143 144  // CHECK-NEXT: return %cst145  return %y: tensor<4 x 5 x i32>146}147 148// CHECK-LABEL: func @muli_one149func.func @muli_one(%arg0: i32) -> i32 {150  // CHECK-NEXT: return %arg0151  %c0_i32 = arith.constant 1 : i32152  %y = arith.muli %c0_i32, %arg0 : i32153  return %y: i32154}155 156// CHECK-LABEL: func @muli_one_index157func.func @muli_one_index(%arg0: index) -> index {158  // CHECK-NEXT: return %arg0159  %c0_index = arith.constant 1 : index160  %y = arith.muli %c0_index, %arg0 : index161  return %y: index162}163 164// CHECK-LABEL: func @muli_one_vector165func.func @muli_one_vector(%arg0: vector<4 x i32>) -> vector<4 x i32> {166  // CHECK-NEXT: return %arg0167  %c1_v4i32 = arith.constant dense<1> : vector<4 x i32>168  %y = arith.muli %c1_v4i32, %arg0 : vector<4 x i32>169  return %y: vector<4 x i32>170}171 172// CHECK-LABEL: func @muli_one_tensor173func.func @muli_one_tensor(%arg0: tensor<4 x 5 x i32>) -> tensor<4 x 5 x i32> {174  // CHECK-NEXT: return %arg0175  %c1_t45i32 = arith.constant dense<1> : tensor<4 x 5 x i32>176  %y = arith.muli %arg0, %c1_t45i32 : tensor<4 x 5 x i32>177  return %y: tensor<4 x 5 x i32>178}179 180//CHECK-LABEL: func @and_self181func.func @and_self(%arg0: i32) -> i32 {182  //CHECK-NEXT: return %arg0183  %1 = arith.andi %arg0, %arg0 : i32184  return %1 : i32185}186 187//CHECK-LABEL: func @and_self_vector188func.func @and_self_vector(%arg0: vector<4xi32>) -> vector<4xi32> {189  //CHECK-NEXT: return %arg0190  %1 = arith.andi %arg0, %arg0 : vector<4xi32>191  return %1 : vector<4xi32>192}193 194//CHECK-LABEL: func @and_self_tensor195func.func @and_self_tensor(%arg0: tensor<4x5xi32>) -> tensor<4x5xi32> {196  //CHECK-NEXT: return %arg0197  %1 = arith.andi %arg0, %arg0 : tensor<4x5xi32>198  return %1 : tensor<4x5xi32>199}200 201//CHECK-LABEL: func @and_zero202func.func @and_zero(%arg0: i32) -> i32 {203  // CHECK-NEXT: %c0_i32 = arith.constant 0 : i32204  %c0_i32 = arith.constant 0 : i32205  // CHECK-NEXT: return %c0_i32206  %1 = arith.andi %arg0, %c0_i32 : i32207  return %1 : i32208}209 210//CHECK-LABEL: func @and_zero_index211func.func @and_zero_index(%arg0: index) -> index {212  // CHECK-NEXT: %[[CST:.*]] = arith.constant 0 : index213  %c0_index = arith.constant 0 : index214  // CHECK-NEXT: return %[[CST]]215  %1 = arith.andi %arg0, %c0_index : index216  return %1 : index217}218 219//CHECK-LABEL: func @and_zero_vector220func.func @and_zero_vector(%arg0: vector<4xi32>) -> vector<4xi32> {221  // CHECK-NEXT: %cst = arith.constant dense<0> : vector<4xi32>222  %cst = arith.constant dense<0> : vector<4xi32>223  // CHECK-NEXT: return %cst224  %1 = arith.andi %arg0, %cst : vector<4xi32>225  return %1 : vector<4xi32>226}227 228//CHECK-LABEL: func @and_zero_tensor229func.func @and_zero_tensor(%arg0: tensor<4x5xi32>) -> tensor<4x5xi32> {230  // CHECK-NEXT: %cst = arith.constant dense<0> : tensor<4x5xi32>231  %cst = arith.constant dense<0> : tensor<4x5xi32>232  // CHECK-NEXT: return %cst233  %1 = arith.andi %arg0, %cst : tensor<4x5xi32>234  return %1 : tensor<4x5xi32>235}236 237//CHECK-LABEL: func @or_self238func.func @or_self(%arg0: i32) -> i32 {239  //CHECK-NEXT: return %arg0240  %1 = arith.ori %arg0, %arg0 : i32241  return %1 : i32242}243 244//CHECK-LABEL: func @or_self_vector245func.func @or_self_vector(%arg0: vector<4xi32>) -> vector<4xi32> {246  //CHECK-NEXT: return %arg0247  %1 = arith.ori %arg0, %arg0 : vector<4xi32>248  return %1 : vector<4xi32>249}250 251//CHECK-LABEL: func @or_self_tensor252func.func @or_self_tensor(%arg0: tensor<4x5xi32>) -> tensor<4x5xi32> {253  //CHECK-NEXT: return %arg0254  %1 = arith.ori %arg0, %arg0 : tensor<4x5xi32>255  return %1 : tensor<4x5xi32>256}257 258//CHECK-LABEL: func @or_zero259func.func @or_zero(%arg0: i32) -> i32 {260  %c0_i32 = arith.constant 0 : i32261  // CHECK-NEXT: return %arg0262  %1 = arith.ori %arg0, %c0_i32 : i32263  return %1 : i32264}265 266//CHECK-LABEL: func @or_zero_index267func.func @or_zero_index(%arg0: index) -> index {268  %c0_index = arith.constant 0 : index269  // CHECK-NEXT: return %arg0270  %1 = arith.ori %arg0, %c0_index : index271  return %1 : index272}273 274//CHECK-LABEL: func @or_zero_vector275func.func @or_zero_vector(%arg0: vector<4xi32>) -> vector<4xi32> {276  // CHECK-NEXT: return %arg0277  %cst = arith.constant dense<0> : vector<4xi32>278  %1 = arith.ori %arg0, %cst : vector<4xi32>279  return %1 : vector<4xi32>280}281 282//CHECK-LABEL: func @or_zero_tensor283func.func @or_zero_tensor(%arg0: tensor<4x5xi32>) -> tensor<4x5xi32> {284  // CHECK-NEXT: return %arg0285  %cst = arith.constant dense<0> : tensor<4x5xi32>286  %1 = arith.ori %arg0, %cst : tensor<4x5xi32>287  return %1 : tensor<4x5xi32>288}289 290// CHECK-LABEL: func @or_all_ones291func.func @or_all_ones(%arg0: i1, %arg1: i4) -> (i1, i4) {292  // CHECK-DAG: %c-1_i4 = arith.constant -1 : i4293  // CHECK-DAG: %true = arith.constant true294  %c1_i1 = arith.constant 1 : i1295  %c15 = arith.constant 15 : i4296  // CHECK-NEXT: return %true297  %1 = arith.ori %arg0, %c1_i1 : i1298  %2 = arith.ori %arg1, %c15 : i4299  return %1, %2 : i1, i4300}301 302//CHECK-LABEL: func @xor_self303func.func @xor_self(%arg0: i32) -> i32 {304  //CHECK-NEXT: %c0_i32 = arith.constant 0305  %1 = arith.xori %arg0, %arg0 : i32306  //CHECK-NEXT: return %c0_i32307  return %1 : i32308}309 310//CHECK-LABEL: func @xor_self_vector311func.func @xor_self_vector(%arg0: vector<4xi32>) -> vector<4xi32> {312  //CHECK-NEXT: %cst = arith.constant dense<0> : vector<4xi32>313  %1 = arith.xori %arg0, %arg0 : vector<4xi32>314  //CHECK-NEXT: return %cst315  return %1 : vector<4xi32>316}317 318//CHECK-LABEL: func @xor_self_tensor319func.func @xor_self_tensor(%arg0: tensor<4x5xi32>) -> tensor<4x5xi32> {320  //CHECK-NEXT: %cst = arith.constant dense<0> : tensor<4x5xi32>321  %1 = arith.xori %arg0, %arg0 : tensor<4x5xi32>322  //CHECK-NEXT: return %cst323  return %1 : tensor<4x5xi32>324}325 326// CHECK-LABEL: func @memref_cast_folding327func.func @memref_cast_folding(%arg0: memref<4 x f32>, %arg1: f32) -> (f32, f32) {328  %0 = memref.cast %arg0 : memref<4xf32> to memref<?xf32>329  // CHECK-NEXT: %c0 = arith.constant 0 : index330  %c0 = arith.constant 0 : index331  %dim = memref.dim %0, %c0 : memref<? x f32>332 333  // CHECK-NEXT: affine.load %arg0[3]334  %1 = affine.load %0[%dim - 1] : memref<?xf32>335 336  // CHECK-NEXT: memref.store %arg1, %arg0[%c0] : memref<4xf32>337  memref.store %arg1, %0[%c0] : memref<?xf32>338 339  // CHECK-NEXT: %{{.*}} = memref.load %arg0[%c0] : memref<4xf32>340  %2 = memref.load %0[%c0] : memref<?xf32>341 342  // CHECK-NEXT: memref.dealloc %arg0 : memref<4xf32>343  memref.dealloc %0: memref<?xf32>344 345  // CHECK-NEXT: return %{{.*}}346  return %1, %2 : f32, f32347}348 349// CHECK-LABEL: @fold_memref_cast_in_memref_cast350// CHECK-SAME: (%[[ARG0:.*]]: memref<42x42xf64>)351func.func @fold_memref_cast_in_memref_cast(%0: memref<42x42xf64>) {352  // CHECK: %[[folded:.*]] = memref.cast %[[ARG0]] : memref<42x42xf64> to memref<?x?xf64>353  %4 = memref.cast %0 : memref<42x42xf64> to memref<?x42xf64>354  // CHECK-NOT: memref.cast355  %5 = memref.cast %4 : memref<?x42xf64> to memref<?x?xf64>356  // CHECK: "test.user"(%[[folded]])357  "test.user"(%5) : (memref<?x?xf64>) -> ()358  return359}360 361// CHECK-LABEL: @fold_memref_cast_chain362// CHECK-SAME: (%[[ARG0:.*]]: memref<42x42xf64>)363func.func @fold_memref_cast_chain(%0: memref<42x42xf64>) {364  // CHECK-NOT: memref.cast365  %4 = memref.cast %0 : memref<42x42xf64> to memref<?x42xf64>366  %5 = memref.cast %4 : memref<?x42xf64> to memref<42x42xf64>367  // CHECK: "test.user"(%[[ARG0]])368  "test.user"(%5) : (memref<42x42xf64>) -> ()369  return370}371 372// CHECK-LABEL: func @dead_alloc_fold373func.func @dead_alloc_fold() {374  // CHECK-NEXT: return375  %c4 = arith.constant 4 : index376  %a = memref.alloc(%c4) : memref<?xf32>377  return378}379 380// CHECK-LABEL: func @dead_dealloc_fold381func.func @dead_dealloc_fold() {382  // CHECK-NEXT: return383  %a = memref.alloc() : memref<4xf32>384  memref.dealloc %a: memref<4xf32>385  return386}387 388// CHECK-LABEL: func @dead_dealloc_fold_multi_use389func.func @dead_dealloc_fold_multi_use(%cond : i1) {390  // CHECK-NOT: alloc391  %a = memref.alloc() : memref<4xf32>392  // CHECK: cond_br393  cf.cond_br %cond, ^bb1, ^bb2394 395^bb1:396  // CHECK-NOT: alloc397  memref.dealloc %a: memref<4xf32>398  // CHECK: return399  return400 401^bb2:402  // CHECK-NOT: alloc403  memref.dealloc %a: memref<4xf32>404  // CHECK: return405  return406}407 408// CHECK-LABEL: func @write_only_alloc_fold409func.func @write_only_alloc_fold(%v: f32) {410  // CHECK-NEXT: return411  %c0 = arith.constant 0 : index412  %c4 = arith.constant 4 : index413  %a = memref.alloc(%c4) : memref<?xf32>414  memref.store %v, %a[%c0] : memref<?xf32>415  memref.dealloc %a: memref<?xf32>416  return417}418 419// CHECK-LABEL: func @write_only_alloca_fold420func.func @write_only_alloca_fold(%v: f32) {421  // CHECK-NEXT: return422  %c0 = arith.constant 0 : index423  %c4 = arith.constant 4 : index424  %a = memref.alloca(%c4) : memref<?xf32>425  memref.store %v, %a[%c0] : memref<?xf32>426  return427}428 429// CHECK-LABEL: func @dead_block_elim430func.func @dead_block_elim() {431  // CHECK-NOT: ^bb432  builtin.module {433    func.func @nested() {434      return435 436    ^bb1:437      return438    }439  }440  return441}442 443// CHECK-LABEL: func @dyn_shape_fold(%arg0: index, %arg1: index)444func.func @dyn_shape_fold(%L : index, %M : index) -> (memref<4 x ? x 8 x ? x ? x f32>, memref<? x ? x i32>, memref<? x ? x f32>, memref<4 x ? x 8 x ? x ? x f32>) {445  // CHECK: %c0 = arith.constant 0 : index446  %zero = arith.constant 0 : index447  // The constants below disappear after they propagate into shapes.448  %nine = arith.constant 9 : index449  %N = arith.constant 1024 : index450  %K = arith.constant 512 : index451 452  // CHECK: memref.alloc(%arg0) : memref<?x1024xf32>453  %a = memref.alloc(%L, %N) : memref<? x ? x f32>454 455  // CHECK: memref.alloc(%arg1) : memref<4x1024x8x512x?xf32>456  %b = memref.alloc(%N, %K, %M) : memref<4 x ? x 8 x ? x ? x f32>457 458  // CHECK: memref.alloc() : memref<512x1024xi32>459  %c = memref.alloc(%K, %N) : memref<? x ? x i32>460 461  // CHECK: memref.alloc() : memref<9x9xf32>462  %d = memref.alloc(%nine, %nine) : memref<? x ? x f32>463 464  // CHECK: memref.alloca(%arg1) : memref<4x1024x8x512x?xf32>465  %e = memref.alloca(%N, %K, %M) : memref<4 x ? x 8 x ? x ? x f32>466 467  // CHECK: affine.for468  affine.for %i = 0 to %L {469    // CHECK-NEXT: affine.for470    affine.for %j = 0 to 10 {471      // CHECK-NEXT: memref.load %{{.*}}[%arg2, %arg3] : memref<?x1024xf32>472      // CHECK-NEXT: memref.store %{{.*}}, %{{.*}}[%c0, %c0, %arg2, %arg3, %c0] : memref<4x1024x8x512x?xf32>473      %v = memref.load %a[%i, %j] : memref<?x?xf32>474      memref.store %v, %b[%zero, %zero, %i, %j, %zero] : memref<4x?x8x?x?xf32>475    }476  }477 478  return %b, %c, %d, %e : memref<4 x ? x 8 x ? x ? x f32>, memref<? x ? x i32>, memref<? x ? x f32>, memref<4 x ? x 8 x ? x ? x f32>479}480 481// CHECK-LABEL: func @dim_op_fold(482// CHECK-SAME: %[[ARG0:[a-z0-9]*]]: index483// CHECK-SAME: %[[ARG1:[a-z0-9]*]]: index484// CHECK-SAME: %[[ARG2:[a-z0-9]*]]: index485// CHECK-SAME: %[[BUF:[a-z0-9]*]]: memref<?xi8>486func.func @dim_op_fold(%arg0: index, %arg1: index, %arg2: index, %BUF: memref<?xi8>, %M : index, %N : index, %K : index) {487// CHECK-SAME: [[M:arg[0-9]+]]: index488// CHECK-SAME: [[N:arg[0-9]+]]: index489// CHECK-SAME: [[K:arg[0-9]+]]: index490  %c0 = arith.constant 0 : index491  %c1 = arith.constant 1 : index492  %c2 = arith.constant 2 : index493  %0 = memref.alloc(%arg0, %arg1) : memref<?x?xf32>494  %1 = memref.alloc(%arg1, %arg2) : memref<?x8x?xf32>495  %2 = memref.dim %1, %c2 : memref<?x8x?xf32>496  affine.for %arg3 = 0 to %2 {497    %3 = memref.alloc(%arg0) : memref<?xi8>498    %ub = memref.dim %3, %c0 : memref<?xi8>499    affine.for %arg4 = 0 to %ub {500      %s = memref.dim %0, %c0 : memref<?x?xf32>501      %v = memref.view %3[%c0][%arg4, %s] : memref<?xi8> to memref<?x?xf32>502      %sv = memref.subview %0[%c0, %c0][%s,%arg4][%c1,%c1] : memref<?x?xf32> to memref<?x?xf32, strided<[?, ?], offset: ?>>503      %l = memref.dim %v, %c1 : memref<?x?xf32>504      %u = memref.dim %sv, %c0 : memref<?x?xf32, strided<[?, ?], offset: ?>>505      affine.for %arg5 = %l to %u {506        "foo"() : () -> ()507      }508      %sv2 = memref.subview %0[0, 0][17, %arg4][1, 1] : memref<?x?xf32> to memref<17x?xf32, strided<[?, 1]>>509      %l2 = memref.dim %v, %c1 : memref<?x?xf32>510      %u2 = memref.dim %sv2, %c1 : memref<17x?xf32, strided<[?, 1]>>511      scf.for %arg5 = %l2 to %u2 step %c1 {512        "foo"() : () -> ()513      }514    }515  }516  //      CHECK: affine.for %[[I:.*]] = 0 to %[[ARG2]] {517  // CHECK-NEXT:   affine.for %[[J:.*]] = 0 to %[[ARG0]] {518  // CHECK-NEXT:     affine.for %[[K:.*]] = %[[ARG0]] to %[[ARG0]] {519  // CHECK-NEXT:       "foo"() : () -> ()520  // CHECK-NEXT:     }521  // CHECK-NEXT:     scf.for %[[KK:.*]] = %[[ARG0]] to %[[J]] step %{{.*}} {522  // CHECK-NEXT:       "foo"() : () -> ()523  // CHECK-NEXT:     }524  // CHECK-NEXT:   }525  // CHECK-NEXT: }526 527  %A = memref.view %BUF[%c0][%M, %K] : memref<?xi8> to memref<?x?xf32>528  %B = memref.view %BUF[%c0][%K, %N] : memref<?xi8> to memref<?x?xf32>529  %C = memref.view %BUF[%c0][%M, %N] : memref<?xi8> to memref<?x?xf32>530 531  %M_ = memref.dim %A, %c0 : memref<?x?xf32>532  %K_ = memref.dim %A, %c1 : memref<?x?xf32>533  %N_ = memref.dim %C, %c1 : memref<?x?xf32>534  scf.for %i = %c0 to %M_ step %c1 {535    scf.for %j = %c0 to %N_ step %c1 {536      scf.for %k = %c0 to %K_ step %c1 {537      }538    }539  }540  // CHECK-NEXT: return541  return542}543 544// CHECK-LABEL: func @merge_constants545func.func @merge_constants() -> (index, index) {546  // CHECK-NEXT: %c42 = arith.constant 42 : index547  %0 = arith.constant 42 : index548  %1 = arith.constant 42 : index549  // CHECK-NEXT: return %c42, %c42550  return %0, %1: index, index551}552 553// CHECK-LABEL: func @hoist_constant554func.func @hoist_constant(%arg0: memref<8xi32>) {555  // CHECK-NEXT: %c42_i32 = arith.constant 42 : i32556  // CHECK-NEXT: affine.for %arg1 = 0 to 8 {557  affine.for %arg1 = 0 to 8 {558    // CHECK-NEXT: memref.store %c42_i32, %arg0[%arg1]559    %c42_i32 = arith.constant 42 : i32560    memref.store %c42_i32, %arg0[%arg1] : memref<8xi32>561  }562  return563}564 565// CHECK-LABEL: func @const_fold_propagate566func.func @const_fold_propagate() -> memref<?x?xf32> {567  %VT_i = arith.constant 512 : index568 569  %VT_i_s = affine.apply affine_map<(d0) -> (d0 floordiv  8)> (%VT_i)570  %VT_k_l = affine.apply affine_map<(d0) -> (d0 floordiv  16)> (%VT_i)571 572  // CHECK: = memref.alloc() : memref<64x32xf32>573  %Av = memref.alloc(%VT_i_s, %VT_k_l) : memref<?x?xf32>574  return %Av : memref<?x?xf32>575}576 577// CHECK-LABEL: func @indirect_call_folding578func.func @indirect_target() {579  return580}581 582func.func @indirect_call_folding() {583  // CHECK-NEXT: call @indirect_target() : () -> ()584  // CHECK-NEXT: return585  %indirect_fn = constant @indirect_target : () -> ()586  call_indirect %indirect_fn() : () -> ()587  return588}589 590//591// IMPORTANT NOTE: the operations in this test are exactly those produced by592// lowering affine.apply affine_map<(i) -> (i mod 42)> to standard operations.  Please only593// change these operations together with the affine lowering pass tests.594//595// CHECK-LABEL: @lowered_affine_mod596func.func @lowered_affine_mod() -> (index, index) {597// CHECK-DAG: {{.*}} = arith.constant 1 : index598// CHECK-DAG: {{.*}} = arith.constant 41 : index599  %c-43 = arith.constant -43 : index600  %c42 = arith.constant 42 : index601  %0 = arith.remsi %c-43, %c42 : index602  %c0 = arith.constant 0 : index603  %1 = arith.cmpi slt, %0, %c0 : index604  %2 = arith.addi %0, %c42 : index605  %3 = arith.select %1, %2, %0 : index606  %c43 = arith.constant 43 : index607  %c42_0 = arith.constant 42 : index608  %4 = arith.remsi %c43, %c42_0 : index609  %c0_1 = arith.constant 0 : index610  %5 = arith.cmpi slt, %4, %c0_1 : index611  %6 = arith.addi %4, %c42_0 : index612  %7 = arith.select %5, %6, %4 : index613  return %3, %7 : index, index614}615 616//617// IMPORTANT NOTE: the operations in this test are exactly those produced by618// lowering affine.apply affine_map<(i) -> (i mod 42)> to standard operations.  Please only619// change these operations together with the affine lowering pass tests.620//621// CHECK-LABEL: func @lowered_affine_floordiv622func.func @lowered_affine_floordiv() -> (index, index) {623// CHECK-DAG: %c1 = arith.constant 1 : index624// CHECK-DAG: %c-2 = arith.constant -2 : index625  %c-43 = arith.constant -43 : index626  %c42 = arith.constant 42 : index627  %c0 = arith.constant 0 : index628  %c-1 = arith.constant -1 : index629  %0 = arith.cmpi slt, %c-43, %c0 : index630  %1 = arith.subi %c-1, %c-43 : index631  %2 = arith.select %0, %1, %c-43 : index632  %3 = arith.divsi %2, %c42 : index633  %4 = arith.subi %c-1, %3 : index634  %5 = arith.select %0, %4, %3 : index635  %c43 = arith.constant 43 : index636  %c42_0 = arith.constant 42 : index637  %c0_1 = arith.constant 0 : index638  %c-1_2 = arith.constant -1 : index639  %6 = arith.cmpi slt, %c43, %c0_1 : index640  %7 = arith.subi %c-1_2, %c43 : index641  %8 = arith.select %6, %7, %c43 : index642  %9 = arith.divsi %8, %c42_0 : index643  %10 = arith.subi %c-1_2, %9 : index644  %11 = arith.select %6, %10, %9 : index645  return %5, %11 : index, index646}647 648//649// IMPORTANT NOTE: the operations in this test are exactly those produced by650// lowering affine.apply affine_map<(i) -> (i mod 42)> to standard operations.  Please only651// change these operations together with the affine lowering pass tests.652//653// CHECK-LABEL: func @lowered_affine_ceildiv654func.func @lowered_affine_ceildiv() -> (index, index) {655// CHECK-DAG:  %c-1 = arith.constant -1 : index656  %c-43 = arith.constant -43 : index657  %c42 = arith.constant 42 : index658  %c0 = arith.constant 0 : index659  %c1 = arith.constant 1 : index660  %0 = arith.cmpi sle, %c-43, %c0 : index661  %1 = arith.subi %c0, %c-43 : index662  %2 = arith.subi %c-43, %c1 : index663  %3 = arith.select %0, %1, %2 : index664  %4 = arith.divsi %3, %c42 : index665  %5 = arith.subi %c0, %4 : index666  %6 = arith.addi %4, %c1 : index667  %7 = arith.select %0, %5, %6 : index668// CHECK-DAG:  %c2 = arith.constant 2 : index669  %c43 = arith.constant 43 : index670  %c42_0 = arith.constant 42 : index671  %c0_1 = arith.constant 0 : index672  %c1_2 = arith.constant 1 : index673  %8 = arith.cmpi sle, %c43, %c0_1 : index674  %9 = arith.subi %c0_1, %c43 : index675  %10 = arith.subi %c43, %c1_2 : index676  %11 = arith.select %8, %9, %10 : index677  %12 = arith.divsi %11, %c42_0 : index678  %13 = arith.subi %c0_1, %12 : index679  %14 = arith.addi %12, %c1_2 : index680  %15 = arith.select %8, %13, %14 : index681 682  // CHECK-NEXT: return %c-1, %c2683  return %7, %15 : index, index684}685 686// Checks that NOP casts are removed.687// CHECK-LABEL: cast_values688func.func @cast_values(%arg0: memref<?xi32>) -> memref<2xi32> {689  // NOP cast690  %1 = memref.cast %arg0 : memref<?xi32> to memref<?xi32>691  // CHECK-NEXT: %[[RET:.*]] = memref.cast %arg0 : memref<?xi32> to memref<2xi32>692  %3 = memref.cast %1 : memref<?xi32> to memref<2xi32>693  // NOP cast694  %5 = memref.cast %3 : memref<2xi32> to memref<2xi32>695  // CHECK-NEXT: return %[[RET]] : memref<2xi32>696  return %5 : memref<2xi32>697}698 699// -----700 701// CHECK-LABEL: func @view702func.func @view(%arg0 : index) -> (f32, f32, f32, f32) {703  // CHECK: %[[C15:.*]] = arith.constant 15 : index704  // CHECK: %[[ALLOC_MEM:.*]] = memref.alloc() : memref<2048xi8>705  %0 = memref.alloc() : memref<2048xi8>706  %c0 = arith.constant 0 : index707  %c7 = arith.constant 7 : index708  %c11 = arith.constant 11 : index709  %c15 = arith.constant 15 : index710 711  // Test: fold constant sizes.712  // CHECK: memref.view %[[ALLOC_MEM]][%[[C15]]][] : memref<2048xi8> to memref<7x11xf32>713  %1 = memref.view %0[%c15][%c7, %c11] : memref<2048xi8> to memref<?x?xf32>714  %r0 = memref.load %1[%c0, %c0] : memref<?x?xf32>715 716  // Test: fold one constant size.717  // CHECK: memref.view %[[ALLOC_MEM]][%[[C15]]][%arg0, %arg0] : memref<2048xi8> to memref<?x?x7xf32>718  %2 = memref.view %0[%c15][%arg0, %arg0, %c7] : memref<2048xi8> to memref<?x?x?xf32>719  %r1 = memref.load %2[%c0, %c0, %c0] : memref<?x?x?xf32>720 721  // Test: preserve an existing static size.722  // CHECK: memref.view %[[ALLOC_MEM]][%[[C15]]][] : memref<2048xi8> to memref<7x4xf32>723  %3 = memref.view %0[%c15][%c7] : memref<2048xi8> to memref<?x4xf32>724  %r2 = memref.load %3[%c0, %c0] : memref<?x4xf32>725 726  // Test: folding static alloc and memref.cast into a view.727  // CHECK: memref.view %[[ALLOC_MEM]][%[[C15]]][] : memref<2048xi8> to memref<15x7xf32>728  %4 = memref.cast %0 : memref<2048xi8> to memref<?xi8>729  %5 = memref.view %4[%c15][%c15, %c7] : memref<?xi8> to memref<?x?xf32>730  %r3 = memref.load %5[%c0, %c0] : memref<?x?xf32>731  return %r0, %r1, %r2, %r3 : f32, f32, f32, f32732}733 734// -----735 736// CHECK-LABEL: func @subview737// CHECK-SAME: %[[ARG0:.*]]: index, %[[ARG1:.*]]: index738func.func @subview(%arg0 : index, %arg1 : index) -> (index, index) {739  // Folded but reappears after subview folding into dim.740  // CHECK-DAG: %[[C0:.*]] = arith.constant 0 : index741  // CHECK-DAG: %[[C7:.*]] = arith.constant 7 : index742  // CHECK-DAG: %[[C11:.*]] = arith.constant 11 : index743  %c0 = arith.constant 0 : index744  // CHECK-NOT: arith.constant 1 : index745  %c1 = arith.constant 1 : index746  // CHECK-NOT: arith.constant 2 : index747  %c2 = arith.constant 2 : index748  // Folded but reappears after subview folding into dim.749  %c7 = arith.constant 7 : index750  %c11 = arith.constant 11 : index751  // CHECK-NOT: arith.constant 15 : index752  %c15 = arith.constant 15 : index753 754  // CHECK: %[[ALLOC0:.*]] = memref.alloc()755  %0 = memref.alloc() : memref<128x96x64xf32, strided<[6144, 64, 1], offset: 0>>756 757  // Test: subview with constant base memref and constant operands is folded.758  // Note that the subview uses the base memrefs layout map because it used759  // zero offset and unit stride arguments.760  // CHECK: memref.subview %[[ALLOC0]][0, 0, 0] [7, 11, 2] [1, 1, 1] :761  // CHECK-SAME: memref<128x96x64xf32, strided<[6144, 64, 1]>>762  // CHECK-SAME: to memref<7x11x2xf32, strided<[6144, 64, 1]>>763  %1 = memref.subview %0[%c0, %c0, %c0] [%c7, %c11, %c2] [%c1, %c1, %c1]764    : memref<128x96x64xf32, strided<[6144, 64, 1], offset: 0>> to765      memref<?x?x?xf32, strided<[?, ?, ?], offset: ?>>766  %v0 = memref.load %1[%c0, %c0, %c0] : memref<?x?x?xf32, strided<[?, ?, ?], offset: ?>>767 768  // Test: subview with one dynamic operand can also be folded.769  // CHECK: memref.subview %[[ALLOC0]][0, %[[ARG0]], 0] [7, 11, 15] [1, 1, 1] :770  // CHECK-SAME: memref<128x96x64xf32, strided<[6144, 64, 1]>>771  // CHECK-SAME: to memref<7x11x15xf32, strided<[6144, 64, 1], offset: ?>>772  %2 = memref.subview %0[%c0, %arg0, %c0] [%c7, %c11, %c15] [%c1, %c1, %c1]773    : memref<128x96x64xf32, strided<[6144, 64, 1], offset: 0>> to774      memref<?x?x?xf32, strided<[?, ?, ?], offset: ?>>775  memref.store %v0, %2[%c0, %c0, %c0] : memref<?x?x?xf32, strided<[?, ?, ?], offset: ?>>776 777  // CHECK: %[[ALLOC1:.*]] = memref.alloc(%[[ARG0]])778  %3 = memref.alloc(%arg0) : memref<?x16x4xf32, strided<[64, 4, 1], offset: 0>>779  // Test: subview with constant operands but dynamic base memref is folded as long as the strides and offset of the base memref are static.780  // CHECK: memref.subview %[[ALLOC1]][0, 0, 0] [7, 11, 2] [1, 1, 1] :781  // CHECK-SAME: memref<?x16x4xf32, strided<[64, 4, 1]>>782  // CHECK-SAME: to memref<7x11x2xf32, strided<[64, 4, 1]>>783  %4 = memref.subview %3[%c0, %c0, %c0] [%c7, %c11, %c2] [%c1, %c1, %c1]784    : memref<?x16x4xf32, strided<[64, 4, 1], offset: 0>> to785      memref<?x?x?xf32, strided<[?, ?, ?], offset: ?>>786  memref.store %v0, %4[%c0, %c0, %c0] : memref<?x?x?xf32, strided<[?, ?, ?], offset: ?>>787 788  // Test: subview offset operands are folded correctly w.r.t. base strides.789  // CHECK: memref.subview %[[ALLOC0]][1, 2, 7] [7, 11, 2] [1, 1, 1] :790  // CHECK-SAME: memref<128x96x64xf32, strided<[6144, 64, 1]>> to791  // CHECK-SAME: memref<7x11x2xf32, strided<[6144, 64, 1], offset: 6279>>792  %5 = memref.subview %0[%c1, %c2, %c7] [%c7, %c11, %c2] [%c1, %c1, %c1]793    : memref<128x96x64xf32, strided<[6144, 64, 1], offset: 0>> to794      memref<?x?x?xf32, strided<[?, ?, ?], offset: ?>>795  memref.store %v0, %5[%c0, %c0, %c0] : memref<?x?x?xf32, strided<[?, ?, ?], offset: ?>>796 797  // Test: subview stride operands are folded correctly w.r.t. base strides.798  // CHECK: memref.subview %[[ALLOC0]][0, 0, 0] [7, 11, 2] [2, 7, 11] :799  // CHECK-SAME: memref<128x96x64xf32, strided<[6144, 64, 1]>>800  // CHECK-SAME: to memref<7x11x2xf32, strided<[12288, 448, 11]>>801  %6 = memref.subview %0[%c0, %c0, %c0] [%c7, %c11, %c2] [%c2, %c7, %c11]802    : memref<128x96x64xf32, strided<[6144, 64, 1], offset: 0>> to803      memref<?x?x?xf32, strided<[?, ?, ?], offset: ?>>804  memref.store %v0, %6[%c0, %c0, %c0] : memref<?x?x?xf32, strided<[?, ?, ?], offset: ?>>805 806  // Test: subview shape are folded, but offsets and strides are not even if base memref is static807  // CHECK: memref.subview %[[ALLOC0]][%[[ARG0]], %[[ARG0]], %[[ARG0]]] [7, 11, 2] [%[[ARG1]], %[[ARG1]], %[[ARG1]]] :808  // CHECK-SAME: memref<128x96x64xf32, strided<[6144, 64, 1]>> to809  // CHECK-SAME: memref<7x11x2xf32, strided<[?, ?, ?], offset: ?>>810  %10 = memref.subview %0[%arg0, %arg0, %arg0] [%c7, %c11, %c2] [%arg1, %arg1, %arg1] :811    memref<128x96x64xf32, strided<[6144, 64, 1], offset: 0>> to812    memref<?x?x?xf32, strided<[?, ?, ?], offset: ?>>813  memref.store %v0, %10[%arg1, %arg1, %arg1] :814    memref<?x?x?xf32, strided<[?, ?, ?], offset: ?>>815 816  // Test: subview strides are folded, but offsets and shape are not even if base memref is static817  // CHECK: memref.subview %[[ALLOC0]][%[[ARG0]], %[[ARG0]], %[[ARG0]]] [%[[ARG1]], %[[ARG1]], %[[ARG1]]] [2, 7, 11] :818  // CHECK-SAME: memref<128x96x64xf32, strided<[6144, 64, 1]>> to819  // CHECK-SAME: memref<?x?x?xf32, strided<[12288, 448, 11], offset: ?>>820  %11 = memref.subview %0[%arg0, %arg0, %arg0] [%arg1, %arg1, %arg1] [%c2, %c7, %c11] :821    memref<128x96x64xf32, strided<[6144, 64, 1], offset: 0>> to822    memref<?x?x?xf32, strided<[?, ?, ?], offset: ?>>823  memref.store %v0, %11[%arg0, %arg0, %arg0] :824    memref<?x?x?xf32, strided<[?, ?, ?], offset: ?>>825 826  // Test: subview offsets are folded, but strides and shape are not even if base memref is static827  // CHECK: memref.subview %[[ALLOC0]][1, 2, 7] [%[[ARG1]], %[[ARG1]], %[[ARG1]]] [%[[ARG0]], %[[ARG0]], %[[ARG0]]] :828  // CHECK-SAME: memref<128x96x64xf32, strided<[6144, 64, 1]>> to829  // CHECK-SAME: memref<?x?x?xf32, strided<[?, ?, ?], offset: 6279>>830  %13 = memref.subview %0[%c1, %c2, %c7] [%arg1, %arg1, %arg1] [%arg0, %arg0, %arg0] :831    memref<128x96x64xf32, strided<[6144, 64, 1], offset: 0>> to832    memref<?x?x?xf32, strided<[?, ?, ?], offset: ?>>833  memref.store %v0, %13[%arg1, %arg1, %arg1] :834    memref<?x?x?xf32, strided<[?, ?, ?], offset: ?>>835 836  // CHECK: %[[ALLOC2:.*]] = memref.alloc(%[[ARG0]], %[[ARG0]], %[[ARG1]])837  %14 = memref.alloc(%arg0, %arg0, %arg1) : memref<?x?x?xf32>838  // Test: subview shape are folded, even if base memref is not static839  // CHECK: memref.subview %[[ALLOC2]][%[[ARG0]], %[[ARG0]], %[[ARG0]]] [7, 11, 2] [%[[ARG1]], %[[ARG1]], %[[ARG1]]] :840  // CHECK-SAME: memref<?x?x?xf32> to841  // CHECK-SAME: memref<7x11x2xf32, strided<[?, ?, ?], offset: ?>>842  %15 = memref.subview %14[%arg0, %arg0, %arg0] [%c7, %c11, %c2] [%arg1, %arg1, %arg1] :843    memref<?x?x?xf32> to844    memref<?x?x?xf32, strided<[?, ?, ?], offset: ?>>845  memref.store %v0, %15[%arg1, %arg1, %arg1] : memref<?x?x?xf32, strided<[?, ?, ?], offset: ?>>846 847  // TEST: subview strides are folded, in the type only the most minor stride is folded.848  // CHECK: memref.subview %[[ALLOC2]][%[[ARG0]], %[[ARG0]], %[[ARG0]]] [%[[ARG1]], %[[ARG1]], %[[ARG1]]] [2, 2, 2] :849  // CHECK-SAME: memref<?x?x?xf32> to850  // CHECK-SAME: memref<?x?x?xf32, strided<[?, ?, 2], offset: ?>>851  %16 = memref.subview %14[%arg0, %arg0, %arg0] [%arg1, %arg1, %arg1] [%c2, %c2, %c2] :852    memref<?x?x?xf32> to853    memref<?x?x?xf32, strided<[?, ?, ?], offset: ?>>854  memref.store %v0, %16[%arg0, %arg0, %arg0] : memref<?x?x?xf32, strided<[?, ?, ?], offset: ?>>855 856  // TEST: subview offsets are folded but the type offset remains dynamic, when the base memref is not static857  // CHECK: memref.subview %[[ALLOC2]][1, 1, 1] [%[[ARG0]], %[[ARG0]], %[[ARG0]]] [%[[ARG1]], %[[ARG1]], %[[ARG1]]] :858  // CHECK-SAME: memref<?x?x?xf32> to859  // CHECK-SAME: memref<?x?x?xf32, strided<[?, ?, ?], offset: ?>>860  %17 = memref.subview %14[%c1, %c1, %c1] [%arg0, %arg0, %arg0] [%arg1, %arg1, %arg1] :861    memref<?x?x?xf32> to862    memref<?x?x?xf32, strided<[?, ?, ?], offset: ?>>863  memref.store %v0, %17[%arg0, %arg0, %arg0] : memref<?x?x?xf32, strided<[?, ?, ?], offset: ?>>864 865  // CHECK: %[[ALLOC3:.*]] = memref.alloc() : memref<128x64xf32>866  %18 = memref.alloc() : memref<128x64xf32>867  %c4 = arith.constant 4 : index868 869  // TEST: subview strides are maintained when sizes are folded870  // CHECK: memref.subview %[[ALLOC3]][%arg1, %arg1] [2, 4] [1, 1] :871  // CHECK-SAME: memref<128x64xf32> to872  // CHECK-SAME: memref<2x4xf32, strided<[64, 1], offset: ?>873  %19 = memref.subview %18[%arg1, %arg1] [%c2, %c4] [1, 1] :874    memref<128x64xf32> to875    memref<?x?xf32, strided<[64, 1], offset: ?>>876  memref.store %v0, %19[%arg1, %arg1] : memref<?x?xf32, strided<[64, 1], offset: ?>>877 878  // TEST: subview strides and sizes are maintained when offsets are folded879  // CHECK: memref.subview %[[ALLOC3]][2, 4] [12, 4] [1, 1] :880  // CHECK-SAME: memref<128x64xf32> to881  // CHECK-SAME: memref<12x4xf32, strided<[64, 1], offset: 132>>882  %20 = memref.subview %18[%c2, %c4] [12, 4] [1, 1] :883    memref<128x64xf32> to884    memref<12x4xf32, strided<[64, 1], offset: ?>>885  memref.store %v0, %20[%arg1, %arg1] : memref<12x4xf32, strided<[64, 1], offset: ?>>886 887  // Test: dim on subview is rewritten to size operand.888  %7 = memref.dim %4, %c0 : memref<?x?x?xf32, strided<[?, ?, ?], offset: ?>>889  %8 = memref.dim %4, %c1 : memref<?x?x?xf32, strided<[?, ?, ?], offset: ?>>890 891  // CHECK: return %[[C7]], %[[C11]]892  return %7, %8 : index, index893}894 895// CHECK-LABEL: func @index_cast896// CHECK-SAME: %[[ARG_0:arg[0-9]+]]: i16897func.func @index_cast(%arg0: i16) -> (i16) {898  %11 = arith.index_cast %arg0 : i16 to index899  %12 = arith.index_cast %11 : index to i16900  // CHECK: return %[[ARG_0]] : i16901  return %12 : i16902}903 904// CHECK-LABEL: func @index_cast_fold905func.func @index_cast_fold() -> (i16, index) {906  %c4 = arith.constant 4 : index907  %1 = arith.index_cast %c4 : index to i16908  %c4_i16 = arith.constant 4 : i16909  %2 = arith.index_cast %c4_i16 : i16 to index910  // CHECK-DAG: %[[C4:.*]] = arith.constant 4 : index911  // CHECK-DAG: %[[C4_I16:.*]] = arith.constant 4 : i16912  // CHECK: return %[[C4_I16]], %[[C4]] : i16, index913  return %1, %2 : i16, index914}915 916// CHECK-LABEL: func @remove_dead_else917func.func @remove_dead_else(%M : memref<100 x i32>) {918  affine.for %i = 0 to 100 {919    affine.load %M[%i] : memref<100xi32>920    affine.if affine_set<(d0) : (d0 - 2 >= 0)>(%i) {921      affine.for %j = 0 to 100 {922        %1 = affine.load %M[%j] : memref<100xi32>923        "prevent.dce"(%1) : (i32) -> ()924      }925    } else {926      // Nothing927    }928    affine.load %M[%i] : memref<100xi32>929  }930  return931}932// CHECK:      affine.if933// CHECK-NEXT:   affine.for934// CHECK-NEXT:     affine.load935// CHECK-NEXT:     "prevent.dce"936// CHECK-NEXT:   }937// CHECK-NEXT: }938 939// -----940 941// CHECK-LABEL: func @divi_signed_by_one942// CHECK-SAME: %[[ARG:[a-zA-Z0-9]+]]943func.func @divi_signed_by_one(%arg0: i32) -> (i32) {944  %c1 = arith.constant 1 : i32945  %res = arith.divsi %arg0, %c1 : i32946  // CHECK: return %[[ARG]]947  return %res : i32948}949 950// CHECK-LABEL: func @divi_unsigned_by_one951// CHECK-SAME: %[[ARG:[a-zA-Z0-9]+]]952func.func @divi_unsigned_by_one(%arg0: i32) -> (i32) {953  %c1 = arith.constant 1 : i32954  %res = arith.divui %arg0, %c1 : i32955  // CHECK: return %[[ARG]]956  return %res : i32957}958 959// CHECK-LABEL: func @tensor_divi_signed_by_one960// CHECK-SAME: %[[ARG:[a-zA-Z0-9]+]]961func.func @tensor_divi_signed_by_one(%arg0: tensor<4x5xi32>) -> tensor<4x5xi32> {962  %c1 = arith.constant dense<1> : tensor<4x5xi32>963  %res = arith.divsi %arg0, %c1 : tensor<4x5xi32>964  // CHECK: return %[[ARG]]965  return %res : tensor<4x5xi32>966}967 968// CHECK-LABEL: func @tensor_divi_unsigned_by_one969// CHECK-SAME: %[[ARG:[a-zA-Z0-9]+]]970func.func @tensor_divi_unsigned_by_one(%arg0: tensor<4x5xi32>) -> tensor<4x5xi32> {971  %c1 = arith.constant dense<1> : tensor<4x5xi32>972  %res = arith.divui %arg0, %c1 : tensor<4x5xi32>973  // CHECK: return %[[ARG]]974  return %res : tensor<4x5xi32>975}976 977// -----978 979// CHECK-LABEL: func @arith.floordivsi_by_one980// CHECK-SAME: %[[ARG:[a-zA-Z0-9]+]]981func.func @arith.floordivsi_by_one(%arg0: i32) -> (i32) {982  %c1 = arith.constant 1 : i32983  %res = arith.floordivsi %arg0, %c1 : i32984  // CHECK: return %[[ARG]]985  return %res : i32986}987 988// CHECK-LABEL: func @tensor_arith.floordivsi_by_one989// CHECK-SAME: %[[ARG:[a-zA-Z0-9]+]]990func.func @tensor_arith.floordivsi_by_one(%arg0: tensor<4x5xi32>) -> tensor<4x5xi32> {991  %c1 = arith.constant dense<1> : tensor<4x5xi32>992  %res = arith.floordivsi %arg0, %c1 : tensor<4x5xi32>993  // CHECK: return %[[ARG]]994  return %res : tensor<4x5xi32>995}996 997// CHECK-LABEL: func @arith.floordivsi_by_one_overflow998func.func @arith.floordivsi_by_one_overflow() -> i64 {999  %neg_one = arith.constant -1 : i641000  %min_int = arith.constant -9223372036854775808 : i641001  // CHECK: arith.floordivsi1002  %poision = arith.floordivsi %min_int, %neg_one : i641003  return %poision : i641004}1005 1006// -----1007 1008// CHECK-LABEL: func @arith.ceildivsi_by_one1009// CHECK-SAME: %[[ARG:[a-zA-Z0-9]+]]1010func.func @arith.ceildivsi_by_one(%arg0: i32) -> (i32) {1011  %c1 = arith.constant 1 : i321012  %res = arith.ceildivsi %arg0, %c1 : i321013  // CHECK: return %[[ARG]]1014  return %res : i321015}1016 1017// CHECK-LABEL: func @tensor_arith.ceildivsi_by_one1018// CHECK-SAME: %[[ARG:[a-zA-Z0-9]+]]1019func.func @tensor_arith.ceildivsi_by_one(%arg0: tensor<4x5xi32>) -> tensor<4x5xi32> {1020  %c1 = arith.constant dense<1> : tensor<4x5xi32>1021  %res = arith.ceildivsi %arg0, %c1 : tensor<4x5xi32>1022  // CHECK: return %[[ARG]]1023  return %res : tensor<4x5xi32>1024}1025 1026// -----1027 1028// CHECK-LABEL: func @arith.ceildivui_by_one1029// CHECK-SAME: %[[ARG:[a-zA-Z0-9]+]]1030func.func @arith.ceildivui_by_one(%arg0: i32) -> (i32) {1031  %c1 = arith.constant 1 : i321032  %res = arith.ceildivui %arg0, %c1 : i321033  // CHECK: return %[[ARG]]1034  return %res : i321035}1036 1037// CHECK-LABEL: func @tensor_arith.ceildivui_by_one1038// CHECK-SAME: %[[ARG:[a-zA-Z0-9]+]]1039func.func @tensor_arith.ceildivui_by_one(%arg0: tensor<4x5xi32>) -> tensor<4x5xi32> {1040  %c1 = arith.constant dense<1> : tensor<4x5xi32>1041  %res = arith.ceildivui %arg0, %c1 : tensor<4x5xi32>1042  // CHECK: return %[[ARG]]1043  return %res : tensor<4x5xi32>1044}1045 1046// -----1047 1048// CHECK-LABEL: func @memref_cast_folding_subview1049func.func @memref_cast_folding_subview(%arg0: memref<4x5xf32>, %i: index) -> (memref<?x?xf32, strided<[?, ?], offset: ?>>) {1050  %0 = memref.cast %arg0 : memref<4x5xf32> to memref<?x?xf32>1051  // CHECK-NEXT: memref.subview %{{.*}}: memref<4x5xf32>1052  %1 = memref.subview %0[%i, %i][%i, %i][%i, %i]: memref<?x?xf32> to memref<?x?xf32, strided<[?, ?], offset: ?>>1053  return %1: memref<?x?xf32, strided<[?, ?], offset: ?>>1054}1055 1056// -----1057 1058// CHECK-LABEL: func @memref_cast_folding_subview_static(1059func.func @memref_cast_folding_subview_static(%V: memref<16x16xf32>, %a: index, %b: index)1060  -> memref<3x4xf32, strided<[?, 1]>>1061{1062  %0 = memref.cast %V : memref<16x16xf32> to memref<?x?xf32>1063  %1 = memref.subview %0[0, 0][3, 4][1, 1] : memref<?x?xf32> to memref<3x4xf32, strided<[?, 1]>>1064 1065  // CHECK:  memref.subview{{.*}}: memref<16x16xf32> to memref<3x4xf32, strided<[16, 1]>>1066  return %1: memref<3x4xf32, strided<[?, 1]>>1067}1068 1069// -----1070 1071// CHECK-LABEL: func @slice1072// CHECK-SAME: %[[ARG0:[0-9a-z]*]]: index, %[[ARG1:[0-9a-z]*]]: index1073func.func @slice(%t: tensor<8x16x4xf32>, %arg0 : index, %arg1 : index)1074  -> tensor<?x?x?xf32>1075{1076  %c0 = arith.constant 0 : index1077  %c1 = arith.constant 1 : index1078  %c2 = arith.constant 2 : index1079  %c7 = arith.constant 7 : index1080  %c11 = arith.constant 11 : index1081 1082  // CHECK: tensor.extract_slice %{{.*}}[0, 0, 0] [7, 11, 2] [1, 1, 1] :1083  // CHECK-SAME: tensor<8x16x4xf32> to tensor<7x11x2xf32>1084  // tensor.cast gets folded away in consumer.1085  //  CHECK-NOT: tensor.cast1086  %1 = tensor.extract_slice %t[%c0, %c0, %c0] [%c7, %c11, %c2] [%c1, %c1, %c1]1087    : tensor<8x16x4xf32> to tensor<?x?x?xf32>1088 1089  // Test: slice with one dynamic operand can also be folded.1090  // CHECK: tensor.extract_slice %{{.*}}[0, 0, 0] [2, %[[ARG0]], 2] [1, 1, 1] :1091  // CHECK-SAME: tensor<7x11x2xf32> to tensor<2x?x2xf32>1092  // CHECK: tensor.cast %{{.*}} : tensor<2x?x2xf32> to tensor<?x?x?xf32>1093  %2 = tensor.extract_slice %1[%c0, %c0, %c0] [%c2, %arg0, %c2] [%c1, %c1, %c1]1094    : tensor<?x?x?xf32> to tensor<?x?x?xf32>1095 1096  return %2 : tensor<?x?x?xf32>1097}1098 1099// -----1100 1101// CHECK-LABEL: func @fold_trunci1102// CHECK-SAME:    (%[[ARG0:[0-9a-z]*]]: i1)1103func.func @fold_trunci(%arg0: i1) -> i1 attributes {} {1104  // CHECK-NEXT: return %[[ARG0]] : i11105  %0 = arith.extui %arg0 : i1 to i81106  %1 = arith.trunci %0 : i8 to i11107  return %1 : i11108}1109 1110// -----1111 1112// CHECK-LABEL: func @fold_trunci_vector1113// CHECK-SAME:    (%[[ARG0:[0-9a-z]*]]: vector<4xi1>)1114func.func @fold_trunci_vector(%arg0: vector<4xi1>) -> vector<4xi1> attributes {} {1115  // CHECK-NEXT: return %[[ARG0]] : vector<4xi1>1116  %0 = arith.extui %arg0 : vector<4xi1> to vector<4xi8>1117  %1 = arith.trunci %0 : vector<4xi8> to vector<4xi1>1118  return %1 : vector<4xi1>1119}1120 1121// -----1122 1123// CHECK-LABEL: func @fold_trunci1124// CHECK-SAME:    (%[[ARG0:[0-9a-z]*]]: i1)1125func.func @fold_trunci(%arg0: i1) -> i2 attributes {} {1126  // CHECK-NEXT: %[[RES:[0-9a-z]*]] = arith.extui %[[ARG0]] : i1 to i21127  // CHECK-NEXT: return %[[RES]] : i21128  %0 = arith.extui %arg0 : i1 to i81129  %1 = arith.trunci %0 : i8 to i21130  return %1 : i21131}1132 1133// -----1134 1135// CHECK-LABEL: func @fold_trunci_vector1136// CHECK-SAME:    (%[[ARG0:[0-9a-z]*]]: vector<4xi1>)1137func.func @fold_trunci_vector(%arg0: vector<4xi1>) -> vector<4xi2> attributes {} {1138  // CHECK-NEXT: %[[RES:[0-9a-z]*]] = arith.extui %[[ARG0]] : vector<4xi1> to vector<4xi2>1139  // CHECK-NEXT: return %[[RES]] : vector<4xi2>1140  %0 = arith.extui %arg0 : vector<4xi1> to vector<4xi8>1141  %1 = arith.trunci %0 : vector<4xi8> to vector<4xi2>1142  return %1 : vector<4xi2>1143}1144 1145// -----1146 1147// CHECK-LABEL: func @fold_trunci_sexti1148// CHECK-SAME:    (%[[ARG0:[0-9a-z]*]]: i1)1149func.func @fold_trunci_sexti(%arg0: i1) -> i1 attributes {} {1150  // CHECK-NEXT: return %[[ARG0]] : i11151  %0 = arith.extsi %arg0 : i1 to i81152  %1 = arith.trunci %0 : i8 to i11153  return %1 : i11154}1155 1156// CHECK-LABEL: func @simple_clone_elimination1157func.func @simple_clone_elimination() -> memref<5xf32> {1158  %ret = memref.alloc() : memref<5xf32>1159  %temp = bufferization.clone %ret : memref<5xf32> to memref<5xf32>1160  memref.dealloc %temp : memref<5xf32>1161  return %ret : memref<5xf32>1162}1163// CHECK-NEXT: %[[ret:.*]] = memref.alloc()1164// CHECK-NOT: %{{.*}} = bufferization.clone1165// CHECK-NOT: memref.dealloc %{{.*}}1166// CHECK: return %[[ret]]1167 1168// -----1169 1170// CHECK-LABEL: func @clone_loop_alloc1171func.func @clone_loop_alloc(%arg0: index, %arg1: index, %arg2: index, %arg3: memref<2xf32>, %arg4: memref<2xf32>) {1172  %0 = memref.alloc() : memref<2xf32>1173  memref.dealloc %0 : memref<2xf32>1174  %1 = bufferization.clone %arg3 : memref<2xf32> to memref<2xf32>1175  %2 = scf.for %arg5 = %arg0 to %arg1 step %arg2 iter_args(%arg6 = %1) -> (memref<2xf32>) {1176    %3 = arith.cmpi eq, %arg5, %arg1 : index1177    memref.dealloc %arg6 : memref<2xf32>1178    %4 = memref.alloc() : memref<2xf32>1179    %5 = bufferization.clone %4 : memref<2xf32> to memref<2xf32>1180    memref.dealloc %4 : memref<2xf32>1181    %6 = bufferization.clone %5 : memref<2xf32> to memref<2xf32>1182    memref.dealloc %5 : memref<2xf32>1183    scf.yield %6 : memref<2xf32>1184  }1185  memref.copy %2, %arg4 : memref<2xf32> to memref<2xf32>1186  memref.dealloc %2 : memref<2xf32>1187  return1188}1189 1190// CHECK-NEXT: %[[ALLOC0:.*]] = bufferization.clone1191// CHECK-NEXT: %[[ALLOC1:.*]] = scf.for1192// CHECK-NEXT: memref.dealloc1193// CHECK-NEXT: %[[ALLOC2:.*]] = memref.alloc1194// CHECK-NEXT: scf.yield %[[ALLOC2]]1195// CHECK: memref.copy %[[ALLOC1]]1196// CHECK-NEXT: memref.dealloc %[[ALLOC1]]1197 1198// -----1199 1200// CHECK-LABEL: func @clone_nested_region1201func.func @clone_nested_region(%arg0: index, %arg1: index, %arg2: index) -> memref<?x?xf32> {1202  %cmp = arith.cmpi eq, %arg0, %arg1 : index1203  %0 = arith.cmpi eq, %arg0, %arg1 : index1204  %1 = memref.alloc(%arg0, %arg0) : memref<?x?xf32>1205  %2 = scf.if %0 -> (memref<?x?xf32>) {1206    %3 = scf.if %cmp -> (memref<?x?xf32>) {1207      %9 = bufferization.clone %1 : memref<?x?xf32> to memref<?x?xf32>1208      scf.yield %9 : memref<?x?xf32>1209    } else {1210      %7 = memref.alloc(%arg0, %arg1) : memref<?x?xf32>1211      %10 = bufferization.clone %7 : memref<?x?xf32> to memref<?x?xf32>1212      memref.dealloc %7 : memref<?x?xf32>1213      scf.yield %10 : memref<?x?xf32>1214    }1215    %6 = bufferization.clone %3 : memref<?x?xf32> to memref<?x?xf32>1216    memref.dealloc %3 : memref<?x?xf32>1217    scf.yield %6 : memref<?x?xf32>1218  } else {1219    %3 = memref.alloc(%arg1, %arg1) : memref<?x?xf32>1220    %6 = bufferization.clone %3 : memref<?x?xf32> to memref<?x?xf32>1221    memref.dealloc %3 : memref<?x?xf32>1222    scf.yield %6 : memref<?x?xf32>1223  }1224  memref.dealloc %1 : memref<?x?xf32>1225  return %2 : memref<?x?xf32>1226}1227 1228//      CHECK: %[[ALLOC1:.*]] = memref.alloc1229// CHECK-NEXT: %[[ALLOC2:.*]] = scf.if1230// CHECK-NEXT: %[[ALLOC3_1:.*]] = scf.if1231// CHECK-NEXT: %[[ALLOC4_1:.*]] = bufferization.clone %[[ALLOC1]]1232// CHECK-NEXT: scf.yield %[[ALLOC4_1]]1233//      CHECK: %[[ALLOC4_2:.*]] = memref.alloc1234// CHECK-NEXT: scf.yield %[[ALLOC4_2]]1235//      CHECK: scf.yield %[[ALLOC3_1]]1236//      CHECK: %[[ALLOC3_2:.*]] = memref.alloc1237// CHECK-NEXT: scf.yield %[[ALLOC3_2]]1238//      CHECK: memref.dealloc %[[ALLOC1]]1239// CHECK-NEXT: return %[[ALLOC2]]1240 1241// -----1242 1243// CHECK-LABEL: func @test_materialize_failure1244func.func @test_materialize_failure() -> i64 {1245  %const = index.constant 12341246  // Cannot materialize this castu's output constant.1247  // CHECK: index.castu1248  %u = index.castu %const : index to i641249  return %u: i641250}1251