177124386SMatthias Springer// RUN: mlir-opt %s -allow-unregistered-dialect \ 2*e4384149SOleksandr "Alex" Zinenko// RUN: -transform-interpreter -canonicalize \ 377124386SMatthias Springer// RUN: -split-input-file -verify-diagnostics | FileCheck %s 477124386SMatthias Springer 577124386SMatthias Springer// This is a test case where "high" padding depends on the IV. 677124386SMatthias Springer 777124386SMatthias Springer// CHECK: #[[$map:.*]] = affine_map<()[s0, s1] -> (s0 - s1)> 877124386SMatthias Springer// CHECK: #[[$map1:.*]] = affine_map<(d0)[s0, s1] -> (-d0 + s0 + s1 + 5)> 977124386SMatthias Springer// CHECK-LABEL: func @make_pad_loop_independent_1( 1077124386SMatthias Springer// CHECK-SAME: %[[lb:.*]]: index, %[[ub:.*]]: index, %[[step:.*]]: index, 1177124386SMatthias Springer// CHECK-SAME: %[[t:.*]]: tensor<?xf32> 1277124386SMatthias Springerfunc.func @make_pad_loop_independent_1(%lb: index, %ub: index, %step: index, 1377124386SMatthias Springer %t: tensor<?xf32>, %f: f32) { 1477124386SMatthias Springer // CHECK: scf.for %[[iv:.*]] = %[[lb]] to %[[ub]] 1577124386SMatthias Springer scf.for %i = %lb to %ub step %step { 1677124386SMatthias Springer // CHECK: %[[high:.*]] = affine.apply #[[$map]]()[%[[ub]], %[[lb]]] 1777124386SMatthias Springer // CHECK: %[[padded:.*]] = tensor.pad %[[t]] low[5] high[%[[high]]] 1877124386SMatthias Springer // CHECK: %[[dim:.*]] = tensor.dim %[[t]] 1977124386SMatthias Springer // CHECK: %[[size:.*]] = affine.apply #[[$map1]](%[[iv]])[%[[ub]], %[[dim]]] 2077124386SMatthias Springer // CHECK: %[[replacement:.*]] = tensor.extract_slice %[[padded]][0] [%[[size]]] [1] 2177124386SMatthias Springer %high = affine.apply affine_map<(d0)[s0] -> (s0 - d0)> (%i)[%ub] 2277124386SMatthias Springer %p = tensor.pad %t low[5] high[%high] { 2377124386SMatthias Springer ^bb0(%arg1: index): 2477124386SMatthias Springer tensor.yield %f : f32 2577124386SMatthias Springer } : tensor<?xf32> to tensor<?xf32> 2677124386SMatthias Springer // CHECK: "dummy.some_use"(%[[replacement]]) 2777124386SMatthias Springer "dummy.some_use"(%p) : (tensor<?xf32>) -> () 2877124386SMatthias Springer } 2977124386SMatthias Springer return 3077124386SMatthias Springer} 3177124386SMatthias Springer 32*e4384149SOleksandr "Alex" Zinenkomodule attributes {transform.with_named_sequence} { 33*e4384149SOleksandr "Alex" Zinenko transform.named_sequence @__transform_main(%arg1: !transform.any_op {transform.readonly}) { 342f3ac28cSAlex Zinenko %0 = transform.structured.match ops{["tensor.pad"]} in %arg1 : (!transform.any_op) -> !transform.any_op 352f3ac28cSAlex Zinenko %1 = transform.tensor.make_loop_independent %0 {num_loops = 1} : (!transform.any_op) -> !transform.any_op 36*e4384149SOleksandr "Alex" Zinenko transform.yield 37*e4384149SOleksandr "Alex" Zinenko } 3877124386SMatthias Springer} 3977124386SMatthias Springer 4077124386SMatthias Springer// ----- 4177124386SMatthias Springer 4277124386SMatthias Springer// This is a test case where "low" padding depends on the IV. 4377124386SMatthias Springer 4477124386SMatthias Springer// CHECK: #[[$map:.*]] = affine_map<()[s0, s1] -> (s0 - s1)> 4577124386SMatthias Springer// CHECK: #[[$map1:.*]] = affine_map<(d0)[s0, s1] -> (-d0 + s0 + s1 + 5)> 4677124386SMatthias Springer// CHECK: #[[$map2:.*]] = affine_map<(d0)[s0] -> (d0 - s0)> 4777124386SMatthias Springer// CHECK-LABEL: func @make_pad_loop_independent_1( 4877124386SMatthias Springer// CHECK-SAME: %[[lb:.*]]: index, %[[ub:.*]]: index, %[[step:.*]]: index, 4977124386SMatthias Springer// CHECK-SAME: %[[t:.*]]: tensor<?xf32> 5077124386SMatthias Springerfunc.func @make_pad_loop_independent_1(%lb: index, %ub: index, %step: index, 5177124386SMatthias Springer %t: tensor<?xf32>, %f: f32) { 5277124386SMatthias Springer // CHECK: scf.for %[[iv:.*]] = %[[lb]] to %[[ub]] 5377124386SMatthias Springer scf.for %i = %lb to %ub step %step { 5477124386SMatthias Springer // CHECK: %[[low:.*]] = affine.apply #[[$map]]()[%[[ub]], %[[lb]]] 5577124386SMatthias Springer // CHECK: %[[padded:.*]] = tensor.pad %[[t]] low[%[[low]]] high[5] 5677124386SMatthias Springer // CHECK: %[[dim:.*]] = tensor.dim %[[t]] 5777124386SMatthias Springer // CHECK: %[[size:.*]] = affine.apply #[[$map1]](%[[iv]])[%[[ub]], %[[dim]]] 5877124386SMatthias Springer // CHECK: %[[offset:.*]] = affine.apply #[[$map2]](%[[iv]])[%[[lb]]] 5977124386SMatthias Springer // CHECK: %[[replacement:.*]] = tensor.extract_slice %[[padded]][%[[offset]]] [%[[size]]] [1] 6077124386SMatthias Springer %low = affine.apply affine_map<(d0)[s0] -> (s0 - d0)> (%i)[%ub] 6177124386SMatthias Springer %p = tensor.pad %t low[%low] high[5] { 6277124386SMatthias Springer ^bb0(%arg1: index): 6377124386SMatthias Springer tensor.yield %f : f32 6477124386SMatthias Springer } : tensor<?xf32> to tensor<?xf32> 6577124386SMatthias Springer // CHECK: "dummy.some_use"(%[[replacement]]) 6677124386SMatthias Springer "dummy.some_use"(%p) : (tensor<?xf32>) -> () 6777124386SMatthias Springer } 6877124386SMatthias Springer return 6977124386SMatthias Springer} 7077124386SMatthias Springer 71*e4384149SOleksandr "Alex" Zinenkomodule attributes {transform.with_named_sequence} { 72*e4384149SOleksandr "Alex" Zinenko transform.named_sequence @__transform_main(%arg1: !transform.any_op {transform.readonly}) { 732f3ac28cSAlex Zinenko %0 = transform.structured.match ops{["tensor.pad"]} in %arg1 : (!transform.any_op) -> !transform.any_op 742f3ac28cSAlex Zinenko %1 = transform.tensor.make_loop_independent %0 {num_loops = 1} : (!transform.any_op) -> !transform.any_op 75*e4384149SOleksandr "Alex" Zinenko transform.yield 76*e4384149SOleksandr "Alex" Zinenko } 7777124386SMatthias Springer} 7877124386SMatthias Springer 7977124386SMatthias Springer// ----- 8077124386SMatthias Springer 8177124386SMatthias Springer// CHECK: #[[$map:.*]] = affine_map<()[s0] -> (s0 * 2 - 2)> 8277124386SMatthias Springer// CHECK-LABEL: func @two_loops( 8377124386SMatthias Springerfunc.func @two_loops(%lb: index, %ub: index, %step: index, 8477124386SMatthias Springer %t: tensor<?xf32>, %f: f32) { 8577124386SMatthias Springer scf.for %i = %lb to %ub step %step { 8677124386SMatthias Springer scf.for %j = %lb to %ub step %step { 8777124386SMatthias Springer // CHECK: affine.apply #map()[%{{.*}}] 8877124386SMatthias Springer %low = affine.apply affine_map<(d0, d1)[] -> (d0 + d1)> (%i, %j)[] 8977124386SMatthias Springer %p = tensor.pad %t low[%low] high[5] { 9077124386SMatthias Springer ^bb0(%arg1: index): 9177124386SMatthias Springer tensor.yield %f : f32 9277124386SMatthias Springer } : tensor<?xf32> to tensor<?xf32> 9377124386SMatthias Springer "dummy.some_use"(%p) : (tensor<?xf32>) -> () 9477124386SMatthias Springer } 9577124386SMatthias Springer } 9677124386SMatthias Springer return 9777124386SMatthias Springer} 9877124386SMatthias Springer 99*e4384149SOleksandr "Alex" Zinenkomodule attributes {transform.with_named_sequence} { 100*e4384149SOleksandr "Alex" Zinenko transform.named_sequence @__transform_main(%arg1: !transform.any_op {transform.readonly}) { 1012f3ac28cSAlex Zinenko %0 = transform.structured.match ops{["tensor.pad"]} in %arg1 : (!transform.any_op) -> !transform.any_op 1022f3ac28cSAlex Zinenko %1 = transform.tensor.make_loop_independent %0 {num_loops = 2} : (!transform.any_op) -> !transform.any_op 103*e4384149SOleksandr "Alex" Zinenko transform.yield 104*e4384149SOleksandr "Alex" Zinenko } 10577124386SMatthias Springer} 10677124386SMatthias Springer 10777124386SMatthias Springer// ----- 10877124386SMatthias Springer 10977124386SMatthias Springerfunc.func @not_enough_loops(%lb: index, %ub: index, %step: index, 11077124386SMatthias Springer %t: tensor<?xf32>, %f: f32) { 11177124386SMatthias Springer scf.for %i = %lb to %ub step %step { 11277124386SMatthias Springer scf.for %j = %lb to %ub step %step { 11377124386SMatthias Springer %low = affine.apply affine_map<(d0, d1)[] -> (d0 + d1)> (%i, %j)[] 11477124386SMatthias Springer // expected-note@below {{target op}} 11577124386SMatthias Springer %p = tensor.pad %t low[%low] high[5] { 11677124386SMatthias Springer ^bb0(%arg1: index): 11777124386SMatthias Springer tensor.yield %f : f32 11877124386SMatthias Springer } : tensor<?xf32> to tensor<?xf32> 11977124386SMatthias Springer "dummy.some_use"(%p) : (tensor<?xf32>) -> () 12077124386SMatthias Springer } 12177124386SMatthias Springer } 12277124386SMatthias Springer return 12377124386SMatthias Springer} 12477124386SMatthias Springer 125*e4384149SOleksandr "Alex" Zinenkomodule attributes {transform.with_named_sequence} { 126*e4384149SOleksandr "Alex" Zinenko transform.named_sequence @__transform_main(%arg1: !transform.any_op {transform.readonly}) { 1272f3ac28cSAlex Zinenko %0 = transform.structured.match ops{["tensor.pad"]} in %arg1 : (!transform.any_op) -> !transform.any_op 12877124386SMatthias Springer // expected-error@below {{could not find 2-th enclosing loop}} 1292f3ac28cSAlex Zinenko %1 = transform.tensor.make_loop_independent %0 {num_loops = 3} : (!transform.any_op) -> !transform.any_op 130*e4384149SOleksandr "Alex" Zinenko transform.yield 131*e4384149SOleksandr "Alex" Zinenko } 13277124386SMatthias Springer} 13377124386SMatthias Springer 13477124386SMatthias Springer// ----- 13577124386SMatthias Springer 13677124386SMatthias Springer// CHECK: #[[$map:.*]] = affine_map<(d0)[s0] -> (-d0 + s0)> 13777124386SMatthias Springer// CHECK: #[[$map1:.*]] = affine_map<()[s0, s1] -> (s0 - s1)> 13877124386SMatthias Springer// CHECK-LABEL: func @make_empty_loop_independent( 13977124386SMatthias Springer// CHECK-SAME: %[[lb:.*]]: index, %[[ub:.*]]: index, %[[step:.*]]: index) 14077124386SMatthias Springerfunc.func @make_empty_loop_independent(%lb: index, %ub: index, %step: index) { 14177124386SMatthias Springer // CHECK: scf.for %[[iv:.*]] = %[[lb]] to %[[ub]] 14277124386SMatthias Springer scf.for %i = %lb to %ub step %step { 14377124386SMatthias Springer // CHECK: %[[slice_sz:.*]] = affine.apply #[[$map]](%[[iv]])[%[[ub]]] 14477124386SMatthias Springer // CHECK: %[[empty_sz:.*]] = affine.apply #[[$map1]]()[%[[ub]], %[[lb]]] 14577124386SMatthias Springer // CHECK: %[[empty:.*]] = tensor.empty(%[[empty_sz]]) : tensor<?xf32> 14677124386SMatthias Springer // CHECK: %[[replacement:.*]] = tensor.extract_slice %[[empty]][0] [%[[slice_sz]]] [1] 14777124386SMatthias Springer %sz = affine.apply affine_map<(d0)[s0] -> (s0 - d0)> (%i)[%ub] 14877124386SMatthias Springer %empty = tensor.empty(%sz) : tensor<?xf32> 14977124386SMatthias Springer // CHECK: "dummy.some_use"(%[[replacement]]) 15077124386SMatthias Springer "dummy.some_use"(%empty) : (tensor<?xf32>) -> () 15177124386SMatthias Springer } 15277124386SMatthias Springer return 15377124386SMatthias Springer} 15477124386SMatthias Springer 155*e4384149SOleksandr "Alex" Zinenkomodule attributes {transform.with_named_sequence} { 156*e4384149SOleksandr "Alex" Zinenko transform.named_sequence @__transform_main(%arg1: !transform.any_op {transform.readonly}) { 1572f3ac28cSAlex Zinenko %0 = transform.structured.match ops{["tensor.empty"]} in %arg1 : (!transform.any_op) -> !transform.any_op 1582f3ac28cSAlex Zinenko %1 = transform.tensor.make_loop_independent %0 {num_loops = 1} : (!transform.any_op) -> !transform.any_op 159*e4384149SOleksandr "Alex" Zinenko transform.yield 160*e4384149SOleksandr "Alex" Zinenko } 16177124386SMatthias Springer} 162