// RUN: mlir-opt --transform-interpreter --split-input-file --verify-diagnostics %s | FileCheck %s #umap = affine_map<(d0, d1, d2) -> (d0, d1, d2)> func.func @specialize_exp(%arg0: tensor, %arg1: tensor) -> tensor { %0 = linalg.generic {indexing_maps = [#umap, #umap], iterator_types = ["parallel", "parallel","parallel"]} ins(%arg0 : tensor) outs(%arg1 : tensor) { ^bb0(%in: f32, %out: f32): %v = math.exp %in : f32 linalg.yield %v : f32 } -> tensor %1 = linalg.generic {indexing_maps = [#umap, #umap], iterator_types = ["parallel", "parallel","parallel"]} ins(%0 : tensor) outs(%arg1 : tensor) { ^bb0(%in: f32, %out: f32): %v = math.log %in : f32 linalg.yield %v : f32 } -> tensor %2 = linalg.generic {indexing_maps = [#umap, #umap], iterator_types = ["parallel", "parallel","parallel"]} ins(%1 : tensor) outs(%arg1 : tensor) { ^bb0(%in: f32, %out: f32): %v = math.absf %in : f32 linalg.yield %v : f32 } -> tensor %3 = linalg.generic {indexing_maps = [#umap, #umap], iterator_types = ["parallel", "parallel","parallel"]} ins(%2 : tensor) outs(%arg1 : tensor) { ^bb0(%in: f32, %out: f32): %v = math.ceil %in : f32 linalg.yield %v : f32 } -> tensor %4 = linalg.generic {indexing_maps = [#umap, #umap], iterator_types = ["parallel", "parallel","parallel"]} ins(%3 : tensor) outs(%arg1 : tensor) { ^bb0(%in: f32, %out: f32): %v = math.floor %in : f32 linalg.yield %v : f32 } -> tensor %5 = linalg.generic {indexing_maps = [#umap, #umap], iterator_types = ["parallel", "parallel","parallel"]} ins(%4 : tensor) outs(%arg1 : tensor) { ^bb0(%in: f32, %out: f32): %v = arith.negf %in : f32 linalg.yield %v : f32 } -> tensor %cst_1 = arith.constant 1.0 : f32 %6 = linalg.generic {indexing_maps = [#umap, #umap], iterator_types = ["parallel", "parallel","parallel"]} ins(%5 : tensor) outs(%arg1 : tensor) { ^bb0(%in: f32, %out: f32): %v = arith.divf %cst_1, %in : f32 linalg.yield %v : f32 } -> tensor %7 = linalg.generic {indexing_maps = [#umap, #umap], iterator_types = ["parallel", "parallel","parallel"]} ins(%6 : tensor) outs(%arg1 : tensor) { ^bb0(%in: f32, %out: f32): %v = math.round %in : f32 linalg.yield %v : f32 } -> tensor %8 = linalg.generic {indexing_maps = [#umap, #umap], iterator_types = ["parallel", "parallel","parallel"]} ins(%7 : tensor) outs(%arg1 : tensor) { ^bb0(%in: f32, %out: f32): %v = math.sqrt %in : f32 linalg.yield %v : f32 } -> tensor %9 = linalg.generic {indexing_maps = [#umap, #umap], iterator_types = ["parallel", "parallel","parallel"]} ins(%8 : tensor) outs(%arg1 : tensor) { ^bb0(%in: f32, %out: f32): %v = math.rsqrt %in : f32 linalg.yield %v : f32 } -> tensor %10 = linalg.generic {indexing_maps = [#umap, #umap], iterator_types = ["parallel", "parallel","parallel"]} ins(%9 : tensor) outs(%arg1 : tensor) { ^bb0(%in: f32, %out: f32): %v = arith.mulf %in, %in : f32 linalg.yield %v : f32 } -> tensor %11 = linalg.generic {indexing_maps = [#umap, #umap], iterator_types = ["parallel", "parallel","parallel"]} ins(%10 : tensor) outs(%arg1 : tensor) { ^bb0(%in: f32, %out: f32): %v = math.tanh %in : f32 linalg.yield %v : f32 } -> tensor %12 = linalg.generic {indexing_maps = [#umap, #umap], iterator_types = ["parallel", "parallel","parallel"]} ins(%11 : tensor) outs(%arg1 : tensor) { ^bb0(%in: f32, %out: f32): %v = math.erf %in : f32 linalg.yield %v : f32 } -> tensor return %12 : tensor } // CHECK-LABEL: specialize_exp // CHECK-SAME: %[[ARG0:.+]]: tensor, %[[ARG1:.+]]: tensor) -> tensor // CHECK-NOT: linalg.generic // CHECK: %[[RES0:.+]] = linalg.exp ins(%[[ARG0]] : tensor) outs(%[[ARG1]] : tensor) -> tensor // CHECK: %[[RES1:.+]] = linalg.log ins(%[[RES0]] : tensor) outs(%[[ARG1]] : tensor) -> tensor // CHECK: %[[RES2:.+]] = linalg.abs ins(%[[RES1]] : tensor) outs(%[[ARG1]] : tensor) -> tensor // CHECK: %[[RES3:.+]] = linalg.ceil ins(%[[RES2]] : tensor) outs(%[[ARG1]] : tensor) -> tensor // CHECK: %[[RES4:.+]] = linalg.floor ins(%[[RES3]] : tensor) outs(%[[ARG1]] : tensor) -> tensor // CHECK: %[[RES5:.+]] = linalg.negf ins(%[[RES4]] : tensor) outs(%[[ARG1]] : tensor) -> tensor // CHECK: %[[RES6:.+]] = linalg.reciprocal ins(%[[RES5]] : tensor) outs(%[[ARG1]] : tensor) -> tensor // CHECK: %[[RES7:.+]] = linalg.round ins(%[[RES6]] : tensor) outs(%[[ARG1]] : tensor) -> tensor // CHECK: %[[RES8:.+]] = linalg.sqrt ins(%[[RES7]] : tensor) outs(%[[ARG1]] : tensor) -> tensor // CHECK: %[[RES9:.+]] = linalg.rsqrt ins(%[[RES8]] : tensor) outs(%[[ARG1]] : tensor) -> tensor // CHECK: %[[RES10:.+]] = linalg.square ins(%[[RES9]] : tensor) outs(%[[ARG1]] : tensor) -> tensor // CHECK: %[[RES11:.+]] = linalg.tanh ins(%[[RES10]] : tensor) outs(%[[ARG1]] : tensor) -> tensor // CHECK: %[[RES12:.+]] = linalg.erf ins(%[[RES11]] : tensor) outs(%[[ARG1]] : tensor) -> tensor module attributes {transform.with_named_sequence} { transform.named_sequence @__transform_main(%arg0: !transform.any_op {transform.readonly}) { %0 = transform.structured.match interface{LinalgOp} in %arg0 : (!transform.any_op) -> !transform.any_op %1 = transform.structured.specialize %0 : (!transform.any_op) -> !transform.any_op transform.yield } }