blob: 20b6b4cc99657c01e73dc5ba423f996b7fa21bcf [file] [edit]
// RUN: mlir-opt %s --pass-pipeline='builtin.module(func.func(test.isolated_region_branch(remove-dead-values)))' > %t.parallel
// RUN: FileCheck %s --check-prefixes=CHECK,CANON < %t.parallel
// RUN: mlir-opt %s --mlir-disable-threading --pass-pipeline='builtin.module(func.func(test.isolated_region_branch(remove-dead-values)))' > %t.serial
// RUN: diff %t.parallel %t.serial
// RUN: mlir-opt %s --pass-pipeline='builtin.module(func.func(test.isolated_region_branch(remove-dead-values{canonicalize=false})))' | FileCheck %s
// CHECK-LABEL: func.func @live_result
// CHECK-SAME: %[[X:.*]]: i32
// CHECK: %[[ROOT:.*]] = "test.isolated_region_branch"(%[[X]])
// CHECK: ^bb0(%[[ARG:.*]]: i32):
// CHECK-NEXT: %[[SUM:.*]] = arith.addi %[[ARG]], %[[ARG]] : i32
// CHECK-NEXT: "test.isolated_region_yield"(%[[SUM]])
// CHECK: return %[[ROOT]] : i32
func.func @live_result(%x: i32) -> i32 {
%r = "test.isolated_region_branch"(%x) ({
^bb0(%arg: i32):
%dead = arith.muli %arg, %arg : i32
%sum = arith.addi %arg, %arg : i32
"test.isolated_region_yield"(%sum) : (i32) -> ()
}) : (i32) -> i32
return %r : i32
}
// Unused root results and inputs are outside this pass's rewrite scope.
// CHECK-LABEL: func.func @unused_result
// CHECK-SAME: %[[X:.*]]: i32
// CHECK: "test.isolated_region_branch"(%[[X]], %[[X]])
// CHECK: ^bb0(%[[A:.*]]: i32, %[[UNUSED:.*]]: i32):
// CHECK-NEXT: %[[SUM:.*]] = arith.addi %[[A]], %[[A]] : i32
// CHECK-NEXT: "test.isolated_region_yield"(%[[SUM]])
// CHECK: "test.isolated_region_branch"(%[[X]], %[[X]])
// CHECK: "test.isolated_region_yield"
// CHECK: return
func.func @unused_result(%x: i32) {
%r = "test.isolated_region_branch"(%x, %x) ({
^bb0(%arg: i32, %unused: i32):
%sum = arith.addi %arg, %arg : i32
"test.isolated_region_yield"(%sum) : (i32) -> ()
}) : (i32, i32) -> i32
%other = "test.isolated_region_branch"(%x, %x) ({
^bb0(%arg: i32, %unused: i32):
"test.isolated_region_yield"(%arg) : (i32) -> ()
}) : (i32, i32) -> i32
return
}
// CHECK-LABEL: func.func @multiple_regions
// CHECK: "test.isolated_region_branch"()
// CHECK-NEXT: "test.isolated_region_yield"()
// CHECK-NEXT: }, {
// CHECK-NEXT: "test.isolated_region_yield"()
// CHECK: return
func.func @multiple_regions() {
"test.isolated_region_branch"() ({
%dead = arith.constant 1 : i32
"test.isolated_region_yield"() : () -> ()
}, {
%dead = arith.constant 2 : i32
"test.isolated_region_yield"() : () -> ()
}) : () -> ()
return
}
// CHECK-LABEL: func.func @effects
// CHECK: "test.isolated_region_branch"
// CHECK: ^bb0(%[[MEM:.*]]: memref<i32>, %[[VAL:.*]]: i32):
// CHECK-NEXT: memref.store %[[VAL]], %[[MEM]][] : memref<i32>
// CHECK-NEXT: "test.isolated_region_yield"()
func.func @effects(%mem: memref<i32>, %x: i32) {
"test.isolated_region_branch"(%mem, %x) ({
^bb0(%arg: memref<i32>, %val: i32):
%dead = arith.muli %val, %val : i32
memref.store %val, %arg[] : memref<i32>
"test.isolated_region_yield"() : () -> ()
}) : (memref<i32>, i32) -> ()
return
}
// Remove dead loop results in both root regions with the shared patterns.
// CANON-LABEL: func.func @dead_carry
// CANON: "test.isolated_region_branch"
// CANON: scf.for {{.*}} iter_args(%[[CARRY:.*]] = %{{.*}}) -> (i32)
// CANON: scf.yield %{{.*}} : i32
// CANON: "test.isolated_region_yield"
// CANON: scf.for {{.*}} iter_args(%{{.*}} = %{{.*}}) -> (i32)
// CANON: scf.yield %{{.*}} : i32
// CANON: "test.isolated_region_yield"
func.func @dead_carry(%lb: index, %ub: index, %step: index, %x: i32) -> i32 {
%r = "test.isolated_region_branch"(%lb, %ub, %step, %x) ({
^bb0(%lower: index, %upper: index, %stride: index, %init: i32):
%loop:2 = scf.for %iv = %lower to %upper step %stride
iter_args(%live = %init, %dead = %init) -> (i32, i32) {
%sum = arith.addi %live, %live : i32
%unused = arith.muli %dead, %dead : i32
scf.yield %sum, %unused : i32, i32
}
"test.isolated_region_yield"(%loop#0) : (i32) -> ()
}, {
^bb0(%lower: index, %upper: index, %stride: index, %init: i32):
%loop:2 = scf.for %iv = %lower to %upper step %stride
iter_args(%live = %init, %dead = %init) -> (i32, i32) {
%sum = arith.addi %live, %live : i32
%unused = arith.muli %dead, %dead : i32
scf.yield %sum, %unused : i32, i32
}
"test.isolated_region_yield"(%loop#0) : (i32) -> ()
}) : (index, index, index, i32) -> i32
return %r : i32
}
// CHECK-LABEL: func.func @isolated_dead_input
// CHECK-SAME: %[[X:.*]]: i32
// CHECK: "test.isolated_region_branch"(%[[X]], %[[X]])
// CHECK: ^bb0(%[[ARG:.*]]: i32, %{{.*}}: i32):
// CHECK-NEXT: "test.isolated_region_yield"(%[[ARG]])
func.func @isolated_dead_input(%x: i32) -> i32 {
%r = "test.isolated_region_branch"(%x, %x) ({
^bb0(%arg: i32, %dead: i32):
"test.isolated_region_yield"(%arg) : (i32) -> ()
}) : (i32, i32) -> i32
return %r : i32
}