The special case parsing of `func` operations is being removed.
// the entry block.
// CHECK-LABEL: func @condBranch
-func @condBranch(%arg0: i1, %arg1: memref<2xf32>, %arg2: memref<2xf32>) {
+func.func @condBranch(%arg0: i1, %arg1: memref<2xf32>, %arg2: memref<2xf32>) {
cf.cond_br %arg0, ^bb1, ^bb2
^bb1:
cf.br ^bb3(%arg1 : memref<2xf32>)
// %0 in bb2.
// CHECK-LABEL: func @condBranchDynamicType
-func @condBranchDynamicType(
+func.func @condBranchDynamicType(
%arg0: i1,
%arg1: memref<?xf32>,
%arg2: memref<?xf32>,
// %0 in bb2.
// CHECK-LABEL: func @condBranchDynamicTypeNested
-func @condBranchDynamicTypeNested(
+func.func @condBranchDynamicTypeNested(
%arg0: i1,
%arg1: memref<?xf32>,
%arg2: memref<?xf32>,
// the entry block.
// CHECK-LABEL: func @criticalEdge
-func @criticalEdge(%arg0: i1, %arg1: memref<2xf32>, %arg2: memref<2xf32>) {
+func.func @criticalEdge(%arg0: i1, %arg1: memref<2xf32>, %arg2: memref<2xf32>) {
cf.cond_br %arg0, ^bb1, ^bb2(%arg1 : memref<2xf32>)
^bb1:
%0 = memref.alloc() : memref<2xf32>
// BufferHoisting expected behavior: It shouldn't move the AllocOps.
// CHECK-LABEL: func @ifElse
-func @ifElse(%arg0: i1, %arg1: memref<2xf32>, %arg2: memref<2xf32>) {
+func.func @ifElse(%arg0: i1, %arg1: memref<2xf32>, %arg2: memref<2xf32>) {
%0 = memref.alloc() : memref<2xf32>
test.buffer_based in(%arg1: memref<2xf32>) out(%0: memref<2xf32>)
cf.cond_br %arg0,
// BufferHoisting expected behavior: It shouldn't move the AllocOp.
// CHECK-LABEL: func @ifElseNoUsers
-func @ifElseNoUsers(%arg0: i1, %arg1: memref<2xf32>, %arg2: memref<2xf32>) {
+func.func @ifElseNoUsers(%arg0: i1, %arg1: memref<2xf32>, %arg2: memref<2xf32>) {
%0 = memref.alloc() : memref<2xf32>
test.buffer_based in(%arg1: memref<2xf32>) out(%0: memref<2xf32>)
cf.cond_br %arg0,
// BufferHoisting expected behavior: AllocOps shouldn't be moved.
// CHECK-LABEL: func @ifElseNested
-func @ifElseNested(%arg0: i1, %arg1: memref<2xf32>, %arg2: memref<2xf32>) {
+func.func @ifElseNested(%arg0: i1, %arg1: memref<2xf32>, %arg2: memref<2xf32>) {
%0 = memref.alloc() : memref<2xf32>
test.buffer_based in(%arg1: memref<2xf32>) out(%0: memref<2xf32>)
cf.cond_br %arg0,
// BufferHoisting expected behavior: It shouldn't move the AllocOps.
// CHECK-LABEL: func @redundantOperations
-func @redundantOperations(%arg0: memref<2xf32>) {
+func.func @redundantOperations(%arg0: memref<2xf32>) {
%0 = memref.alloc() : memref<2xf32>
test.buffer_based in(%arg0: memref<2xf32>) out(%0: memref<2xf32>)
%1 = memref.alloc() : memref<2xf32>
// entry block.
// CHECK-LABEL: func @moving_alloc_and_inserting_missing_dealloc
-func @moving_alloc_and_inserting_missing_dealloc(
+func.func @moving_alloc_and_inserting_missing_dealloc(
%cond: i1,
%arg0: memref<2xf32>,
%arg1: memref<2xf32>) {
// block.
// CHECK-LABEL: func @moving_invalid_dealloc_op_complex
-func @moving_invalid_dealloc_op_complex(
+func.func @moving_invalid_dealloc_op_complex(
%cond: i1,
%arg0: memref<2xf32>,
%arg1: memref<2xf32>) {
// RegionBufferBasedOp should be moved to the entry block.
// CHECK-LABEL: func @nested_regions_and_cond_branch
-func @nested_regions_and_cond_branch(
+func.func @nested_regions_and_cond_branch(
%arg0: i1,
%arg1: memref<2xf32>,
%arg2: memref<2xf32>) {
// both if branches until it is finally returned.
// CHECK-LABEL: func @nested_region_control_flow
-func @nested_region_control_flow(
+func.func @nested_region_control_flow(
%arg0 : index,
%arg1 : index) -> memref<?x?xf32> {
%0 = arith.cmpi eq, %arg0, %arg1 : index
// The alloc positions of %1 does not need to be changed. %3 is moved upwards.
// CHECK-LABEL: func @nested_region_control_flow_div
-func @nested_region_control_flow_div(
+func.func @nested_region_control_flow_div(
%arg0 : index,
%arg1 : index) -> memref<?x?xf32> {
%0 = arith.cmpi eq, %arg0, %arg1 : index
// moved upwards.
// CHECK-LABEL: func @nested_region_control_flow_div_nested
-func @nested_region_control_flow_div_nested(
+func.func @nested_region_control_flow_div_nested(
%arg0 : index,
%arg1 : index) -> memref<?x?xf32> {
%0 = arith.cmpi eq, %arg0, %arg1 : index
// this region.
// CHECK-LABEL: func @nested_region_control_flow_div_nested_dependencies
-func @nested_region_control_flow_div_nested_dependencies(
+func.func @nested_region_control_flow_div_nested_dependencies(
%arg0: i32,
%arg1: i1,
%arg2: index) -> memref<?x?xf32> {
// The alloc positions of %0 does not need to be changed.
// CHECK-LABEL: func @inner_region_control_flow
-func @inner_region_control_flow(%arg0 : index) -> memref<?x?xf32> {
+func.func @inner_region_control_flow(%arg0 : index) -> memref<?x?xf32> {
%0 = memref.alloc(%arg0, %arg0) : memref<?x?xf32>
%1 = test.region_if %0 : memref<?x?xf32> -> (memref<?x?xf32>) then {
^bb0(%arg1 : memref<?x?xf32>):
// The alloc positions of %0 does not need to be changed. %2 is moved upwards.
// CHECK-LABEL: func @inner_region_control_flow_div
-func @inner_region_control_flow_div(
+func.func @inner_region_control_flow_div(
%arg0 : index,
%arg1 : index) -> memref<?x?xf32> {
%0 = memref.alloc(%arg0, %arg0) : memref<?x?xf32>
// Test Case: Alloca operations shouldn't be moved.
// CHECK-LABEL: func @condBranchAlloca
-func @condBranchAlloca(%arg0: i1, %arg1: memref<2xf32>, %arg2: memref<2xf32>) {
+func.func @condBranchAlloca(%arg0: i1, %arg1: memref<2xf32>, %arg2: memref<2xf32>) {
cf.cond_br %arg0, ^bb1, ^bb2
^bb1:
cf.br ^bb3(%arg1 : memref<2xf32>)
// shouldn't be moved analogously to the ifElseNested test.
// CHECK-LABEL: func @ifElseNestedAlloca
-func @ifElseNestedAlloca(
+func.func @ifElseNestedAlloca(
%arg0: i1,
%arg1: memref<2xf32>,
%arg2: memref<2xf32>) {
// be moved in the beginning analogous to the nestedRegionsAndCondBranch test.
// CHECK-LABEL: func @nestedRegionsAndCondBranchAlloca
-func @nestedRegionsAndCondBranchAlloca(
+func.func @nestedRegionsAndCondBranchAlloca(
%arg0: i1,
%arg1: memref<2xf32>,
%arg2: memref<2xf32>) {
// The alloc positions of %3 will be moved upwards.
// CHECK-LABEL: func @loop_alloc
-func @loop_alloc(
+func.func @loop_alloc(
%lb: index,
%ub: index,
%step: index,
// The allocation %4 is not moved upwards.
// CHECK-LABEL: func @loop_nested_if_alloc
-func @loop_nested_if_alloc(
+func.func @loop_nested_if_alloc(
%lb: index,
%ub: index,
%step: index,
// Same behavior is an loop_nested_if_alloc: The allocs are not moved upwards.
// CHECK-LABEL: func @loop_nested_alloc
-func @loop_nested_alloc(
+func.func @loop_nested_alloc(
%lb: index,
%ub: index,
%step: index,
// -----
// CHECK-LABEL: func @loop_nested_alloc_dyn_dependency
-func @loop_nested_alloc_dyn_dependency(
+func.func @loop_nested_alloc_dyn_dependency(
%lb: index,
%ub: index,
%step: index,
// BufferLoopHoisting expected behavior: It should not move the AllocOp.
// CHECK-LABEL: func @condBranch
-func @condBranch(%arg0: i1, %arg1: memref<2xf32>, %arg2: memref<2xf32>) {
+func.func @condBranch(%arg0: i1, %arg1: memref<2xf32>, %arg2: memref<2xf32>) {
cf.cond_br %arg0, ^bb1, ^bb2
^bb1:
cf.br ^bb3(%arg1 : memref<2xf32>)
// %0 in bb2.
// CHECK-LABEL: func @condBranchDynamicType
-func @condBranchDynamicType(
+func.func @condBranchDynamicType(
%arg0: i1,
%arg1: memref<?xf32>,
%arg2: memref<?xf32>,
// the RegionBufferBasedOp should not be moved during this pass.
// CHECK-LABEL: func @nested_regions_and_cond_branch
-func @nested_regions_and_cond_branch(
+func.func @nested_regions_and_cond_branch(
%arg0: i1,
%arg1: memref<2xf32>,
%arg2: memref<2xf32>) {
// both if branches until it is finally returned.
// CHECK-LABEL: func @nested_region_control_flow
-func @nested_region_control_flow(
+func.func @nested_region_control_flow(
%arg0 : index,
%arg1 : index) -> memref<?x?xf32> {
%0 = arith.cmpi eq, %arg0, %arg1 : index
// The alloc positions of %3 should not be changed.
// CHECK-LABEL: func @loop_alloc
-func @loop_alloc(
+func.func @loop_alloc(
%lb: index,
%ub: index,
%step: index,
// The allocation %4 should not be moved upwards due to a back-edge dependency.
// CHECK-LABEL: func @loop_nested_if_alloc
-func @loop_nested_if_alloc(
+func.func @loop_nested_if_alloc(
%lb: index,
%ub: index,
%step: index,
// in their positions.
// CHECK-LABEL: func @loop_nested_alloc
-func @loop_nested_alloc(
+func.func @loop_nested_alloc(
%lb: index,
%ub: index,
%step: index,
// -----
// CHECK-LABEL: func @loop_nested_alloc_dyn_dependency
-func @loop_nested_alloc_dyn_dependency(
+func.func @loop_nested_alloc_dyn_dependency(
%lb: index,
%ub: index,
%step: index,
// -----
// CHECK-LABEL: func @hoist_one_loop
-func @hoist_one_loop(
+func.func @hoist_one_loop(
%lb: index,
%ub: index,
%step: index,
// -----
// CHECK-LABEL: func @no_hoist_one_loop
-func @no_hoist_one_loop(
+func.func @no_hoist_one_loop(
%lb: index,
%ub: index,
%step: index,
// -----
// CHECK-LABEL: func @hoist_multiple_loop
-func @hoist_multiple_loop(
+func.func @hoist_multiple_loop(
%lb: index,
%ub: index,
%step: index,
// -----
// CHECK-LABEL: func @no_hoist_one_loop_conditional
-func @no_hoist_one_loop_conditional(
+func.func @no_hoist_one_loop_conditional(
%lb: index,
%ub: index,
%step: index,
// -----
// CHECK-LABEL: func @hoist_one_loop_conditional
-func @hoist_one_loop_conditional(
+func.func @hoist_one_loop_conditional(
%lb: index,
%ub: index,
%step: index,
// -----
// CHECK-LABEL: func @no_hoist_one_loop_dependency
-func @no_hoist_one_loop_dependency(
+func.func @no_hoist_one_loop_dependency(
%lb: index,
%ub: index,
%step: index,
// -----
// CHECK-LABEL: func @partial_hoist_multiple_loop_dependency
-func @partial_hoist_multiple_loop_dependency(
+func.func @partial_hoist_multiple_loop_dependency(
%lb: index,
%ub: index,
%step: index,
// Test with allocas to ensure that op is also considered.
// CHECK-LABEL: func @hoist_alloca
-func @hoist_alloca(
+func.func @hoist_alloca(
%lb: index,
%ub: index,
%step: index,
// CHECK: memref.copy %[[RESULT]], %[[ARG]] : memref<f32> to memref<f32>
// CHECK: return
// CHECK: }
-func @basic() -> (memref<f32>) {
+func.func @basic() -> (memref<f32>) {
%0 = "test.source"() : () -> (memref<f32>)
return %0 : memref<f32>
}
// CHECK: memref.copy %[[RESULT]], %[[ARG1]] : memref<2xf32> to memref<2xf32>
// CHECK: return
// CHECK: }
-func @presence_of_existing_arguments(%arg0: memref<1xf32>) -> (memref<2xf32>) {
+func.func @presence_of_existing_arguments(%arg0: memref<1xf32>) -> (memref<2xf32>) {
%0 = "test.source"() : () -> (memref<2xf32>)
return %0 : memref<2xf32>
}
// CHECK: memref.copy %[[RESULTS]]#1, %[[ARG1]] : memref<2xf32> to memref<2xf32>
// CHECK: return
// CHECK: }
-func @multiple_results() -> (memref<1xf32>, memref<2xf32>) {
+func.func @multiple_results() -> (memref<1xf32>, memref<2xf32>) {
%0, %1 = "test.source"() : () -> (memref<1xf32>, memref<2xf32>)
return %0, %1 : memref<1xf32>, memref<2xf32>
}
// CHECK: memref.copy %[[RESULT1]]#1, %[[OUTPARAM]] : memref<f32> to memref<f32>
// CHECK: return %[[RESULT1]]#0, %[[RESULT1]]#2 : i1, i32
// CHECK: }
-func @non_memref_types() -> (i1, memref<f32>, i32) {
+func.func @non_memref_types() -> (i1, memref<f32>, i32) {
%0, %1, %2 = "test.source"() : () -> (i1, memref<f32>, i32)
return %0, %1, %2 : i1, memref<f32>, i32
}
// CHECK: func private @external_function(memref<f32>)
-func private @external_function() -> (memref<f32>)
+func.func private @external_function() -> (memref<f32>)
// CHECK: func private @result_attrs(memref<f32> {test.some_attr})
-func private @result_attrs() -> (memref<f32> {test.some_attr})
+func.func private @result_attrs() -> (memref<f32> {test.some_attr})
// CHECK: func private @mixed_result_attrs(memref<1xf32>, memref<2xf32> {test.some_attr}, memref<3xf32>)
-func private @mixed_result_attrs() -> (memref<1xf32>, memref<2xf32> {test.some_attr}, memref<3xf32>)
+func.func private @mixed_result_attrs() -> (memref<1xf32>, memref<2xf32> {test.some_attr}, memref<3xf32>)
// -----
// CHECK-LABEL: func private @callee(memref<1xf32>)
-func private @callee() -> memref<1xf32>
+func.func private @callee() -> memref<1xf32>
// CHECK-LABEL: func @call_basic() {
// CHECK: %[[OUTPARAM:.*]] = memref.alloc() : memref<1xf32>
// CHECK: "test.sink"(%[[OUTPARAM]]) : (memref<1xf32>) -> ()
// CHECK: return
// CHECK: }
-func @call_basic() {
+func.func @call_basic() {
%0 = call @callee() : () -> memref<1xf32>
"test.sink"(%0) : (memref<1xf32>) -> ()
return
// -----
// CHECK-LABEL: func private @callee(memref<1xf32>, memref<2xf32>)
-func private @callee() -> (memref<1xf32>, memref<2xf32>)
+func.func private @callee() -> (memref<1xf32>, memref<2xf32>)
// CHECK-LABEL: func @call_multiple_result() {
// CHECK: %[[RESULT0:.*]] = memref.alloc() : memref<1xf32>
// CHECK: call @callee(%[[RESULT0]], %[[RESULT1]]) : (memref<1xf32>, memref<2xf32>) -> ()
// CHECK: "test.sink"(%[[RESULT0]], %[[RESULT1]]) : (memref<1xf32>, memref<2xf32>) -> ()
// CHECK: }
-func @call_multiple_result() {
+func.func @call_multiple_result() {
%0, %1 = call @callee() : () -> (memref<1xf32>, memref<2xf32>)
"test.sink"(%0, %1) : (memref<1xf32>, memref<2xf32>) -> ()
}
// -----
// CHECK-LABEL: func private @callee(memref<1xf32>) -> (i1, i32)
-func private @callee() -> (i1, memref<1xf32>, i32)
+func.func private @callee() -> (i1, memref<1xf32>, i32)
// CHECK-LABEL: func @call_non_memref_result() {
// CHECK: %[[RESULT0:.*]] = memref.alloc() : memref<1xf32>
// CHECK: %[[NON_MEMREF_RESULTS:.*]]:2 = call @callee(%[[RESULT0]]) : (memref<1xf32>) -> (i1, i32)
// CHECK: "test.sink"(%[[NON_MEMREF_RESULTS]]#0, %[[RESULT0]], %[[NON_MEMREF_RESULTS]]#1) : (i1, memref<1xf32>, i32) -> ()
// CHECK: }
-func @call_non_memref_result() {
+func.func @call_non_memref_result() {
%0, %1, %2 = call @callee() : () -> (i1, memref<1xf32>, i32)
"test.sink"(%0, %1, %2) : (i1, memref<1xf32>, i32) -> ()
}
// -----
-func private @callee() -> (memref<?xf32>)
+func.func private @callee() -> (memref<?xf32>)
-func @call_non_memref_result() {
+func.func @call_non_memref_result() {
// expected-error @+1 {{cannot create out param for dynamically shaped result}}
%0 = call @callee() : () -> (memref<?xf32>)
"test.sink"(%0) : (memref<?xf32>) -> ()
// Check the simple case of single operation blocks with a return.
// CHECK-LABEL: func @return_blocks(
-func @return_blocks() {
+func.func @return_blocks() {
// CHECK: "foo.cond_br"()[^bb1, ^bb1]
// CHECK: ^bb1:
// CHECK-NEXT: return
// Check the case of identical blocks with matching arguments.
// CHECK-LABEL: func @matching_arguments(
-func @matching_arguments() -> i32 {
+func.func @matching_arguments() -> i32 {
// CHECK: "foo.cond_br"()[^bb1, ^bb1]
// CHECK: ^bb1(%{{.*}}: i32):
// CHECK-NEXT: return
// update th predecessor.
// CHECK-LABEL: func @mismatch_unknown_terminator
-func @mismatch_unknown_terminator(%arg0 : i32, %arg1 : i32) -> i32 {
+func.func @mismatch_unknown_terminator(%arg0 : i32, %arg1 : i32) -> i32 {
// CHECK: "foo.cond_br"()[^bb1, ^bb2]
"foo.cond_br"() [^bb1, ^bb2] : () -> ()
// CHECK-LABEL: func @mismatch_operands
// CHECK-SAME: %[[COND:.*]]: i1, %[[ARG0:.*]]: i32, %[[ARG1:.*]]: i32
-func @mismatch_operands(%cond : i1, %arg0 : i32, %arg1 : i32) -> i32 {
+func.func @mismatch_operands(%cond : i1, %arg0 : i32, %arg1 : i32) -> i32 {
// CHECK: %[[RES:.*]] = arith.select %[[COND]], %[[ARG0]], %[[ARG1]]
// CHECK: return %[[RES]]
// CHECK-LABEL: func @mismatch_operands_matching_arguments(
// CHECK-SAME: %[[COND:.*]]: i1, %[[ARG0:.*]]: i32, %[[ARG1:.*]]: i32
-func @mismatch_operands_matching_arguments(%cond : i1, %arg0 : i32, %arg1 : i32) -> (i32, i32) {
+func.func @mismatch_operands_matching_arguments(%cond : i1, %arg0 : i32, %arg1 : i32) -> (i32, i32) {
// CHECK: %[[RES0:.*]] = arith.select %[[COND]], %[[ARG1]], %[[ARG0]]
// CHECK: %[[RES1:.*]] = arith.select %[[COND]], %[[ARG0]], %[[ARG1]]
// CHECK: return %[[RES1]], %[[RES0]]
// Check that merging does not occur if the uses of the arguments differ.
// CHECK-LABEL: func @mismatch_argument_uses(
-func @mismatch_argument_uses(%cond : i1, %arg0 : i32, %arg1 : i32) -> (i32, i32) {
+func.func @mismatch_argument_uses(%cond : i1, %arg0 : i32, %arg1 : i32) -> (i32, i32) {
// CHECK: cf.cond_br %{{.*}}, ^bb1(%{{.*}}), ^bb2
cf.cond_br %cond, ^bb1(%arg1 : i32), ^bb2(%arg0 : i32)
// Check that merging does not occur if the types of the arguments differ.
// CHECK-LABEL: func @mismatch_argument_types(
-func @mismatch_argument_types(%cond : i1, %arg0 : i32, %arg1 : i16) {
+func.func @mismatch_argument_types(%cond : i1, %arg0 : i32, %arg1 : i16) {
// CHECK: cf.cond_br %{{.*}}, ^bb1(%{{.*}}), ^bb2
cf.cond_br %cond, ^bb1(%arg0 : i32), ^bb2(%arg1 : i16)
// Check that merging does not occur if the number of the arguments differ.
// CHECK-LABEL: func @mismatch_argument_count(
-func @mismatch_argument_count(%cond : i1, %arg0 : i32) {
+func.func @mismatch_argument_count(%cond : i1, %arg0 : i32) {
// CHECK: cf.cond_br %{{.*}}, ^bb1(%{{.*}}), ^bb2
cf.cond_br %cond, ^bb1(%arg0 : i32), ^bb2
// Check that merging does not occur if the operations differ.
// CHECK-LABEL: func @mismatch_operations(
-func @mismatch_operations(%cond : i1) {
+func.func @mismatch_operations(%cond : i1) {
// CHECK: cf.cond_br %{{.*}}, ^bb1, ^bb2
cf.cond_br %cond, ^bb1, ^bb2
// Check that merging does not occur if the number of operations differ.
// CHECK-LABEL: func @mismatch_operation_count(
-func @mismatch_operation_count(%cond : i1) {
+func.func @mismatch_operation_count(%cond : i1) {
// CHECK: cf.cond_br %{{.*}}, ^bb1, ^bb2
cf.cond_br %cond, ^bb1, ^bb2
// Check that merging does not occur if the blocks contain regions.
// CHECK-LABEL: func @contains_regions(
-func @contains_regions(%cond : i1) {
+func.func @contains_regions(%cond : i1) {
// CHECK: cf.cond_br %{{.*}}, ^bb1, ^bb2
cf.cond_br %cond, ^bb1, ^bb2
// CHECK-LABEL: func @mismatch_loop(
// CHECK-SAME: %[[ARG:.*]]: i1, %[[ARG2:.*]]: i1
-func @mismatch_loop(%cond : i1, %cond2 : i1) {
+func.func @mismatch_loop(%cond : i1, %cond2 : i1) {
// CHECK-NEXT: %[[LOOP_CARRY:.*]] = "foo.op"
// CHECK: cf.cond_br %{{.*}}, ^bb1(%[[ARG2]] : i1), ^bb2
// Check that blocks are not merged if the types of the operands differ.
// CHECK-LABEL: func @mismatch_operand_types(
-func @mismatch_operand_types(%arg0 : i1, %arg1 : memref<i32>, %arg2 : memref<i1>) {
+func.func @mismatch_operand_types(%arg0 : i1, %arg1 : memref<i32>, %arg2 : memref<i1>) {
%c0_i32 = arith.constant 0 : i32
%true = arith.constant true
cf.br ^bb1
// with an external user. Incorrectly performing the optimization
// anyways will result in print(merged, merged) rather than
// distinct operands.
-func private @print(%arg0: i32, %arg1: i32)
+func.func private @print(%arg0: i32, %arg1: i32)
// CHECK-LABEL: @nomerge
-func @nomerge(%arg0: i32, %i: i32) {
+func.func @nomerge(%arg0: i32, %i: i32) {
%c1_i32 = arith.constant 1 : i32
%icmp = arith.cmpi slt, %i, %arg0 : i32
cf.cond_br %icmp, ^bb2, ^bb3
// CHECK-LABEL: func @mismatch_dominance(
-func @mismatch_dominance() -> i32 {
+func.func @mismatch_dominance() -> i32 {
// CHECK: %[[RES:.*]] = "test.producing_br"()
%0 = "test.producing_br"()[^bb1, ^bb2] {
operand_segment_sizes = dense<0> : vector<2 x i32>
// CHECK: func @f(%arg0: f32) {
// CHECK-NEXT: return
-func @f(%arg0: f32) {
+func.func @f(%arg0: f32) {
%0 = "arith.addf"(%arg0, %arg0) : (f32, f32) -> f32
return
}
// CHECK-NEXT: ^bb1:
// CHECK-NEXT: return
-func @f(%arg0: f32) {
+func.func @f(%arg0: f32) {
"test.br"(%arg0)[^succ] : (f32) -> ()
^succ(%0: f32):
return
// CHECK-NEXT: cf.br ^bb1
-func @f(%arg0: f32) {
+func.func @f(%arg0: f32) {
cf.br ^loop(%arg0: f32)
^loop(%loop: f32):
cf.br ^loop(%loop: f32)
// CHECK-NEXT: ^bb1:
// CHECK-NEXT: cf.br ^bb1
-func @f(%arg0: f32) {
+func.func @f(%arg0: f32) {
cf.br ^loop(%arg0: f32)
^loop(%0: f32):
%1 = "math.exp"(%0) : (f32) -> f32
// CHECK: func @f(%arg0: f32, %arg1: i1)
// CHECK-NEXT: return
-func @f(%arg0: f32, %pred: i1) {
+func.func @f(%arg0: f32, %pred: i1) {
%exp = "math.exp"(%arg0) : (f32) -> f32
cf.cond_br %pred, ^true(%exp: f32), ^false(%exp: f32)
^true(%0: f32):
// CHECK-NEXT: func @g(%arg1: f32)
// CHECK-NEXT: return
-func @f(%arg0: f32) {
+func.func @f(%arg0: f32) {
func.func @g(%arg1: f32) {
%0 = "arith.addf"(%arg1, %arg1) : (f32, f32) -> f32
return
// CHECK-NEXT: [[VAL0:%.+]] = arith.addf %arg0, %arg0 : f32
// CHECK-NEXT: return [[VAL0]] : f32
-func @f(%arg0: f32) -> f32 {
+func.func @f(%arg0: f32) -> f32 {
%0 = "arith.addf"(%arg0, %arg0) : (f32, f32) -> f32
return %0 : f32
}
// CHECK-NEXT: "foo.print"(%arg0) : (f32) -> ()
// CHECK-NEXT: return
-func @f(%arg0: f32) {
+func.func @f(%arg0: f32) {
"foo.print"(%arg0) : (f32) -> ()
return
}
// CHECK-NEXT: "foo.has_region"
// CHECK-NEXT: "foo.return"
-func @f(%arg0: f32) {
+func.func @f(%arg0: f32) {
%0 = "math.exp"(%arg0) : (f32) -> f32
"foo.has_region"() ({
%1 = "math.exp"(%0) : (f32) -> f32
// CHECK-NEXT: return
-func @f(
+func.func @f(
%arg0: tensor<1xf32>,
%arg1: tensor<2xf32>,
%arg2: tensor<3xf32>,
// CHECK-NEXT: test.graph_region
// CHECK-NEXT: "test.terminator"() : () -> ()
-func @f() {
+func.func @f() {
test.graph_region {
%0 = "math.exp"(%1) : (f32) -> f32
%1 = "math.exp"(%0) : (f32) -> f32
// BU-LABEL: func @default_insertion_position
// TD-LABEL: func @default_insertion_position
-func @default_insertion_position(%cond: i1) {
+func.func @default_insertion_position(%cond: i1) {
// Constant should be folded into the entry block.
// BU: arith.constant 2
// wants to be the insertion point for the constant.
// BU-LABEL: func @custom_insertion_position
// TD-LABEL: func @custom_insertion_position
-func @custom_insertion_position() {
+func.func @custom_insertion_position() {
// BU: test.one_region_op
// BU-NEXT: arith.constant 2
// RUN: mlir-opt -allow-unregistered-dialect %s -pass-pipeline='func.func(canonicalize)' -split-input-file | FileCheck %s
// CHECK-LABEL: func @test_subi_zero
-func @test_subi_zero(%arg0: i32) -> i32 {
+func.func @test_subi_zero(%arg0: i32) -> i32 {
// CHECK-NEXT: %c0_i32 = arith.constant 0 : i32
// CHECK-NEXT: return %c0
%y = arith.subi %arg0, %arg0 : i32
}
// CHECK-LABEL: func @test_subi_zero_vector
-func @test_subi_zero_vector(%arg0: vector<4xi32>) -> vector<4xi32> {
+func.func @test_subi_zero_vector(%arg0: vector<4xi32>) -> vector<4xi32> {
//CHECK-NEXT: %cst = arith.constant dense<0> : vector<4xi32>
%y = arith.subi %arg0, %arg0 : vector<4xi32>
// CHECK-NEXT: return %cst
}
// CHECK-LABEL: func @test_subi_zero_tensor
-func @test_subi_zero_tensor(%arg0: tensor<4x5xi32>) -> tensor<4x5xi32> {
+func.func @test_subi_zero_tensor(%arg0: tensor<4x5xi32>) -> tensor<4x5xi32> {
//CHECK-NEXT: %cst = arith.constant dense<0> : tensor<4x5xi32>
%y = arith.subi %arg0, %arg0 : tensor<4x5xi32>
// CHECK-NEXT: return %cst
}
// CHECK-LABEL: func @dim
-func @dim(%arg0: tensor<8x4xf32>) -> index {
+func.func @dim(%arg0: tensor<8x4xf32>) -> index {
// CHECK: %c4 = arith.constant 4 : index
%c1 = arith.constant 1 : index
}
// CHECK-LABEL: func @test_commutative
-func @test_commutative(%arg0: i32) -> (i32, i32) {
+func.func @test_commutative(%arg0: i32) -> (i32, i32) {
// CHECK: %c42_i32 = arith.constant 42 : i32
%c42_i32 = arith.constant 42 : i32
// CHECK-NEXT: %0 = arith.addi %arg0, %c42_i32 : i32
}
// CHECK-LABEL: func @trivial_dce
-func @trivial_dce(%arg0: tensor<8x4xf32>) {
+func.func @trivial_dce(%arg0: tensor<8x4xf32>) {
%c1 = arith.constant 1 : index
%0 = tensor.dim %arg0, %c1 : tensor<8x4xf32>
// CHECK-NEXT: return
}
// CHECK-LABEL: func @load_dce
-func @load_dce(%arg0: index) {
+func.func @load_dce(%arg0: index) {
%c4 = arith.constant 4 : index
%a = memref.alloc(%c4) : memref<?xf32>
%2 = memref.load %a[%arg0] : memref<?xf32>
}
// CHECK-LABEL: func @addi_zero
-func @addi_zero(%arg0: i32) -> i32 {
+func.func @addi_zero(%arg0: i32) -> i32 {
// CHECK-NEXT: return %arg0
%c0_i32 = arith.constant 0 : i32
%y = arith.addi %c0_i32, %arg0 : i32
}
// CHECK-LABEL: func @addi_zero_index
-func @addi_zero_index(%arg0: index) -> index {
+func.func @addi_zero_index(%arg0: index) -> index {
// CHECK-NEXT: return %arg0
%c0_index = arith.constant 0 : index
%y = arith.addi %c0_index, %arg0 : index
// CHECK-LABEL: func @addi_zero_vector
-func @addi_zero_vector(%arg0: vector<4 x i32>) -> vector<4 x i32> {
+func.func @addi_zero_vector(%arg0: vector<4 x i32>) -> vector<4 x i32> {
// CHECK-NEXT: return %arg0
%c0_v4i32 = arith.constant dense<0> : vector<4 x i32>
%y = arith.addi %c0_v4i32, %arg0 : vector<4 x i32>
}
// CHECK-LABEL: func @addi_zero_tensor
-func @addi_zero_tensor(%arg0: tensor<4 x 5 x i32>) -> tensor<4 x 5 x i32> {
+func.func @addi_zero_tensor(%arg0: tensor<4 x 5 x i32>) -> tensor<4 x 5 x i32> {
// CHECK-NEXT: return %arg0
%c0_t45i32 = arith.constant dense<0> : tensor<4 x 5 x i32>
%y = arith.addi %arg0, %c0_t45i32 : tensor<4 x 5 x i32>
}
// CHECK-LABEL: func @muli_zero
-func @muli_zero(%arg0: i32) -> i32 {
+func.func @muli_zero(%arg0: i32) -> i32 {
// CHECK-NEXT: %c0_i32 = arith.constant 0 : i32
%c0_i32 = arith.constant 0 : i32
}
// CHECK-LABEL: func @muli_zero_index
-func @muli_zero_index(%arg0: index) -> index {
+func.func @muli_zero_index(%arg0: index) -> index {
// CHECK-NEXT: %[[CST:.*]] = arith.constant 0 : index
%c0_index = arith.constant 0 : index
}
// CHECK-LABEL: func @muli_zero_vector
-func @muli_zero_vector(%arg0: vector<4 x i32>) -> vector<4 x i32> {
+func.func @muli_zero_vector(%arg0: vector<4 x i32>) -> vector<4 x i32> {
// CHECK-NEXT: %cst = arith.constant dense<0> : vector<4xi32>
%cst = arith.constant dense<0> : vector<4 x i32>
}
// CHECK-LABEL: func @muli_zero_tensor
-func @muli_zero_tensor(%arg0: tensor<4 x 5 x i32>) -> tensor<4 x 5 x i32> {
+func.func @muli_zero_tensor(%arg0: tensor<4 x 5 x i32>) -> tensor<4 x 5 x i32> {
// CHECK-NEXT: %cst = arith.constant dense<0> : tensor<4x5xi32>
%cst = arith.constant dense<0> : tensor<4 x 5 x i32>
}
// CHECK-LABEL: func @muli_one
-func @muli_one(%arg0: i32) -> i32 {
+func.func @muli_one(%arg0: i32) -> i32 {
// CHECK-NEXT: return %arg0
%c0_i32 = arith.constant 1 : i32
%y = arith.muli %c0_i32, %arg0 : i32
}
// CHECK-LABEL: func @muli_one_index
-func @muli_one_index(%arg0: index) -> index {
+func.func @muli_one_index(%arg0: index) -> index {
// CHECK-NEXT: return %arg0
%c0_index = arith.constant 1 : index
%y = arith.muli %c0_index, %arg0 : index
}
// CHECK-LABEL: func @muli_one_vector
-func @muli_one_vector(%arg0: vector<4 x i32>) -> vector<4 x i32> {
+func.func @muli_one_vector(%arg0: vector<4 x i32>) -> vector<4 x i32> {
// CHECK-NEXT: return %arg0
%c1_v4i32 = arith.constant dense<1> : vector<4 x i32>
%y = arith.muli %c1_v4i32, %arg0 : vector<4 x i32>
}
// CHECK-LABEL: func @muli_one_tensor
-func @muli_one_tensor(%arg0: tensor<4 x 5 x i32>) -> tensor<4 x 5 x i32> {
+func.func @muli_one_tensor(%arg0: tensor<4 x 5 x i32>) -> tensor<4 x 5 x i32> {
// CHECK-NEXT: return %arg0
%c1_t45i32 = arith.constant dense<1> : tensor<4 x 5 x i32>
%y = arith.muli %arg0, %c1_t45i32 : tensor<4 x 5 x i32>
}
//CHECK-LABEL: func @and_self
-func @and_self(%arg0: i32) -> i32 {
+func.func @and_self(%arg0: i32) -> i32 {
//CHECK-NEXT: return %arg0
%1 = arith.andi %arg0, %arg0 : i32
return %1 : i32
}
//CHECK-LABEL: func @and_self_vector
-func @and_self_vector(%arg0: vector<4xi32>) -> vector<4xi32> {
+func.func @and_self_vector(%arg0: vector<4xi32>) -> vector<4xi32> {
//CHECK-NEXT: return %arg0
%1 = arith.andi %arg0, %arg0 : vector<4xi32>
return %1 : vector<4xi32>
}
//CHECK-LABEL: func @and_self_tensor
-func @and_self_tensor(%arg0: tensor<4x5xi32>) -> tensor<4x5xi32> {
+func.func @and_self_tensor(%arg0: tensor<4x5xi32>) -> tensor<4x5xi32> {
//CHECK-NEXT: return %arg0
%1 = arith.andi %arg0, %arg0 : tensor<4x5xi32>
return %1 : tensor<4x5xi32>
}
//CHECK-LABEL: func @and_zero
-func @and_zero(%arg0: i32) -> i32 {
+func.func @and_zero(%arg0: i32) -> i32 {
// CHECK-NEXT: %c0_i32 = arith.constant 0 : i32
%c0_i32 = arith.constant 0 : i32
// CHECK-NEXT: return %c0_i32
}
//CHECK-LABEL: func @and_zero_index
-func @and_zero_index(%arg0: index) -> index {
+func.func @and_zero_index(%arg0: index) -> index {
// CHECK-NEXT: %[[CST:.*]] = arith.constant 0 : index
%c0_index = arith.constant 0 : index
// CHECK-NEXT: return %[[CST]]
}
//CHECK-LABEL: func @and_zero_vector
-func @and_zero_vector(%arg0: vector<4xi32>) -> vector<4xi32> {
+func.func @and_zero_vector(%arg0: vector<4xi32>) -> vector<4xi32> {
// CHECK-NEXT: %cst = arith.constant dense<0> : vector<4xi32>
%cst = arith.constant dense<0> : vector<4xi32>
// CHECK-NEXT: return %cst
}
//CHECK-LABEL: func @and_zero_tensor
-func @and_zero_tensor(%arg0: tensor<4x5xi32>) -> tensor<4x5xi32> {
+func.func @and_zero_tensor(%arg0: tensor<4x5xi32>) -> tensor<4x5xi32> {
// CHECK-NEXT: %cst = arith.constant dense<0> : tensor<4x5xi32>
%cst = arith.constant dense<0> : tensor<4x5xi32>
// CHECK-NEXT: return %cst
}
//CHECK-LABEL: func @or_self
-func @or_self(%arg0: i32) -> i32 {
+func.func @or_self(%arg0: i32) -> i32 {
//CHECK-NEXT: return %arg0
%1 = arith.ori %arg0, %arg0 : i32
return %1 : i32
}
//CHECK-LABEL: func @or_self_vector
-func @or_self_vector(%arg0: vector<4xi32>) -> vector<4xi32> {
+func.func @or_self_vector(%arg0: vector<4xi32>) -> vector<4xi32> {
//CHECK-NEXT: return %arg0
%1 = arith.ori %arg0, %arg0 : vector<4xi32>
return %1 : vector<4xi32>
}
//CHECK-LABEL: func @or_self_tensor
-func @or_self_tensor(%arg0: tensor<4x5xi32>) -> tensor<4x5xi32> {
+func.func @or_self_tensor(%arg0: tensor<4x5xi32>) -> tensor<4x5xi32> {
//CHECK-NEXT: return %arg0
%1 = arith.ori %arg0, %arg0 : tensor<4x5xi32>
return %1 : tensor<4x5xi32>
}
//CHECK-LABEL: func @or_zero
-func @or_zero(%arg0: i32) -> i32 {
+func.func @or_zero(%arg0: i32) -> i32 {
%c0_i32 = arith.constant 0 : i32
// CHECK-NEXT: return %arg0
%1 = arith.ori %arg0, %c0_i32 : i32
}
//CHECK-LABEL: func @or_zero_index
-func @or_zero_index(%arg0: index) -> index {
+func.func @or_zero_index(%arg0: index) -> index {
%c0_index = arith.constant 0 : index
// CHECK-NEXT: return %arg0
%1 = arith.ori %arg0, %c0_index : index
}
//CHECK-LABEL: func @or_zero_vector
-func @or_zero_vector(%arg0: vector<4xi32>) -> vector<4xi32> {
+func.func @or_zero_vector(%arg0: vector<4xi32>) -> vector<4xi32> {
// CHECK-NEXT: return %arg0
%cst = arith.constant dense<0> : vector<4xi32>
%1 = arith.ori %arg0, %cst : vector<4xi32>
}
//CHECK-LABEL: func @or_zero_tensor
-func @or_zero_tensor(%arg0: tensor<4x5xi32>) -> tensor<4x5xi32> {
+func.func @or_zero_tensor(%arg0: tensor<4x5xi32>) -> tensor<4x5xi32> {
// CHECK-NEXT: return %arg0
%cst = arith.constant dense<0> : tensor<4x5xi32>
%1 = arith.ori %arg0, %cst : tensor<4x5xi32>
}
// CHECK-LABEL: func @or_all_ones
-func @or_all_ones(%arg0: i1, %arg1: i4) -> (i1, i4) {
+func.func @or_all_ones(%arg0: i1, %arg1: i4) -> (i1, i4) {
// CHECK-DAG: %c-1_i4 = arith.constant -1 : i4
// CHECK-DAG: %true = arith.constant true
%c1_i1 = arith.constant 1 : i1
}
//CHECK-LABEL: func @xor_self
-func @xor_self(%arg0: i32) -> i32 {
+func.func @xor_self(%arg0: i32) -> i32 {
//CHECK-NEXT: %c0_i32 = arith.constant 0
%1 = arith.xori %arg0, %arg0 : i32
//CHECK-NEXT: return %c0_i32
}
//CHECK-LABEL: func @xor_self_vector
-func @xor_self_vector(%arg0: vector<4xi32>) -> vector<4xi32> {
+func.func @xor_self_vector(%arg0: vector<4xi32>) -> vector<4xi32> {
//CHECK-NEXT: %cst = arith.constant dense<0> : vector<4xi32>
%1 = arith.xori %arg0, %arg0 : vector<4xi32>
//CHECK-NEXT: return %cst
}
//CHECK-LABEL: func @xor_self_tensor
-func @xor_self_tensor(%arg0: tensor<4x5xi32>) -> tensor<4x5xi32> {
+func.func @xor_self_tensor(%arg0: tensor<4x5xi32>) -> tensor<4x5xi32> {
//CHECK-NEXT: %cst = arith.constant dense<0> : tensor<4x5xi32>
%1 = arith.xori %arg0, %arg0 : tensor<4x5xi32>
//CHECK-NEXT: return %cst
}
// CHECK-LABEL: func @memref_cast_folding
-func @memref_cast_folding(%arg0: memref<4 x f32>, %arg1: f32) -> (f32, f32) {
+func.func @memref_cast_folding(%arg0: memref<4 x f32>, %arg1: f32) -> (f32, f32) {
%0 = memref.cast %arg0 : memref<4xf32> to memref<?xf32>
// CHECK-NEXT: %c0 = arith.constant 0 : index
%c0 = arith.constant 0 : index
// CHECK-LABEL: @fold_memref_cast_in_memref_cast
// CHECK-SAME: (%[[ARG0:.*]]: memref<42x42xf64>)
-func @fold_memref_cast_in_memref_cast(%0: memref<42x42xf64>) {
+func.func @fold_memref_cast_in_memref_cast(%0: memref<42x42xf64>) {
// CHECK: %[[folded:.*]] = memref.cast %[[ARG0]] : memref<42x42xf64> to memref<?x?xf64>
%4 = memref.cast %0 : memref<42x42xf64> to memref<?x42xf64>
// CHECK-NOT: memref.cast
// CHECK-LABEL: @fold_memref_cast_chain
// CHECK-SAME: (%[[ARG0:.*]]: memref<42x42xf64>)
-func @fold_memref_cast_chain(%0: memref<42x42xf64>) {
+func.func @fold_memref_cast_chain(%0: memref<42x42xf64>) {
// CHECK-NOT: memref.cast
%4 = memref.cast %0 : memref<42x42xf64> to memref<?x42xf64>
%5 = memref.cast %4 : memref<?x42xf64> to memref<42x42xf64>
}
// CHECK-LABEL: func @dead_alloc_fold
-func @dead_alloc_fold() {
+func.func @dead_alloc_fold() {
// CHECK-NEXT: return
%c4 = arith.constant 4 : index
%a = memref.alloc(%c4) : memref<?xf32>
}
// CHECK-LABEL: func @dead_dealloc_fold
-func @dead_dealloc_fold() {
+func.func @dead_dealloc_fold() {
// CHECK-NEXT: return
%a = memref.alloc() : memref<4xf32>
memref.dealloc %a: memref<4xf32>
}
// CHECK-LABEL: func @dead_dealloc_fold_multi_use
-func @dead_dealloc_fold_multi_use(%cond : i1) {
+func.func @dead_dealloc_fold_multi_use(%cond : i1) {
// CHECK-NEXT: return
%a = memref.alloc() : memref<4xf32>
cf.cond_br %cond, ^bb1, ^bb2
}
// CHECK-LABEL: func @write_only_alloc_fold
-func @write_only_alloc_fold(%v: f32) {
+func.func @write_only_alloc_fold(%v: f32) {
// CHECK-NEXT: return
%c0 = arith.constant 0 : index
%c4 = arith.constant 4 : index
}
// CHECK-LABEL: func @write_only_alloca_fold
-func @write_only_alloca_fold(%v: f32) {
+func.func @write_only_alloca_fold(%v: f32) {
// CHECK-NEXT: return
%c0 = arith.constant 0 : index
%c4 = arith.constant 4 : index
}
// CHECK-LABEL: func @dead_block_elim
-func @dead_block_elim() {
+func.func @dead_block_elim() {
// CHECK-NOT: ^bb
func.func @nested() {
return
}
// CHECK-LABEL: func @dyn_shape_fold(%arg0: index, %arg1: index)
-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>) {
+func.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>) {
// CHECK: %c0 = arith.constant 0 : index
%zero = arith.constant 0 : index
// The constants below disappear after they propagate into shapes.
// CHECK-SAME: %[[ARG1:[a-z0-9]*]]: index
// CHECK-SAME: %[[ARG2:[a-z0-9]*]]: index
// CHECK-SAME: %[[BUF:[a-z0-9]*]]: memref<?xi8>
-func @dim_op_fold(%arg0: index, %arg1: index, %arg2: index, %BUF: memref<?xi8>, %M : index, %N : index, %K : index) {
+func.func @dim_op_fold(%arg0: index, %arg1: index, %arg2: index, %BUF: memref<?xi8>, %M : index, %N : index, %K : index) {
// CHECK-SAME: [[M:arg[0-9]+]]: index
// CHECK-SAME: [[N:arg[0-9]+]]: index
// CHECK-SAME: [[K:arg[0-9]+]]: index
}
// CHECK-LABEL: func @merge_constants
-func @merge_constants() -> (index, index) {
+func.func @merge_constants() -> (index, index) {
// CHECK-NEXT: %c42 = arith.constant 42 : index
%0 = arith.constant 42 : index
%1 = arith.constant 42 : index
}
// CHECK-LABEL: func @hoist_constant
-func @hoist_constant(%arg0: memref<8xi32>) {
+func.func @hoist_constant(%arg0: memref<8xi32>) {
// CHECK-NEXT: %c42_i32 = arith.constant 42 : i32
// CHECK-NEXT: affine.for %arg1 = 0 to 8 {
affine.for %arg1 = 0 to 8 {
}
// CHECK-LABEL: func @const_fold_propagate
-func @const_fold_propagate() -> memref<?x?xf32> {
+func.func @const_fold_propagate() -> memref<?x?xf32> {
%VT_i = arith.constant 512 : index
%VT_i_s = affine.apply affine_map<(d0) -> (d0 floordiv 8)> (%VT_i)
}
// CHECK-LABEL: func @indirect_call_folding
-func @indirect_target() {
+func.func @indirect_target() {
return
}
-func @indirect_call_folding() {
+func.func @indirect_call_folding() {
// CHECK-NEXT: call @indirect_target() : () -> ()
// CHECK-NEXT: return
%indirect_fn = constant @indirect_target : () -> ()
// change these operations together with the affine lowering pass tests.
//
// CHECK-LABEL: @lowered_affine_mod
-func @lowered_affine_mod() -> (index, index) {
+func.func @lowered_affine_mod() -> (index, index) {
// CHECK-DAG: {{.*}} = arith.constant 1 : index
// CHECK-DAG: {{.*}} = arith.constant 41 : index
%c-43 = arith.constant -43 : index
// change these operations together with the affine lowering pass tests.
//
// CHECK-LABEL: func @lowered_affine_floordiv
-func @lowered_affine_floordiv() -> (index, index) {
+func.func @lowered_affine_floordiv() -> (index, index) {
// CHECK-DAG: %c1 = arith.constant 1 : index
// CHECK-DAG: %c-2 = arith.constant -2 : index
%c-43 = arith.constant -43 : index
// change these operations together with the affine lowering pass tests.
//
// CHECK-LABEL: func @lowered_affine_ceildiv
-func @lowered_affine_ceildiv() -> (index, index) {
+func.func @lowered_affine_ceildiv() -> (index, index) {
// CHECK-DAG: %c-1 = arith.constant -1 : index
%c-43 = arith.constant -43 : index
%c42 = arith.constant 42 : index
// Checks that NOP casts are removed.
// CHECK-LABEL: cast_values
-func @cast_values(%arg0: memref<?xi32>) -> memref<2xi32> {
+func.func @cast_values(%arg0: memref<?xi32>) -> memref<2xi32> {
// NOP cast
%1 = memref.cast %arg0 : memref<?xi32> to memref<?xi32>
// CHECK-NEXT: %[[RET:.*]] = memref.cast %arg0 : memref<?xi32> to memref<2xi32>
// -----
// CHECK-LABEL: func @view
-func @view(%arg0 : index) -> (f32, f32, f32, f32) {
+func.func @view(%arg0 : index) -> (f32, f32, f32, f32) {
// CHECK: %[[C15:.*]] = arith.constant 15 : index
// CHECK: %[[ALLOC_MEM:.*]] = memref.alloc() : memref<2048xi8>
%0 = memref.alloc() : memref<2048xi8>
// CHECK-LABEL: func @subview
// CHECK-SAME: %[[ARG0:.*]]: index, %[[ARG1:.*]]: index
-func @subview(%arg0 : index, %arg1 : index) -> (index, index) {
+func.func @subview(%arg0 : index, %arg1 : index) -> (index, index) {
// Folded but reappears after subview folding into dim.
// CHECK-DAG: %[[C0:.*]] = arith.constant 0 : index
// CHECK-DAG: %[[C7:.*]] = arith.constant 7 : index
// CHECK-LABEL: func @index_cast
// CHECK-SAME: %[[ARG_0:arg[0-9]+]]: i16
-func @index_cast(%arg0: i16) -> (i16) {
+func.func @index_cast(%arg0: i16) -> (i16) {
%11 = arith.index_cast %arg0 : i16 to index
%12 = arith.index_cast %11 : index to i16
// CHECK: return %[[ARG_0]] : i16
}
// CHECK-LABEL: func @index_cast_fold
-func @index_cast_fold() -> (i16, index) {
+func.func @index_cast_fold() -> (i16, index) {
%c4 = arith.constant 4 : index
%1 = arith.index_cast %c4 : index to i16
%c4_i16 = arith.constant 4 : i16
}
// CHECK-LABEL: func @remove_dead_else
-func @remove_dead_else(%M : memref<100 x i32>) {
+func.func @remove_dead_else(%M : memref<100 x i32>) {
affine.for %i = 0 to 100 {
affine.load %M[%i] : memref<100xi32>
affine.if affine_set<(d0) : (d0 - 2 >= 0)>(%i) {
// CHECK-LABEL: func @divi_signed_by_one
// CHECK-SAME: %[[ARG:[a-zA-Z0-9]+]]
-func @divi_signed_by_one(%arg0: i32) -> (i32) {
+func.func @divi_signed_by_one(%arg0: i32) -> (i32) {
%c1 = arith.constant 1 : i32
%res = arith.divsi %arg0, %c1 : i32
// CHECK: return %[[ARG]]
// CHECK-LABEL: func @divi_unsigned_by_one
// CHECK-SAME: %[[ARG:[a-zA-Z0-9]+]]
-func @divi_unsigned_by_one(%arg0: i32) -> (i32) {
+func.func @divi_unsigned_by_one(%arg0: i32) -> (i32) {
%c1 = arith.constant 1 : i32
%res = arith.divui %arg0, %c1 : i32
// CHECK: return %[[ARG]]
// CHECK-LABEL: func @tensor_divi_signed_by_one
// CHECK-SAME: %[[ARG:[a-zA-Z0-9]+]]
-func @tensor_divi_signed_by_one(%arg0: tensor<4x5xi32>) -> tensor<4x5xi32> {
+func.func @tensor_divi_signed_by_one(%arg0: tensor<4x5xi32>) -> tensor<4x5xi32> {
%c1 = arith.constant dense<1> : tensor<4x5xi32>
%res = arith.divsi %arg0, %c1 : tensor<4x5xi32>
// CHECK: return %[[ARG]]
// CHECK-LABEL: func @tensor_divi_unsigned_by_one
// CHECK-SAME: %[[ARG:[a-zA-Z0-9]+]]
-func @tensor_divi_unsigned_by_one(%arg0: tensor<4x5xi32>) -> tensor<4x5xi32> {
+func.func @tensor_divi_unsigned_by_one(%arg0: tensor<4x5xi32>) -> tensor<4x5xi32> {
%c1 = arith.constant dense<1> : tensor<4x5xi32>
%res = arith.divui %arg0, %c1 : tensor<4x5xi32>
// CHECK: return %[[ARG]]
// CHECK-LABEL: func @arith.floordivsi_by_one
// CHECK-SAME: %[[ARG:[a-zA-Z0-9]+]]
-func @arith.floordivsi_by_one(%arg0: i32) -> (i32) {
+func.func @arith.floordivsi_by_one(%arg0: i32) -> (i32) {
%c1 = arith.constant 1 : i32
%res = arith.floordivsi %arg0, %c1 : i32
// CHECK: return %[[ARG]]
// CHECK-LABEL: func @tensor_arith.floordivsi_by_one
// CHECK-SAME: %[[ARG:[a-zA-Z0-9]+]]
-func @tensor_arith.floordivsi_by_one(%arg0: tensor<4x5xi32>) -> tensor<4x5xi32> {
+func.func @tensor_arith.floordivsi_by_one(%arg0: tensor<4x5xi32>) -> tensor<4x5xi32> {
%c1 = arith.constant dense<1> : tensor<4x5xi32>
%res = arith.floordivsi %arg0, %c1 : tensor<4x5xi32>
// CHECK: return %[[ARG]]
// CHECK-LABEL: func @arith.ceildivsi_by_one
// CHECK-SAME: %[[ARG:[a-zA-Z0-9]+]]
-func @arith.ceildivsi_by_one(%arg0: i32) -> (i32) {
+func.func @arith.ceildivsi_by_one(%arg0: i32) -> (i32) {
%c1 = arith.constant 1 : i32
%res = arith.ceildivsi %arg0, %c1 : i32
// CHECK: return %[[ARG]]
// CHECK-LABEL: func @tensor_arith.ceildivsi_by_one
// CHECK-SAME: %[[ARG:[a-zA-Z0-9]+]]
-func @tensor_arith.ceildivsi_by_one(%arg0: tensor<4x5xi32>) -> tensor<4x5xi32> {
+func.func @tensor_arith.ceildivsi_by_one(%arg0: tensor<4x5xi32>) -> tensor<4x5xi32> {
%c1 = arith.constant dense<1> : tensor<4x5xi32>
%res = arith.ceildivsi %arg0, %c1 : tensor<4x5xi32>
// CHECK: return %[[ARG]]
// CHECK-LABEL: func @arith.ceildivui_by_one
// CHECK-SAME: %[[ARG:[a-zA-Z0-9]+]]
-func @arith.ceildivui_by_one(%arg0: i32) -> (i32) {
+func.func @arith.ceildivui_by_one(%arg0: i32) -> (i32) {
%c1 = arith.constant 1 : i32
%res = arith.ceildivui %arg0, %c1 : i32
// CHECK: return %[[ARG]]
// CHECK-LABEL: func @tensor_arith.ceildivui_by_one
// CHECK-SAME: %[[ARG:[a-zA-Z0-9]+]]
-func @tensor_arith.ceildivui_by_one(%arg0: tensor<4x5xi32>) -> tensor<4x5xi32> {
+func.func @tensor_arith.ceildivui_by_one(%arg0: tensor<4x5xi32>) -> tensor<4x5xi32> {
%c1 = arith.constant dense<1> : tensor<4x5xi32>
%res = arith.ceildivui %arg0, %c1 : tensor<4x5xi32>
// CHECK: return %[[ARG]]
// -----
// CHECK-LABEL: func @memref_cast_folding_subview
-func @memref_cast_folding_subview(%arg0: memref<4x5xf32>, %i: index) -> (memref<?x?xf32, offset:? , strides: [?, ?]>) {
+func.func @memref_cast_folding_subview(%arg0: memref<4x5xf32>, %i: index) -> (memref<?x?xf32, offset:? , strides: [?, ?]>) {
%0 = memref.cast %arg0 : memref<4x5xf32> to memref<?x?xf32>
// CHECK-NEXT: memref.subview %{{.*}}: memref<4x5xf32>
%1 = memref.subview %0[%i, %i][%i, %i][%i, %i]: memref<?x?xf32> to memref<?x?xf32, offset:? , strides: [?, ?]>
// CHECK-DAG: #[[$map1:.*]] = affine_map<(d0, d1)[s0, s1] -> (d0 * s1 + s0 + d1)>
// CHECK-LABEL: func @memref_cast_folding_subview_static(
-func @memref_cast_folding_subview_static(%V: memref<16x16xf32>, %a: index, %b: index)
+func.func @memref_cast_folding_subview_static(%V: memref<16x16xf32>, %a: index, %b: index)
-> memref<3x4xf32, offset:?, strides:[?, 1]>
{
%0 = memref.cast %V : memref<16x16xf32> to memref<?x?xf32>
// CHECK-LABEL: func @slice
// CHECK-SAME: %[[ARG0:[0-9a-z]*]]: index, %[[ARG1:[0-9a-z]*]]: index
-func @slice(%t: tensor<8x16x4xf32>, %arg0 : index, %arg1 : index)
+func.func @slice(%t: tensor<8x16x4xf32>, %arg0 : index, %arg1 : index)
-> tensor<?x?x?xf32>
{
%c0 = arith.constant 0 : index
// CHECK-LABEL: func @fold_trunci
// CHECK-SAME: (%[[ARG0:[0-9a-z]*]]: i1)
-func @fold_trunci(%arg0: i1) -> i1 attributes {} {
+func.func @fold_trunci(%arg0: i1) -> i1 attributes {} {
// CHECK-NEXT: return %[[ARG0]] : i1
%0 = arith.extui %arg0 : i1 to i8
%1 = arith.trunci %0 : i8 to i1
// CHECK-LABEL: func @fold_trunci_vector
// CHECK-SAME: (%[[ARG0:[0-9a-z]*]]: vector<4xi1>)
-func @fold_trunci_vector(%arg0: vector<4xi1>) -> vector<4xi1> attributes {} {
+func.func @fold_trunci_vector(%arg0: vector<4xi1>) -> vector<4xi1> attributes {} {
// CHECK-NEXT: return %[[ARG0]] : vector<4xi1>
%0 = arith.extui %arg0 : vector<4xi1> to vector<4xi8>
%1 = arith.trunci %0 : vector<4xi8> to vector<4xi1>
// CHECK-LABEL: func @do_not_fold_trunci
// CHECK-SAME: (%[[ARG0:[0-9a-z]*]]: i1)
-func @do_not_fold_trunci(%arg0: i1) -> i2 attributes {} {
+func.func @do_not_fold_trunci(%arg0: i1) -> i2 attributes {} {
// CHECK-NEXT: arith.extui %[[ARG0]] : i1 to i8
// CHECK-NEXT: %[[RES:[0-9a-z]*]] = arith.trunci %{{.*}} : i8 to i2
// CHECK-NEXT: return %[[RES]] : i2
// CHECK-LABEL: func @do_not_fold_trunci_vector
// CHECK-SAME: (%[[ARG0:[0-9a-z]*]]: vector<4xi1>)
-func @do_not_fold_trunci_vector(%arg0: vector<4xi1>) -> vector<4xi2> attributes {} {
+func.func @do_not_fold_trunci_vector(%arg0: vector<4xi1>) -> vector<4xi2> attributes {} {
// CHECK-NEXT: arith.extui %[[ARG0]] : vector<4xi1> to vector<4xi8>
// CHECK-NEXT: %[[RES:[0-9a-z]*]] = arith.trunci %{{.*}} : vector<4xi8> to vector<4xi2>
// CHECK-NEXT: return %[[RES]] : vector<4xi2>
// CHECK-LABEL: func @fold_trunci_sexti
// CHECK-SAME: (%[[ARG0:[0-9a-z]*]]: i1)
-func @fold_trunci_sexti(%arg0: i1) -> i1 attributes {} {
+func.func @fold_trunci_sexti(%arg0: i1) -> i1 attributes {} {
// CHECK-NEXT: return %[[ARG0]] : i1
%0 = arith.extsi %arg0 : i1 to i8
%1 = arith.trunci %0 : i8 to i1
}
// CHECK-LABEL: func @simple_clone_elimination
-func @simple_clone_elimination() -> memref<5xf32> {
+func.func @simple_clone_elimination() -> memref<5xf32> {
%ret = memref.alloc() : memref<5xf32>
%temp = bufferization.clone %ret : memref<5xf32> to memref<5xf32>
memref.dealloc %temp : memref<5xf32>
// -----
// CHECK-LABEL: func @clone_loop_alloc
-func @clone_loop_alloc(%arg0: index, %arg1: index, %arg2: index, %arg3: memref<2xf32>, %arg4: memref<2xf32>) {
+func.func @clone_loop_alloc(%arg0: index, %arg1: index, %arg2: index, %arg3: memref<2xf32>, %arg4: memref<2xf32>) {
%0 = memref.alloc() : memref<2xf32>
memref.dealloc %0 : memref<2xf32>
%1 = bufferization.clone %arg3 : memref<2xf32> to memref<2xf32>
// -----
// CHECK-LABEL: func @clone_nested_region
-func @clone_nested_region(%arg0: index, %arg1: index, %arg2: index) -> memref<?x?xf32> {
+func.func @clone_nested_region(%arg0: index, %arg1: index, %arg2: index) -> memref<?x?xf32> {
%cmp = arith.cmpi eq, %arg0, %arg1 : index
%0 = arith.cmpi eq, %arg0, %arg1 : index
%1 = memref.alloc(%arg0, %arg0) : memref<?x?xf32>
#map0 = affine_map<(d0, d1) -> (d0 * 1024 + d1 + 2304)>
#map1 = affine_map<(d0, d1) -> (d0 * 1024 + d1 + 3456)>
-func @main(%input: memref<4x1024xf32>) -> memref<1x128xf32, #map1> {
+func.func @main(%input: memref<4x1024xf32>) -> memref<1x128xf32, #map1> {
// CHECK: subview %arg0[3, 384] [1, 128] [1, 1]
// CHECK-SAME: memref<4x1024xf32> to memref<1x128xf32, [[MAP]]>
%0 = memref.subview %input[2, 256] [2, 256] [1, 1] : memref<4x1024xf32> to memref<2x256xf32, #map0>
#map1 = affine_map<(d0, d1) -> (d0 * 1024 + d1 + 2688)>
#map2 = affine_map<(d0, d1) -> (d0 * 1024 + d1 + 3745)>
-func @main(%input: memref<4x1024xf32>) -> memref<1x10xf32, #map2> {
+func.func @main(%input: memref<4x1024xf32>) -> memref<1x10xf32, #map2> {
// CHECK: subview %arg0[3, 673] [1, 10] [1, 1]
// CHECK-SAME: memref<4x1024xf32> to memref<1x10xf32, [[MAP]]>
%0 = memref.subview %input[1, 512] [3, 256] [1, 1] : memref<4x1024xf32> to memref<3x256xf32, #map0>
// CHECK: [[MAP:#.*]] = affine_map<(d0, d1)[s0] -> (d0 * 1024 + s0 + d1)
#map = affine_map<(d0, d1)[s0] -> (d0 * 1024 + s0 + d1)>
-func @main(%input: memref<4x1024xf32>) -> memref<1x128xf32, #map> {
+func.func @main(%input: memref<4x1024xf32>) -> memref<1x128xf32, #map> {
// CHECK: [[CST_3:%.*]] = arith.constant 3 : index
%cst_1 = arith.constant 1 : index
%cst_2 = arith.constant 2 : index
// CHECK: [[MAP:#.*]] = affine_map<(d0, d1)[s0] -> (d0 * 1024 + s0 + d1)
#map = affine_map<(d0, d1)[s0] -> (d0 * 1024 + s0 + d1)>
-func @main(%input: memref<4x1024xf32>) -> memref<1x128xf32, #map> {
+func.func @main(%input: memref<4x1024xf32>) -> memref<1x128xf32, #map> {
// CHECK: [[CST_3:%.*]] = arith.constant 3 : index
%cst_2 = arith.constant 2 : index
// CHECK: [[CST_384:%.*]] = arith.constant 384 : index
// CHECK-LABEL: @affine_for
// CHECK-SAME: [[ARG:%[a-zA-Z0-9]+]]
-func @affine_for(%p : memref<f32>) {
+func.func @affine_for(%p : memref<f32>) {
// CHECK: [[C:%.+]] = arith.constant 6.{{0*}}e+00 : f32
affine.for %arg1 = 0 to 128 {
affine.for %arg2 = 0 to 8 { // CHECK: affine.for %{{.*}} = 0 to 8 {
// -----
// CHECK-LABEL: func @simple_addf
-func @simple_addf() -> f32 {
+func.func @simple_addf() -> f32 {
%0 = arith.constant 4.5 : f32
%1 = arith.constant 1.5 : f32
// -----
// CHECK-LABEL: func @addf_splat_tensor
-func @addf_splat_tensor() -> tensor<4xf32> {
+func.func @addf_splat_tensor() -> tensor<4xf32> {
%0 = arith.constant dense<4.5> : tensor<4xf32>
%1 = arith.constant dense<1.5> : tensor<4xf32>
// -----
// CHECK-LABEL: func @addf_dense_tensor
-func @addf_dense_tensor() -> tensor<4xf32> {
+func.func @addf_dense_tensor() -> tensor<4xf32> {
%0 = arith.constant dense<[1.5, 2.5, 3.5, 4.5]> : tensor<4xf32>
%1 = arith.constant dense<[1.5, 2.5, 3.5, 4.5]> : tensor<4xf32>
// -----
// CHECK-LABEL: func @addf_dense_and_splat_tensors
-func @addf_dense_and_splat_tensors() -> tensor<4xf32> {
+func.func @addf_dense_and_splat_tensors() -> tensor<4xf32> {
%0 = arith.constant dense<[1.5, 2.5, 3.5, 4.5]> : tensor<4xf32>
%1 = arith.constant dense<1.5> : tensor<4xf32>
// -----
// CHECK-LABEL: func @simple_addi
-func @simple_addi() -> i32 {
+func.func @simple_addi() -> i32 {
%0 = arith.constant 1 : i32
%1 = arith.constant 5 : i32
// CHECK: func @simple_and
// CHECK-SAME: [[ARG0:%[a-zA-Z0-9]+]]: i1
// CHECK-SAME: [[ARG1:%[a-zA-Z0-9]+]]: i32)
-func @simple_and(%arg0 : i1, %arg1 : i32) -> (i1, i32) {
+func.func @simple_and(%arg0 : i1, %arg1 : i32) -> (i1, i32) {
%c1 = arith.constant 1 : i1
%cAllOnes_32 = arith.constant 4294967295 : i32
// CHECK-LABEL: func @and_index
// CHECK-SAME: [[ARG:%[a-zA-Z0-9]+]]
-func @and_index(%arg0 : index) -> (index) {
+func.func @and_index(%arg0 : index) -> (index) {
// CHECK: [[C31:%.*]] = arith.constant 31 : index
%c31 = arith.constant 31 : index
%c_AllOnes = arith.constant -1 : index
// CHECK: func @tensor_and
// CHECK-SAME: [[ARG0:%[a-zA-Z0-9]+]]: tensor<2xi32>
-func @tensor_and(%arg0 : tensor<2xi32>) -> tensor<2xi32> {
+func.func @tensor_and(%arg0 : tensor<2xi32>) -> tensor<2xi32> {
%cAllOnes_32 = arith.constant dense<4294967295> : tensor<2xi32>
// CHECK: [[C31:%.*]] = arith.constant dense<31> : tensor<2xi32>
// CHECK: func @vector_and
// CHECK-SAME: [[ARG0:%[a-zA-Z0-9]+]]: vector<2xi32>
-func @vector_and(%arg0 : vector<2xi32>) -> vector<2xi32> {
+func.func @vector_and(%arg0 : vector<2xi32>) -> vector<2xi32> {
%cAllOnes_32 = arith.constant dense<4294967295> : vector<2xi32>
// CHECK: [[C31:%.*]] = arith.constant dense<31> : vector<2xi32>
// -----
// CHECK-LABEL: func @addi_splat_vector
-func @addi_splat_vector() -> vector<8xi32> {
+func.func @addi_splat_vector() -> vector<8xi32> {
%0 = arith.constant dense<1> : vector<8xi32>
%1 = arith.constant dense<5> : vector<8xi32>
// -----
// CHECK-LABEL: func @simple_subf
-func @simple_subf() -> f32 {
+func.func @simple_subf() -> f32 {
%0 = arith.constant 4.5 : f32
%1 = arith.constant 1.5 : f32
// -----
// CHECK-LABEL: func @subf_splat_vector
-func @subf_splat_vector() -> vector<4xf32> {
+func.func @subf_splat_vector() -> vector<4xf32> {
%0 = arith.constant dense<4.5> : vector<4xf32>
%1 = arith.constant dense<1.5> : vector<4xf32>
// CHECK: func @simple_subi
// CHECK-SAME: [[ARG0:%[a-zA-Z0-9]+]]
-func @simple_subi(%arg0 : i32) -> (i32, i32) {
+func.func @simple_subi(%arg0 : i32) -> (i32, i32) {
%0 = arith.constant 4 : i32
%1 = arith.constant 1 : i32
%2 = arith.constant 0 : i32
// -----
// CHECK-LABEL: func @subi_splat_tensor
-func @subi_splat_tensor() -> tensor<4xi32> {
+func.func @subi_splat_tensor() -> tensor<4xi32> {
%0 = arith.constant dense<4> : tensor<4xi32>
%1 = arith.constant dense<1> : tensor<4xi32>
// -----
// CHECK-LABEL: func @affine_apply
-func @affine_apply(%variable : index) -> (index, index, index) {
+func.func @affine_apply(%variable : index) -> (index, index, index) {
%c177 = arith.constant 177 : index
%c211 = arith.constant 211 : index
%N = arith.constant 1075 : index
// -----
// CHECK-LABEL: func @simple_mulf
-func @simple_mulf() -> f32 {
+func.func @simple_mulf() -> f32 {
%0 = arith.constant 4.5 : f32
%1 = arith.constant 1.5 : f32
// -----
// CHECK-LABEL: func @mulf_splat_tensor
-func @mulf_splat_tensor() -> tensor<4xf32> {
+func.func @mulf_splat_tensor() -> tensor<4xf32> {
%0 = arith.constant dense<4.5> : tensor<4xf32>
%1 = arith.constant dense<1.5> : tensor<4xf32>
// -----
// CHECK-LABEL: func @simple_divi_signed
-func @simple_divi_signed() -> (i32, i32, i32) {
+func.func @simple_divi_signed() -> (i32, i32, i32) {
// CHECK-DAG: [[C0:%.+]] = arith.constant 0
%z = arith.constant 0 : i32
// CHECK-DAG: [[C6:%.+]] = arith.constant 6
// -----
// CHECK-LABEL: func @divi_signed_splat_tensor
-func @divi_signed_splat_tensor() -> (tensor<4xi32>, tensor<4xi32>, tensor<4xi32>) {
+func.func @divi_signed_splat_tensor() -> (tensor<4xi32>, tensor<4xi32>, tensor<4xi32>) {
// CHECK-DAG: [[C0:%.+]] = arith.constant dense<0>
%z = arith.constant dense<0> : tensor<4xi32>
// CHECK-DAG: [[C6:%.+]] = arith.constant dense<6>
// -----
// CHECK-LABEL: func @simple_divi_unsigned
-func @simple_divi_unsigned() -> (i32, i32, i32) {
+func.func @simple_divi_unsigned() -> (i32, i32, i32) {
%z = arith.constant 0 : i32
// CHECK-DAG: [[C6:%.+]] = arith.constant 6
%0 = arith.constant 6 : i32
// -----
// CHECK-LABEL: func @divi_unsigned_splat_tensor
-func @divi_unsigned_splat_tensor() -> (tensor<4xi32>, tensor<4xi32>, tensor<4xi32>) {
+func.func @divi_unsigned_splat_tensor() -> (tensor<4xi32>, tensor<4xi32>, tensor<4xi32>) {
%z = arith.constant dense<0> : tensor<4xi32>
// CHECK-DAG: [[C6:%.+]] = arith.constant dense<6>
%0 = arith.constant dense<6> : tensor<4xi32>
// -----
// CHECK-LABEL: func @simple_arith.floordivsi
-func @simple_arith.floordivsi() -> (i32, i32, i32, i32, i32) {
+func.func @simple_arith.floordivsi() -> (i32, i32, i32, i32, i32) {
// CHECK-DAG: [[C0:%.+]] = arith.constant 0
%z = arith.constant 0 : i32
// CHECK-DAG: [[C6:%.+]] = arith.constant 7
// -----
// CHECK-LABEL: func @simple_arith.ceildivsi
-func @simple_arith.ceildivsi() -> (i32, i32, i32, i32, i32) {
+func.func @simple_arith.ceildivsi() -> (i32, i32, i32, i32, i32) {
// CHECK-DAG: [[C0:%.+]] = arith.constant 0
%z = arith.constant 0 : i32
// CHECK-DAG: [[C6:%.+]] = arith.constant 7
// -----
// CHECK-LABEL: func @simple_arith.ceildivui
-func @simple_arith.ceildivui() -> (i32, i32, i32, i32, i32) {
+func.func @simple_arith.ceildivui() -> (i32, i32, i32, i32, i32) {
// CHECK-DAG: [[C0:%.+]] = arith.constant 0
%z = arith.constant 0 : i32
// CHECK-DAG: [[C6:%.+]] = arith.constant 7
// -----
// CHECK-LABEL: func @simple_arith.remsi
-func @simple_arith.remsi(%a : i32) -> (i32, i32, i32) {
+func.func @simple_arith.remsi(%a : i32) -> (i32, i32, i32) {
%0 = arith.constant 5 : i32
%1 = arith.constant 2 : i32
%2 = arith.constant 1 : i32
// -----
// CHECK-LABEL: func @simple_arith.remui
-func @simple_arith.remui(%a : i32) -> (i32, i32, i32) {
+func.func @simple_arith.remui(%a : i32) -> (i32, i32, i32) {
%0 = arith.constant 5 : i32
%1 = arith.constant 2 : i32
%2 = arith.constant 1 : i32
// -----
// CHECK-LABEL: func @muli
-func @muli() -> i32 {
+func.func @muli() -> i32 {
%0 = arith.constant 4 : i32
%1 = arith.constant 2 : i32
// -----
// CHECK-LABEL: func @muli_splat_vector
-func @muli_splat_vector() -> vector<4xi32> {
+func.func @muli_splat_vector() -> vector<4xi32> {
%0 = arith.constant dense<4> : vector<4xi32>
%1 = arith.constant dense<2> : vector<4xi32>
}
// CHECK-LABEL: func @dim
-func @dim(%x : tensor<8x4xf32>) -> index {
+func.func @dim(%x : tensor<8x4xf32>) -> index {
// CHECK:[[C4:%.+]] = arith.constant 4 : index
%c1 = arith.constant 1 : index
// -----
// CHECK-LABEL: func @cmpi
-func @cmpi() -> (i1, i1, i1, i1, i1, i1, i1, i1, i1, i1) {
+func.func @cmpi() -> (i1, i1, i1, i1, i1, i1, i1, i1, i1, i1) {
%c42 = arith.constant 42 : i32
%cm1 = arith.constant -1 : i32
// CHECK-DAG: [[F:%.+]] = arith.constant false
// -----
// CHECK-LABEL: func @cmpf_normal_numbers
-func @cmpf_normal_numbers() -> (i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1) {
+func.func @cmpf_normal_numbers() -> (i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1) {
%c42 = arith.constant 42. : f32
%cm1 = arith.constant -1. : f32
// CHECK-DAG: [[F:%.+]] = arith.constant false
// -----
// CHECK-LABEL: func @cmpf_nan
-func @cmpf_nan() -> (i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1) {
+func.func @cmpf_nan() -> (i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1) {
%c42 = arith.constant 42. : f32
%cqnan = arith.constant 0xFFFFFFFF : f32
// CHECK-DAG: [[F:%.+]] = arith.constant false
// -----
// CHECK-LABEL: func @cmpf_inf
-func @cmpf_inf() -> (i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1) {
+func.func @cmpf_inf() -> (i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1) {
%c42 = arith.constant 42. : f32
%cpinf = arith.constant 0x7F800000 : f32
// CHECK-DAG: [[F:%.+]] = arith.constant false
// -----
// CHECK-LABEL: func @nested_isolated_region
-func @nested_isolated_region() {
+func.func @nested_isolated_region() {
// CHECK-NEXT: func @isolated_op
// CHECK-NEXT: arith.constant 2
func.func @isolated_op() {
// -----
// CHECK-LABEL: func @custom_insertion_position
-func @custom_insertion_position() {
+func.func @custom_insertion_position() {
// CHECK: test.one_region_op
// CHECK-NEXT: arith.constant 2
"test.one_region_op"() ({
// -----
// CHECK-LABEL: func @subview_scalar_fold
-func @subview_scalar_fold(%arg0: memref<f32>) -> memref<f32> {
+func.func @subview_scalar_fold(%arg0: memref<f32>) -> memref<f32> {
// CHECK-NOT: memref.subview
%c = memref.subview %arg0[] [] [] : memref<f32> to memref<f32>
return %c : memref<f32>
// RUN: mlir-opt -test-control-flow-sink %s | FileCheck %s
// CHECK-LABEL: func @test_sink
-func @test_sink() {
+func.func @test_sink() {
%0 = "test.sink_me"() : () -> i32
// CHECK-NEXT: test.sink_target
"test.sink_target"() ({
}
// CHECK-LABEL: func @test_sink_first_region_only
-func @test_sink_first_region_only() {
+func.func @test_sink_first_region_only() {
%0 = "test.sink_me"() {first} : () -> i32
// CHECK-NEXT: %[[V1:.*]] = "test.sink_me"() {second}
%1 = "test.sink_me"() {second} : () -> i32
}
// CHECK-LABEL: func @test_sink_targeted_op_only
-func @test_sink_targeted_op_only() {
+func.func @test_sink_targeted_op_only() {
%0 = "test.sink_me"() : () -> i32
// CHECK-NEXT: %[[V1:.*]] = "test.dont_sink_me"
%1 = "test.dont_sink_me"() : () -> i32
// CHECK-NEXT: test.region_if_yield %[[V3]]
// CHECK-NEXT: }
// CHECK-NEXT: return %[[V1]]
-func @test_simple_sink(%arg0: i32, %arg1: i32, %arg2: i32) -> i32 {
+func.func @test_simple_sink(%arg0: i32, %arg1: i32, %arg2: i32) -> i32 {
%0 = arith.subi %arg1, %arg2 : i32
%1 = arith.subi %arg2, %arg1 : i32
%2 = arith.addi %arg1, %arg1 : i32
// CHECK-NEXT: test.region_if_yield %[[ARG2]]
// CHECK-NEXT: }
// CHECK-NEXT: return %[[V0]]
-func @test_region_sink(%arg0: i32, %arg1: i32, %arg2: i32) -> i32 {
+func.func @test_region_sink(%arg0: i32, %arg1: i32, %arg2: i32) -> i32 {
%0 = arith.subi %arg1, %arg2 : i32
%1 = test.region_if %arg0: i32 -> i32 then {
^bb0(%arg3: i32):
// CHECK-NEXT: test.region_if_yield %[[ARG2]]
// CHECK-NEXT: }
// CHECK-NEXT: return %[[V0]]
-func @test_subgraph_sink(%arg0: i32, %arg1: i32, %arg2: i32) -> i32 {
+func.func @test_subgraph_sink(%arg0: i32, %arg1: i32, %arg2: i32) -> i32 {
%0 = arith.addi %arg1, %arg2 : i32
%1 = arith.subi %arg1, %arg2 : i32
%2 = arith.subi %arg2, %arg1 : i32
// CHECK-NEXT: })
// CHECK-NEXT: %[[V2:.*]] = arith.addi %[[V0]], %[[V1]]
// CHECK-NEXT: return %[[V2]]
-func @test_multiblock_region_sink(%arg0: i32, %arg1: i32, %arg2: i32) -> i32 {
+func.func @test_multiblock_region_sink(%arg0: i32, %arg1: i32, %arg2: i32) -> i32 {
%0 = arith.addi %arg1, %arg2 : i32
%1 = arith.addi %0, %arg2 : i32
%2 = arith.addi %1, %arg1 : i32
// CHECK-NEXT: test.region_if_yield %[[ARG1]]
// CHECK-NEXT: }
// CHECK-NEXT: return %[[V0]]
-func @test_nested_region_sink(%arg0: i32, %arg1: i32) -> i32 {
+func.func @test_nested_region_sink(%arg0: i32, %arg1: i32) -> i32 {
%0 = arith.addi %arg1, %arg1 : i32
%1 = test.region_if %arg0: i32 -> i32 then {
^bb0(%arg3: i32):
// CHECK-NEXT: "test.yield"(%[[V1]]) : (i32) -> ()
// CHECK-NEXT: })
// CHECK-NEXT: return %[[V0]]
-func @test_not_sunk_deeply(%arg0: i32) -> i32 {
+func.func @test_not_sunk_deeply(%arg0: i32) -> i32 {
%0 = arith.addi %arg0, %arg0 : i32
%1 = "test.any_cond"() ({
cf.br ^bb1
#map0 = affine_map<(d0) -> (d0 mod 2)>
// CHECK-LABEL: @simple_constant
-func @simple_constant() -> (i32, i32) {
+func.func @simple_constant() -> (i32, i32) {
// CHECK-NEXT: %c1_i32 = arith.constant 1 : i32
%0 = arith.constant 1 : i32
}
// CHECK-LABEL: @basic
-func @basic() -> (index, index) {
+func.func @basic() -> (index, index) {
// CHECK: %c0 = arith.constant 0 : index
%c0 = arith.constant 0 : index
%c1 = arith.constant 0 : index
}
// CHECK-LABEL: @many
-func @many(f32, f32) -> (f32) {
+func.func @many(f32, f32) -> (f32) {
^bb0(%a : f32, %b : f32):
// CHECK-NEXT: %0 = arith.addf %arg0, %arg1 : f32
%c = arith.addf %a, %b : f32
/// Check that operations are not eliminated if they have different operands.
// CHECK-LABEL: @different_ops
-func @different_ops() -> (i32, i32) {
+func.func @different_ops() -> (i32, i32) {
// CHECK: %c0_i32 = arith.constant 0 : i32
// CHECK: %c1_i32 = arith.constant 1 : i32
%0 = arith.constant 0 : i32
/// Check that operations are not eliminated if they have different result
/// types.
// CHECK-LABEL: @different_results
-func @different_results(%arg0: tensor<*xf32>) -> (tensor<?x?xf32>, tensor<4x?xf32>) {
+func.func @different_results(%arg0: tensor<*xf32>) -> (tensor<?x?xf32>, tensor<4x?xf32>) {
// CHECK: %0 = tensor.cast %arg0 : tensor<*xf32> to tensor<?x?xf32>
// CHECK-NEXT: %1 = tensor.cast %arg0 : tensor<*xf32> to tensor<4x?xf32>
%0 = tensor.cast %arg0 : tensor<*xf32> to tensor<?x?xf32>
/// Check that operations are not eliminated if they have different attributes.
// CHECK-LABEL: @different_attributes
-func @different_attributes(index, index) -> (i1, i1, i1) {
+func.func @different_attributes(index, index) -> (i1, i1, i1) {
^bb0(%a : index, %b : index):
// CHECK: %0 = arith.cmpi slt, %arg0, %arg1 : index
%0 = arith.cmpi slt, %a, %b : index
/// Check that operations with side effects are not eliminated.
// CHECK-LABEL: @side_effect
-func @side_effect() -> (memref<2x1xf32>, memref<2x1xf32>) {
+func.func @side_effect() -> (memref<2x1xf32>, memref<2x1xf32>) {
// CHECK: %0 = memref.alloc() : memref<2x1xf32>
%0 = memref.alloc() : memref<2x1xf32>
/// Check that operation definitions are properly propagated down the dominance
/// tree.
// CHECK-LABEL: @down_propagate_for
-func @down_propagate_for() {
+func.func @down_propagate_for() {
// CHECK: %c1_i32 = arith.constant 1 : i32
%0 = arith.constant 1 : i32
}
// CHECK-LABEL: @down_propagate
-func @down_propagate() -> i32 {
+func.func @down_propagate() -> i32 {
// CHECK-NEXT: %c1_i32 = arith.constant 1 : i32
%0 = arith.constant 1 : i32
/// Check that operation definitions are NOT propagated up the dominance tree.
// CHECK-LABEL: @up_propagate_for
-func @up_propagate_for() -> i32 {
+func.func @up_propagate_for() -> i32 {
// CHECK: affine.for {{.*}} = 0 to 4 {
affine.for %i = 0 to 4 {
// CHECK-NEXT: %c1_i32_0 = arith.constant 1 : i32
}
// CHECK-LABEL: func @up_propagate
-func @up_propagate() -> i32 {
+func.func @up_propagate() -> i32 {
// CHECK-NEXT: %c0_i32 = arith.constant 0 : i32
%0 = arith.constant 0 : i32
/// The same test as above except that we are testing on a cfg embedded within
/// an operation region.
// CHECK-LABEL: func @up_propagate_region
-func @up_propagate_region() -> i32 {
+func.func @up_propagate_region() -> i32 {
// CHECK-NEXT: %0 = "foo.region"
%0 = "foo.region"() ({
// CHECK-NEXT: %c0_i32 = arith.constant 0 : i32
/// This test checks that nested regions that are isolated from above are
/// properly handled.
// CHECK-LABEL: @nested_isolated
-func @nested_isolated() -> i32 {
+func.func @nested_isolated() -> i32 {
// CHECK-NEXT: arith.constant 1
%0 = arith.constant 1 : i32
/// where the use occurs before the def, and one of the defs could be CSE'd with
/// the other.
// CHECK-LABEL: @use_before_def
-func @use_before_def() {
+func.func @use_before_def() {
// CHECK-NEXT: test.graph_region
test.graph_region {
// CHECK-NEXT: arith.addi %c1_i32, %c1_i32_0
/// This test is checking that CSE is removing duplicated read op that follow
/// other.
// CHECK-LABEL: @remove_direct_duplicated_read_op
-func @remove_direct_duplicated_read_op() -> i32 {
+func.func @remove_direct_duplicated_read_op() -> i32 {
// CHECK-NEXT: %[[READ_VALUE:.*]] = "test.op_with_memread"() : () -> i32
%0 = "test.op_with_memread"() : () -> (i32)
%1 = "test.op_with_memread"() : () -> (i32)
/// This test is checking that CSE is removing duplicated read op that follow
/// other.
// CHECK-LABEL: @remove_multiple_duplicated_read_op
-func @remove_multiple_duplicated_read_op() -> i64 {
+func.func @remove_multiple_duplicated_read_op() -> i64 {
// CHECK: %[[READ_VALUE:.*]] = "test.op_with_memread"() : () -> i64
%0 = "test.op_with_memread"() : () -> (i64)
%1 = "test.op_with_memread"() : () -> (i64)
/// This test is checking that CSE is not removing duplicated read op that
/// have write op in between.
// CHECK-LABEL: @dont_remove_duplicated_read_op_with_sideeffecting
-func @dont_remove_duplicated_read_op_with_sideeffecting() -> i32 {
+func.func @dont_remove_duplicated_read_op_with_sideeffecting() -> i32 {
// CHECK-NEXT: %[[READ_VALUE0:.*]] = "test.op_with_memread"() : () -> i32
%0 = "test.op_with_memread"() : () -> (i32)
"test.op_with_memwrite"() : () -> ()
/// This test is checking that identical commutative operation are gracefully
/// handled but the CSE pass.
// CHECK-LABEL: func @check_cummutative_cse
-func @check_cummutative_cse(%a : i32, %b : i32) -> i32 {
+func.func @check_cummutative_cse(%a : i32, %b : i32) -> i32 {
// CHECK: %[[ADD1:.*]] = arith.addi %{{.*}}, %{{.*}} : i32
%1 = arith.addi %a, %b : i32
%2 = arith.addi %b, %a : i32
// CHECK: %[[RET0:.*]] = "test.get_tuple_element"(%[[ARG_MATERIALIZED]]) {index = 0 : i32} : (tuple<i1, i32>) -> i1
// CHECK: %[[RET1:.*]] = "test.get_tuple_element"(%[[ARG_MATERIALIZED]]) {index = 1 : i32} : (tuple<i1, i32>) -> i32
// CHECK: return %[[RET0]], %[[RET1]] : i1, i32
-func @identity(%arg0: tuple<i1, i32>) -> tuple<i1, i32> {
+func.func @identity(%arg0: tuple<i1, i32>) -> tuple<i1, i32> {
return %arg0 : tuple<i1, i32>
}
// CHECK-LABEL: func @identity_1_to_1_no_materializations(
// CHECK-SAME: %[[ARG0:.*]]: i1) -> i1 {
// CHECK: return %[[ARG0]] : i1
-func @identity_1_to_1_no_materializations(%arg0: tuple<i1>) -> tuple<i1> {
+func.func @identity_1_to_1_no_materializations(%arg0: tuple<i1>) -> tuple<i1> {
return %arg0 : tuple<i1>
}
// CHECK-LABEL: func @recursive_decomposition(
// CHECK-SAME: %[[ARG0:.*]]: i1) -> i1 {
// CHECK: return %[[ARG0]] : i1
-func @recursive_decomposition(%arg0: tuple<tuple<tuple<i1>>>) -> tuple<tuple<tuple<i1>>> {
+func.func @recursive_decomposition(%arg0: tuple<tuple<tuple<i1>>>) -> tuple<tuple<tuple<i1>>> {
return %arg0 : tuple<tuple<tuple<i1>>>
}
// Test case: Check decomposition of calls.
// CHECK-LABEL: func private @callee(i1, i32) -> (i1, i32)
-func private @callee(tuple<i1, i32>) -> tuple<i1, i32>
+func.func private @callee(tuple<i1, i32>) -> tuple<i1, i32>
// CHECK-LABEL: func @caller(
// CHECK-SAME: %[[ARG0:.*]]: i1,
// CHECK: %[[RET0:.*]] = "test.get_tuple_element"(%[[CALL_RESULT_RECOMPOSED]]) {index = 0 : i32} : (tuple<i1, i32>) -> i1
// CHECK: %[[RET1:.*]] = "test.get_tuple_element"(%[[CALL_RESULT_RECOMPOSED]]) {index = 1 : i32} : (tuple<i1, i32>) -> i32
// CHECK: return %[[RET0]], %[[RET1]] : i1, i32
-func @caller(%arg0: tuple<i1, i32>) -> tuple<i1, i32> {
+func.func @caller(%arg0: tuple<i1, i32>) -> tuple<i1, i32> {
%0 = call @callee(%arg0) : (tuple<i1, i32>) -> tuple<i1, i32>
return %0 : tuple<i1, i32>
}
// Test case: Type that decomposes to nothing (that is, a 1:0 decomposition).
// CHECK-LABEL: func private @callee()
-func private @callee(tuple<>) -> tuple<>
+func.func private @callee(tuple<>) -> tuple<>
// CHECK-LABEL: func @caller() {
// CHECK: call @callee() : () -> ()
// CHECK: return
-func @caller(%arg0: tuple<>) -> tuple<> {
+func.func @caller(%arg0: tuple<>) -> tuple<> {
%0 = call @callee(%arg0) : (tuple<>) -> (tuple<>)
return %0 : tuple<>
}
// CHECK: %[[RET0:.*]] = "test.get_tuple_element"(%[[UNCONVERTED_VALUE]]) {index = 0 : i32} : (tuple<i1, i32>) -> i1
// CHECK: %[[RET1:.*]] = "test.get_tuple_element"(%[[UNCONVERTED_VALUE]]) {index = 1 : i32} : (tuple<i1, i32>) -> i32
// CHECK: return %[[RET0]], %[[RET1]] : i1, i32
-func @unconverted_op_result() -> tuple<i1, i32> {
+func.func @unconverted_op_result() -> tuple<i1, i32> {
%0 = "test.source"() : () -> (tuple<i1, i32>)
return %0 : tuple<i1, i32>
}
// This makes sure to test the cases if 1:0, 1:1, and 1:N decompositions.
// CHECK-LABEL: func private @callee(i1, i2, i3, i4, i5, i6) -> (i1, i2, i3, i4, i5, i6)
-func private @callee(tuple<>, i1, tuple<i2>, i3, tuple<i4, i5>, i6) -> (tuple<>, i1, tuple<i2>, i3, tuple<i4, i5>, i6)
+func.func private @callee(tuple<>, i1, tuple<i2>, i3, tuple<i4, i5>, i6) -> (tuple<>, i1, tuple<i2>, i3, tuple<i4, i5>, i6)
// CHECK-LABEL: func @caller(
// CHECK-SAME: %[[I1:.*]]: i1,
// CHECK: %[[RET_TUPLE_0:.*]] = "test.get_tuple_element"(%[[RET_TUPLE]]) {index = 0 : i32} : (tuple<i4, i5>) -> i4
// CHECK: %[[RET_TUPLE_1:.*]] = "test.get_tuple_element"(%[[RET_TUPLE]]) {index = 1 : i32} : (tuple<i4, i5>) -> i5
// CHECK: return %[[CALL]]#0, %[[CALL]]#1, %[[CALL]]#2, %[[RET_TUPLE_0]], %[[RET_TUPLE_1]], %[[CALL]]#5 : i1, i2, i3, i4, i5, i6
-func @caller(%arg0: tuple<>, %arg1: i1, %arg2: tuple<i2>, %arg3: i3, %arg4: tuple<i4, i5>, %arg5: i6) -> (tuple<>, i1, tuple<i2>, i3, tuple<i4, i5>, i6) {
+func.func @caller(%arg0: tuple<>, %arg1: i1, %arg2: tuple<i2>, %arg3: i3, %arg4: tuple<i4, i5>, %arg5: i6) -> (tuple<>, i1, tuple<i2>, i3, tuple<i4, i5>, i6) {
%0, %1, %2, %3, %4, %5 = call @callee(%arg0, %arg1, %arg2, %arg3, %arg4, %arg5) : (tuple<>, i1, tuple<i2>, i3, tuple<i4, i5>, i6) -> (tuple<>, i1, tuple<i2>, i3, tuple<i4, i5>, i6)
return %0, %1, %2, %3, %4, %5 : tuple<>, i1, tuple<i2>, i3, tuple<i4, i5>, i6
}
// Function is already dead.
// CHECK-NOT: func private @dead_function
-func private @dead_function() {
+func.func private @dead_function() {
return
}
// Function becomes dead after inlining.
// CHECK-NOT: func private @dead_function_b
-func @dead_function_b() {
+func.func @dead_function_b() {
return
}
// CHECK: func @live_function()
-func @live_function() {
+func.func @live_function() {
call @dead_function_b() : () -> ()
return
}
// Same as above, but a transitive example.
// CHECK: func @live_function_b
-func @live_function_b() {
+func.func @live_function_b() {
return
}
// CHECK-NOT: func private @dead_function_c
-func private @dead_function_c() {
+func.func private @dead_function_c() {
call @live_function_b() : () -> ()
return
}
// CHECK-NOT: func private @dead_function_d
-func private @dead_function_d() {
+func.func private @dead_function_d() {
call @dead_function_c() : () -> ()
call @dead_function_c() : () -> ()
return
}
// CHECK: func @live_function_c
-func @live_function_c() {
+func.func @live_function_c() {
call @dead_function_c() : () -> ()
call @dead_function_d() : () -> ()
return
// Function is referenced by non-callable top-level user.
// CHECK: func private @live_function_d
-func private @live_function_d() {
+func.func private @live_function_d() {
return
}
// functions in different SCCs that are referenced by calls materialized during
// canonicalization.
// CHECK: func @live_function_e
-func @live_function_e() {
+func.func @live_function_e() {
call @dead_function_e() : () -> ()
return
}
// CHECK-NOT: func @dead_function_e
-func private @dead_function_e() -> () {
+func.func private @dead_function_e() -> () {
"test.fold_to_call_op"() {callee=@dead_function_f} : () -> ()
return
}
// CHECK-NOT: func private @dead_function_f
-func private @dead_function_f() {
+func.func private @dead_function_f() {
return
}
// This could crash the inliner, make sure it does not.
-func @A() {
+func.func @A() {
call @B() { inA } : () -> ()
return
}
-func @B() {
+func.func @B() {
call @E() : () -> ()
return
}
-func @C() {
+func.func @C() {
call @D() : () -> ()
return
}
-func private @D() {
+func.func private @D() {
call @B() { inD } : () -> ()
return
}
-func @E() {
+func.func @E() {
call @fabsf() : () -> ()
return
}
-func private @fabsf()
+func.func private @fabsf()
// CHECK: func @A() {
// CHECK: call @fabsf() : () -> ()
// RUN: mlir-opt %s -inline='op-pipelines=func.func(canonicalize,cse)' | FileCheck %s --check-prefix INLINE_SIMPLIFY
// Inline a function that takes an argument.
-func @func_with_arg(%c : i32) -> i32 {
+func.func @func_with_arg(%c : i32) -> i32 {
%b = arith.addi %c, %c : i32
return %b : i32
}
// CHECK-LABEL: func @inline_with_arg
-func @inline_with_arg(%arg0 : i32) -> i32 {
+func.func @inline_with_arg(%arg0 : i32) -> i32 {
// CHECK-NEXT: arith.addi
// CHECK-NEXT: return
}
// Inline a function that has multiple return operations.
-func @func_with_multi_return(%a : i1) -> (i32) {
+func.func @func_with_multi_return(%a : i1) -> (i32) {
cf.cond_br %a, ^bb1, ^bb2
^bb1:
}
// CHECK-LABEL: func @inline_with_multi_return() -> i32
-func @inline_with_multi_return() -> i32 {
+func.func @inline_with_multi_return() -> i32 {
// CHECK-NEXT: [[VAL_7:%.*]] = arith.constant false
// CHECK-NEXT: cf.cond_br [[VAL_7]], ^bb1, ^bb2
// CHECK: ^bb1:
}
// Check that location information is updated for inlined instructions.
-func @func_with_locations(%c : i32) -> i32 {
+func.func @func_with_locations(%c : i32) -> i32 {
%b = arith.addi %c, %c : i32 loc("mysource.cc":10:8)
return %b : i32 loc("mysource.cc":11:2)
}
// INLINE-LOC-LABEL: func @inline_with_locations
-func @inline_with_locations(%arg0 : i32) -> i32 {
+func.func @inline_with_locations(%arg0 : i32) -> i32 {
// INLINE-LOC-NEXT: arith.addi %{{.*}}, %{{.*}} : i32 loc(callsite("mysource.cc":10:8 at "mysource.cc":55:14))
// INLINE-LOC-NEXT: return
// Check that external function declarations are not inlined.
-func private @func_external()
+func.func private @func_external()
// CHECK-LABEL: func @no_inline_external
-func @no_inline_external() {
+func.func @no_inline_external() {
// CHECK-NEXT: call @func_external()
call @func_external() : () -> ()
return
}
// Check that multiple levels of calls will be inlined.
-func @multilevel_func_a() {
+func.func @multilevel_func_a() {
return
}
-func @multilevel_func_b() {
+func.func @multilevel_func_b() {
call @multilevel_func_a() : () -> ()
return
}
// CHECK-LABEL: func @inline_multilevel
-func @inline_multilevel() {
+func.func @inline_multilevel() {
// CHECK-NOT: call
%fn = "test.functional_region_op"() ({
call @multilevel_func_b() : () -> ()
// Check that recursive calls are not inlined.
// CHECK-LABEL: func @no_inline_recursive
-func @no_inline_recursive() {
+func.func @no_inline_recursive() {
// CHECK: test.functional_region_op
// CHECK-NOT: test.functional_region_op
%fn = "test.functional_region_op"() ({
}
// Check that we can convert types for inputs and results as necessary.
-func @convert_callee_fn(%arg : i32) -> i32 {
+func.func @convert_callee_fn(%arg : i32) -> i32 {
return %arg : i32
}
-func @convert_callee_fn_multi_arg(%a : i32, %b : i32) -> () {
+func.func @convert_callee_fn_multi_arg(%a : i32, %b : i32) -> () {
return
}
-func @convert_callee_fn_multi_res() -> (i32, i32) {
+func.func @convert_callee_fn_multi_res() -> (i32, i32) {
%res = arith.constant 0 : i32
return %res, %res : i32, i32
}
// CHECK-LABEL: func @inline_convert_call
-func @inline_convert_call() -> i16 {
+func.func @inline_convert_call() -> i16 {
// CHECK: %[[INPUT:.*]] = arith.constant
%test_input = arith.constant 0 : i16
return %res : i16
}
-func @convert_callee_fn_multiblock() -> i32 {
+func.func @convert_callee_fn_multiblock() -> i32 {
cf.br ^bb0
^bb0:
%0 = arith.constant 0 : i32
}
// CHECK-LABEL: func @inline_convert_result_multiblock
-func @inline_convert_result_multiblock() -> i16 {
+func.func @inline_convert_result_multiblock() -> i16 {
// CHECK: cf.br ^bb1 {inlined_conversion}
// CHECK: ^bb1:
// CHECK: %[[C:.+]] = arith.constant {inlined_conversion} 0 : i32
}
// CHECK-LABEL: func @no_inline_convert_call
-func @no_inline_convert_call() {
+func.func @no_inline_convert_call() {
// CHECK: "test.conversion_call_op"
%test_input_i16 = arith.constant 0 : i16
%test_input_i64 = arith.constant 0 : i64
}
// Check that we properly simplify when inlining.
-func @simplify_return_constant() -> i32 {
+func.func @simplify_return_constant() -> i32 {
%res = arith.constant 0 : i32
return %res : i32
}
-func @simplify_return_reference() -> (() -> i32) {
+func.func @simplify_return_reference() -> (() -> i32) {
%res = constant @simplify_return_constant : () -> i32
return %res : () -> i32
}
// INLINE_SIMPLIFY-LABEL: func @inline_simplify
-func @inline_simplify() -> i32 {
+func.func @inline_simplify() -> i32 {
// INLINE_SIMPLIFY-NEXT: %[[CST:.*]] = arith.constant 0 : i32
// INLINE_SIMPLIFY-NEXT: return %[[CST]]
%fn = call @simplify_return_reference() : () -> (() -> i32)
}
// CHECK-LABEL: func @no_inline_invalid_call
-func @no_inline_invalid_call() -> i32 {
+func.func @no_inline_invalid_call() -> i32 {
%res = "test.conversion_call_op"() { callee=@convert_callee_fn_multiblock, noinline } : () -> (i32)
return %res : i32
}
-func @gpu_alloc() -> memref<1024xf32> {
+func.func @gpu_alloc() -> memref<1024xf32> {
%m = gpu.alloc [] () : memref<1024xf32>
return %m : memref<1024xf32>
}
// CHECK-LABEL: func @inline_gpu_ops
-func @inline_gpu_ops() -> memref<1024xf32> {
+func.func @inline_gpu_ops() -> memref<1024xf32> {
// CHECK-NEXT: gpu.alloc
%m = call @gpu_alloc() : () -> memref<1024xf32>
return %m : memref<1024xf32>
// Test block arguments location propagation.
// Use two call-sites to force cloning.
-func @func_with_block_args_location(%arg0 : i32) {
+func.func @func_with_block_args_location(%arg0 : i32) {
cf.br ^bb1(%arg0 : i32)
^bb1(%x : i32 loc("foo")):
"test.foo" (%x) : (i32) -> () loc("bar")
// INLINE-LOC-LABEL: func @func_with_block_args_location_callee1
// INLINE-LOC: cf.br
// INLINE-LOC: ^bb{{[0-9]+}}(%{{.*}}: i32 loc("foo")
-func @func_with_block_args_location_callee1(%arg0 : i32) {
+func.func @func_with_block_args_location_callee1(%arg0 : i32) {
call @func_with_block_args_location(%arg0) : (i32) -> ()
return
}
// CHECK-LABEL: func @func_with_block_args_location_callee2
-func @func_with_block_args_location_callee2(%arg0 : i32) {
+func.func @func_with_block_args_location_callee2(%arg0 : i32) {
call @func_with_block_args_location(%arg0) : (i32) -> ()
return
}
// TAG-NEXT: loc(fused["original", "tagged"("[[FILE]]":{{[0-9]+}}:{{[0-9]+}})])
// TAG-NEXT: } loc(fused["original", "tagged"("[[FILE]]":{{[0-9]+}}:{{[0-9]+}})])
-func @function() -> i32 {
+func.func @function() -> i32 {
%1 = "foo"() : () -> i32 loc("original")
return %1 : i32 loc("original")
} loc("original")
// -----
// CHECK-LABEL: func @should_fuse_at_depth_above_loop_carried_dependence(%{{.*}}: memref<64x4xf32>, %{{.*}}: memref<64x4xf32>) {
-func @should_fuse_at_depth_above_loop_carried_dependence(%arg0: memref<64x4xf32>, %arg1: memref<64x4xf32>) {
+func.func @should_fuse_at_depth_above_loop_carried_dependence(%arg0: memref<64x4xf32>, %arg1: memref<64x4xf32>) {
%out = memref.alloc() : memref<64x4xf32>
%0 = arith.constant 0.0 : f32
affine.for %i0 = 0 to 64 {
// -----
// CHECK-LABEL: func @should_fuse_only_two_loops_and_remove_producer() {
-func @should_fuse_only_two_loops_and_remove_producer() {
+func.func @should_fuse_only_two_loops_and_remove_producer() {
%a = memref.alloc() : memref<10xf32>
%b = memref.alloc() : memref<10xf32>
// -----
// CHECK-LABEL: func @should_fuse_after_one_loop_interchange() {
-func @should_fuse_after_one_loop_interchange() {
+func.func @should_fuse_after_one_loop_interchange() {
%a = memref.alloc() : memref<10xf32>
%cf0 = arith.constant 0.0 : f32
// -----
// CHECK-LABEL: func @should_fuse_after_two_loop_interchanges() {
-func @should_fuse_after_two_loop_interchanges() {
+func.func @should_fuse_after_two_loop_interchanges() {
%a = memref.alloc() : memref<6x8xf32>
%cf0 = arith.constant 0.0 : f32
// -----
-func @should_fuse_live_out_writer(%arg0 : memref<10xf32>) -> memref<10xf32> {
+func.func @should_fuse_live_out_writer(%arg0 : memref<10xf32>) -> memref<10xf32> {
%cst = arith.constant 0.000000e+00 : f32
affine.for %i0 = 0 to 10 {
affine.store %cst, %arg0[%i0] : memref<10xf32>
// CHECK-DAG: [[$MAP_UB:#map[0-9]+]] = affine_map<(d0) -> (d0 * 16 + 16)>
// CHECK-LABEL: slice_tile
-func @slice_tile(%arg0: memref<128x8xf32>, %arg1: memref<32x8xf32>, %0 : f32) -> memref<32x8xf32> {
+func.func @slice_tile(%arg0: memref<128x8xf32>, %arg1: memref<32x8xf32>, %0 : f32) -> memref<32x8xf32> {
affine.for %i0 = 0 to 32 {
affine.for %i1 = 0 to 8 {
affine.store %0, %arg1[%i0, %i1] : memref<32x8xf32>
// -----
// Test case which illustrates fix for b/126454413
-func @test_add_slice_bounds() {
+func.func @test_add_slice_bounds() {
%a = memref.alloc() : memref<10xf32>
%b = memref.alloc() : memref<10xf32>
%cf7 = arith.constant 7.0 : f32
// -----
-func @should_fuse_init_loops_siblings_then_shared_producer(%arg0: memref<10x10xf32>, %arg1: memref<10x10xf32>) {
+func.func @should_fuse_init_loops_siblings_then_shared_producer(%arg0: memref<10x10xf32>, %arg1: memref<10x10xf32>) {
%0 = memref.alloc() : memref<10x10xf32>
%cst = arith.constant 0.000000e+00 : f32
%cst_0 = arith.constant 1.000000e+00 : f32
// -----
-func @two_matrix_vector_products() {
+func.func @two_matrix_vector_products() {
%in_matrix = memref.alloc() : memref<10x10xf32>
%in_vec0 = memref.alloc() : memref<10xf32>
%in_vec1 = memref.alloc() : memref<10xf32>
// -----
-func @should_not_slice_past_slice_barrier() {
+func.func @should_not_slice_past_slice_barrier() {
%0 = memref.alloc() : memref<100x16xf32>
affine.for %i0 = 0 to 100 {
affine.for %i1 = 0 to 16 {
// -----
#map0 = affine_map<(d0, d1) -> (d0 * 16 + d1)>
-func @fuse_across_dim_mismatch(%arg0: memref<4x4x16x1xf32>, %arg1: memref<144x9xf32>, %arg2: memref<9xf32>) {
+func.func @fuse_across_dim_mismatch(%arg0: memref<4x4x16x1xf32>, %arg1: memref<144x9xf32>, %arg2: memref<9xf32>) {
%1 = memref.alloc() : memref<144x4xf32>
%2 = arith.constant 0.0 : f32
affine.for %i2 = 0 to 9 {
#map10 = affine_map<(d0, d1) -> (d0 * 16 + d1)>
#map11 = affine_map<(d0, d1) -> (d0 * 16 + d1)>
#map12 = affine_map<(d0, d1) -> (d0 * 16 - d1 + 15)>
-func @fuse_across_varying_dims_complex(%arg0: f32) {
+func.func @fuse_across_varying_dims_complex(%arg0: f32) {
%c0 = arith.constant 0 : index
%0 = memref.alloc() : memref<2x2x3x3x16x1xf32>
%1 = memref.alloc() : memref<64x9xf32>
// -----
-func @should_fuse_with_slice_union() {
+func.func @should_fuse_with_slice_union() {
%a = memref.alloc() : memref<100xf32>
%c0 = arith.constant 0 : index
%cf0 = arith.constant 0.0 : f32
// -----
-func @affine_add_mm_fused(%arg0: memref<1024x1024xf32>, %arg1: memref<1024x1024xf32>, %arg2: memref<1024x1024xf32>, %arg3: memref<1024x1024xf32>) {
+func.func @affine_add_mm_fused(%arg0: memref<1024x1024xf32>, %arg1: memref<1024x1024xf32>, %arg2: memref<1024x1024xf32>, %arg3: memref<1024x1024xf32>) {
affine.for %i2 = 0 to 1024 {
affine.for %i3 = 0 to 1024 {
%0 = affine.load %arg3[%i2, %i3] : memref<1024x1024xf32>
// -----
-func @affine_2mm_fused(%arg0: memref<1024x1024xf32>, %arg1: memref<1024x1024xf32>, %arg2: memref<1024x1024xf32>, %arg3: memref<1024x1024xf32>, %arg4: memref<1024x1024xf32>) {
+func.func @affine_2mm_fused(%arg0: memref<1024x1024xf32>, %arg1: memref<1024x1024xf32>, %arg2: memref<1024x1024xf32>, %arg3: memref<1024x1024xf32>, %arg4: memref<1024x1024xf32>) {
%cst = arith.constant 0.000000e+00 : f32
affine.for %i0 = 0 to 1024 {
affine.for %i1 = 0 to 1024 {
// -----
-func @affine_2_dependent_mm_fused(%arg0: memref<1024x1024xf32>, %arg1: memref<1024x1024xf32>, %arg2: memref<1024x1024xf32>, %arg3: memref<1024x1024xf32>, %arg4: memref<1024x1024xf32>) {
+func.func @affine_2_dependent_mm_fused(%arg0: memref<1024x1024xf32>, %arg1: memref<1024x1024xf32>, %arg2: memref<1024x1024xf32>, %arg3: memref<1024x1024xf32>, %arg4: memref<1024x1024xf32>) {
affine.for %i0 = 0 to 1024 {
affine.for %i1 = 0 to 1024 {
affine.for %i2 = 0 to 1024 {
// -----
// CHECK-LABEL: func @should_fuse_self_dependence_multi_store_producer() {
-func @should_fuse_self_dependence_multi_store_producer() {
+func.func @should_fuse_self_dependence_multi_store_producer() {
%m = memref.alloc() : memref<10xf32>
%local_m = memref.alloc() : memref<10xf32>
%cf7 = arith.constant 7.0 : f32
// -----
// CHECK-LABEL: func @should_fuse_dead_multi_store_producer() {
-func @should_fuse_dead_multi_store_producer() {
+func.func @should_fuse_dead_multi_store_producer() {
%m = memref.alloc() : memref<10xf32>
%dead_m = memref.alloc() : memref<10xf32>
%cf7 = arith.constant 7.0 : f32
// -----
// CHECK-LABEL: func @should_fuse_function_live_out_multi_store_producer
-func @should_fuse_function_live_out_multi_store_producer(%live_in_out_m : memref<10xf32>) {
+func.func @should_fuse_function_live_out_multi_store_producer(%live_in_out_m : memref<10xf32>) {
%m = memref.alloc() : memref<10xf32>
%cf7 = arith.constant 7.0 : f32
// Test case from github bug 777.
// CHECK-LABEL: func @mul_add_0
-func @mul_add_0(%arg0: memref<3x4xf32>, %arg1: memref<4x3xf32>, %arg2: memref<3x3xf32>, %arg3: memref<3x3xf32>) {
+func.func @mul_add_0(%arg0: memref<3x4xf32>, %arg1: memref<4x3xf32>, %arg2: memref<3x3xf32>, %arg3: memref<3x3xf32>) {
%cst = arith.constant 0.000000e+00 : f32
%0 = memref.alloc() : memref<3x3xf32>
affine.for %arg4 = 0 to 3 {
// that has multiple outgoing edges.
// CHECK-LABEL: func @should_fuse_multi_outgoing_edge_store_producer
-func @should_fuse_multi_outgoing_edge_store_producer(%a : memref<1xf32>) {
+func.func @should_fuse_multi_outgoing_edge_store_producer(%a : memref<1xf32>) {
%cst = arith.constant 0.000000e+00 : f32
affine.for %arg0 = 0 to 1 {
affine.store %cst, %a[%arg0] : memref<1xf32>
// dependencies on external memrefs '%a' and '%b'.
// CHECK-LABEL: func @should_fuse_producer_with_multi_outgoing_edges
-func @should_fuse_producer_with_multi_outgoing_edges(%a : memref<1xf32>, %b : memref<1xf32>) {
+func.func @should_fuse_producer_with_multi_outgoing_edges(%a : memref<1xf32>, %b : memref<1xf32>) {
%cst = arith.constant 0.000000e+00 : f32
affine.for %arg0 = 0 to 1 {
%0 = affine.load %a[%arg0] : memref<1xf32>
}
// MAXIMAL-LABEL: func @reshape_into_matmul
-func @reshape_into_matmul(%lhs : memref<1024x1024xf32>,
+func.func @reshape_into_matmul(%lhs : memref<1024x1024xf32>,
%R: memref<16x64x1024xf32>, %out: memref<1024x1024xf32>) {
%rhs = memref.alloc() : memref<1024x1024xf32>
// -----
// CHECK-LABEL: func @vector_loop
-func @vector_loop(%a : memref<10x20xf32>, %b : memref<10x20xf32>,
+func.func @vector_loop(%a : memref<10x20xf32>, %b : memref<10x20xf32>,
%c : memref<10x20xf32>) {
affine.for %j = 0 to 10 {
affine.for %i = 0 to 5 {
// -----
// CHECK-LABEL: func @multi_outgoing_edges
-func @multi_outgoing_edges(%in0 : memref<32xf32>,
+func.func @multi_outgoing_edges(%in0 : memref<32xf32>,
%in1 : memref<32xf32>) {
affine.for %d = 0 to 32 {
%lhs = affine.load %in0[%d] : memref<32xf32>
// Test fusion when dynamically shaped memrefs are used with constant trip count loops.
// CHECK-LABEL: func @calc
-func @calc(%arg0: memref<?xf32>, %arg1: memref<?xf32>, %arg2: memref<?xf32>, %len: index) {
+func.func @calc(%arg0: memref<?xf32>, %arg1: memref<?xf32>, %arg2: memref<?xf32>, %len: index) {
%c1 = arith.constant 1 : index
%1 = memref.alloc(%len) : memref<?xf32>
affine.for %arg4 = 1 to 10 {
// -----
// CHECK-LABEL: func @should_not_fuse_since_non_affine_users
-func @should_not_fuse_since_non_affine_users(%in0 : memref<32xf32>,
+func.func @should_not_fuse_since_non_affine_users(%in0 : memref<32xf32>,
%in1 : memref<32xf32>) {
affine.for %d = 0 to 32 {
%lhs = affine.load %in0[%d] : memref<32xf32>
// -----
// CHECK-LABEL: func @should_not_fuse_since_top_level_non_affine_users
-func @should_not_fuse_since_top_level_non_affine_users(%in0 : memref<32xf32>,
+func.func @should_not_fuse_since_top_level_non_affine_users(%in0 : memref<32xf32>,
%in1 : memref<32xf32>) {
%sum = memref.alloc() : memref<f32>
affine.for %d = 0 to 32 {
// -----
// CHECK-LABEL: func @should_not_fuse_since_top_level_non_affine_mem_write_users
-func @should_not_fuse_since_top_level_non_affine_mem_write_users(
+func.func @should_not_fuse_since_top_level_non_affine_mem_write_users(
%in0 : memref<32xf32>, %in1 : memref<32xf32>) {
%c0 = arith.constant 0 : index
%cst_0 = arith.constant 0.000000e+00 : f32
// -----
// MAXIMAL-LABEL: func @fuse_minor_affine_map
-func @fuse_minor_affine_map(%in: memref<128xf32>, %out: memref<20x512xf32>) {
+func.func @fuse_minor_affine_map(%in: memref<128xf32>, %out: memref<20x512xf32>) {
%tmp = memref.alloc() : memref<128xf32>
affine.for %arg4 = 0 to 128 {
// -----
// CHECK-LABEL: func @should_fuse_multi_store_producer_and_privatize_memfefs
-func @should_fuse_multi_store_producer_and_privatize_memfefs() {
+func.func @should_fuse_multi_store_producer_and_privatize_memfefs() {
%a = memref.alloc() : memref<10xf32>
%b = memref.alloc() : memref<10xf32>
%c = memref.alloc() : memref<10xf32>
}
-func @should_fuse_multi_store_producer_with_escaping_memrefs_and_remove_src(
+func.func @should_fuse_multi_store_producer_with_escaping_memrefs_and_remove_src(
%a : memref<10xf32>, %b : memref<10xf32>) {
%cst = arith.constant 0.000000e+00 : f32
affine.for %i0 = 0 to 10 {
// -----
-func @should_fuse_multi_store_producer_with_escaping_memrefs_and_preserve_src(
+func.func @should_fuse_multi_store_producer_with_escaping_memrefs_and_preserve_src(
%a : memref<10xf32>, %b : memref<10xf32>) {
%cst = arith.constant 0.000000e+00 : f32
affine.for %i0 = 0 to 10 {
}
-func @should_not_fuse_due_to_dealloc(%arg0: memref<16xf32>){
+func.func @should_not_fuse_due_to_dealloc(%arg0: memref<16xf32>){
%A = memref.alloc() : memref<16xf32>
%C = memref.alloc() : memref<16xf32>
%cst_1 = arith.constant 1.000000e+00 : f32
// -----
// CHECK-LABEL: func @should_fuse_defining_node_has_no_dependence_from_source_node
-func @should_fuse_defining_node_has_no_dependence_from_source_node(
+func.func @should_fuse_defining_node_has_no_dependence_from_source_node(
%a : memref<10xf32>, %b : memref<f32>) -> () {
affine.for %i0 = 0 to 10 {
%0 = affine.load %b[] : memref<f32>
// -----
// CHECK-LABEL: func @should_not_fuse_defining_node_has_dependence_from_source_loop
-func @should_not_fuse_defining_node_has_dependence_from_source_loop(
+func.func @should_not_fuse_defining_node_has_dependence_from_source_loop(
%a : memref<10xf32>, %b : memref<f32>) -> () {
%cst = arith.constant 0.000000e+00 : f32
affine.for %i0 = 0 to 10 {
// -----
// CHECK-LABEL: func @should_not_fuse_defining_node_has_transitive_dependence_from_source_loop
-func @should_not_fuse_defining_node_has_transitive_dependence_from_source_loop(
+func.func @should_not_fuse_defining_node_has_transitive_dependence_from_source_loop(
%a : memref<10xf32>, %b : memref<10xf32>, %c : memref<f32>) -> () {
%cst = arith.constant 0.000000e+00 : f32
affine.for %i0 = 0 to 10 {
// -----
// CHECK-LABEL: func @should_not_fuse_dest_loop_nest_return_value
-func @should_not_fuse_dest_loop_nest_return_value(
+func.func @should_not_fuse_dest_loop_nest_return_value(
%a : memref<10xf32>) -> () {
%cst = arith.constant 0.000000e+00 : f32
affine.for %i0 = 0 to 10 {
// -----
// CHECK-LABEL: func @should_not_fuse_src_loop_nest_return_value
-func @should_not_fuse_src_loop_nest_return_value(
+func.func @should_not_fuse_src_loop_nest_return_value(
%a : memref<10xf32>) -> () {
%cst = arith.constant 1.000000e+00 : f32
%b = affine.for %i = 0 to 10 step 2 iter_args(%b_iter = %cst) -> f32 {
// -----
-func private @some_function(memref<16xf32>)
-func @call_op_prevents_fusion(%arg0: memref<16xf32>){
+func.func private @some_function(memref<16xf32>)
+func.func @call_op_prevents_fusion(%arg0: memref<16xf32>){
%A = memref.alloc() : memref<16xf32>
%cst_1 = arith.constant 1.000000e+00 : f32
affine.for %arg1 = 0 to 16 {
// -----
-func private @some_function()
-func @call_op_does_not_prevent_fusion(%arg0: memref<16xf32>){
+func.func private @some_function()
+func.func @call_op_does_not_prevent_fusion(%arg0: memref<16xf32>){
%A = memref.alloc() : memref<16xf32>
%cst_1 = arith.constant 1.000000e+00 : f32
affine.for %arg1 = 0 to 16 {
// not to be removed after fusion and the destinations do not write to `%arg0`.
// This should enable both the consumers to benefit from fusion, which would not
// be possible if private memrefs were not created.
-func @should_fuse_with_both_consumers_separately(%arg0: memref<10xf32>) {
+func.func @should_fuse_with_both_consumers_separately(%arg0: memref<10xf32>) {
%cf7 = arith.constant 7.0 : f32
affine.for %i0 = 0 to 10 {
affine.store %cf7, %arg0[%i0] : memref<10xf32>
// Fusion is avoided when the slice computed is invalid. Comments below describe
// incorrect backward slice computation. Similar logic applies for forward slice
// as well.
-func @no_fusion_cannot_compute_valid_slice() {
+func.func @no_fusion_cannot_compute_valid_slice() {
%A = memref.alloc() : memref<5xf32>
%B = memref.alloc() : memref<6xf32>
%C = memref.alloc() : memref<5xf32>
// CHECK-NEXT: affine.store
// MAXIMAL-LABEL: func @reduce_add_f32_f32(
-func @reduce_add_f32_f32(%arg0: memref<64x64xf32, 1>, %arg1: memref<1x64xf32, 1>, %arg2: memref<1x64xf32, 1>) {
+func.func @reduce_add_f32_f32(%arg0: memref<64x64xf32, 1>, %arg1: memref<1x64xf32, 1>, %arg2: memref<1x64xf32, 1>) {
%cst_0 = arith.constant 0.000000e+00 : f32
%cst_1 = arith.constant 1.000000e+00 : f32
%0 = memref.alloca() : memref<f32, 1>
// -----
// CHECK-LABEL: func @reduce_add_non_innermost
-func @reduce_add_non_innermost(%arg0: memref<64x64xf32, 1>, %arg1: memref<1x64xf32, 1>, %arg2: memref<1x64xf32, 1>) {
+func.func @reduce_add_non_innermost(%arg0: memref<64x64xf32, 1>, %arg1: memref<1x64xf32, 1>, %arg2: memref<1x64xf32, 1>) {
%cst = arith.constant 0.000000e+00 : f32
%cst_0 = arith.constant 1.000000e+00 : f32
%0 = memref.alloca() : memref<f32, 1>
// -----
// CHECK-LABEL: func @fuse_large_number_of_loops
-func @fuse_large_number_of_loops(%arg0: memref<20x10xf32, 1>, %arg1: memref<20x10xf32, 1>, %arg2: memref<20x10xf32, 1>, %arg3: memref<20x10xf32, 1>, %arg4: memref<20x10xf32, 1>, %arg5: memref<f32, 1>, %arg6: memref<f32, 1>, %arg7: memref<f32, 1>, %arg8: memref<f32, 1>, %arg9: memref<20x10xf32, 1>, %arg10: memref<20x10xf32, 1>, %arg11: memref<20x10xf32, 1>, %arg12: memref<20x10xf32, 1>) {
+func.func @fuse_large_number_of_loops(%arg0: memref<20x10xf32, 1>, %arg1: memref<20x10xf32, 1>, %arg2: memref<20x10xf32, 1>, %arg3: memref<20x10xf32, 1>, %arg4: memref<20x10xf32, 1>, %arg5: memref<f32, 1>, %arg6: memref<f32, 1>, %arg7: memref<f32, 1>, %arg8: memref<f32, 1>, %arg9: memref<20x10xf32, 1>, %arg10: memref<20x10xf32, 1>, %arg11: memref<20x10xf32, 1>, %arg12: memref<20x10xf32, 1>) {
%cst = arith.constant 1.000000e+00 : f32
%0 = memref.alloc() : memref<f32, 1>
affine.store %cst, %0[] : memref<f32, 1>
// Expects fusion of producer into consumer at depth 4 and subsequent removal of
// source loop.
// PRODUCER-CONSUMER-LABEL: func @unflatten4d
-func @unflatten4d(%arg1: memref<7x8x9x10xf32>) {
+func.func @unflatten4d(%arg1: memref<7x8x9x10xf32>) {
%m = memref.alloc() : memref<5040xf32>
%cf7 = arith.constant 7.0 : f32
// Expects fusion of producer into consumer at depth 2 and subsequent removal of
// source loop.
// PRODUCER-CONSUMER-LABEL: func @unflatten2d_with_transpose
-func @unflatten2d_with_transpose(%arg1: memref<8x7xf32>) {
+func.func @unflatten2d_with_transpose(%arg1: memref<8x7xf32>) {
%m = memref.alloc() : memref<56xf32>
%cf7 = arith.constant 7.0 : f32
// Expects fusion of producer into consumer at depth 1 and source loop to not
// be removed due to difference in loop steps.
// PRODUCER-CONSUMER-LABEL: func @check_src_dst_step
-func @check_src_dst_step(%m : memref<100xf32>,
+func.func @check_src_dst_step(%m : memref<100xf32>,
%src: memref<100xf32>,
%out: memref<100xf32>) {
affine.for %i0 = 0 to 100 {
// -----
// SIBLING-MAXIMAL-LABEL: func @reduce_add_non_maximal_f32_f32(
-func @reduce_add_non_maximal_f32_f32(%arg0: memref<64x64xf32, 1>, %arg1 : memref<1x64xf32, 1>, %arg2 : memref<1x64xf32, 1>) {
+func.func @reduce_add_non_maximal_f32_f32(%arg0: memref<64x64xf32, 1>, %arg1 : memref<1x64xf32, 1>, %arg2 : memref<1x64xf32, 1>) {
%cst_0 = arith.constant 0.000000e+00 : f32
%cst_1 = arith.constant 1.000000e+00 : f32
affine.for %arg3 = 0 to 1 {
// -----
// CHECK-LABEL: func @cannot_fuse_would_create_cycle() {
-func @cannot_fuse_would_create_cycle() {
+func.func @cannot_fuse_would_create_cycle() {
%a = memref.alloc() : memref<10xf32>
%b = memref.alloc() : memref<10xf32>
%c = memref.alloc() : memref<10xf32>
// -----
// CHECK-LABEL: func @can_fuse_rar_dependence() {
-func @can_fuse_rar_dependence() {
+func.func @can_fuse_rar_dependence() {
%a = memref.alloc() : memref<10xf32>
%b = memref.alloc() : memref<10xf32>
%c = memref.alloc() : memref<10xf32>
// -----
// CHECK-LABEL: func @can_fuse_different_memrefs() {
-func @can_fuse_different_memrefs() {
+func.func @can_fuse_different_memrefs() {
%a = memref.alloc() : memref<10xf32>
%b = memref.alloc() : memref<10xf32>
%c = memref.alloc() : memref<10xf32>
// -----
// CHECK-LABEL: func @should_not_fuse_across_intermediate_store() {
-func @should_not_fuse_across_intermediate_store() {
+func.func @should_not_fuse_across_intermediate_store() {
%0 = memref.alloc() : memref<10xf32>
%c0 = arith.constant 0 : index
%cf7 = arith.constant 7.0 : f32
// -----
// CHECK-LABEL: func @should_not_fuse_across_intermediate_load() {
-func @should_not_fuse_across_intermediate_load() {
+func.func @should_not_fuse_across_intermediate_load() {
%0 = memref.alloc() : memref<10xf32>
%c0 = arith.constant 0 : index
%cf7 = arith.constant 7.0 : f32
// -----
// CHECK-LABEL: func @should_not_fuse_across_ssa_value_def() {
-func @should_not_fuse_across_ssa_value_def() {
+func.func @should_not_fuse_across_ssa_value_def() {
%0 = memref.alloc() : memref<10xf32>
%1 = memref.alloc() : memref<10xf32>
%c0 = arith.constant 0 : index
// -----
// CHECK-LABEL: func @should_not_fuse_store_before_load() {
-func @should_not_fuse_store_before_load() {
+func.func @should_not_fuse_store_before_load() {
%0 = memref.alloc() : memref<10xf32>
%c0 = arith.constant 0 : index
%cf7 = arith.constant 7.0 : f32
// -----
// CHECK-LABEL: func @should_not_fuse_across_load_at_depth1() {
-func @should_not_fuse_across_load_at_depth1() {
+func.func @should_not_fuse_across_load_at_depth1() {
%0 = memref.alloc() : memref<10x10xf32>
%c0 = arith.constant 0 : index
%cf7 = arith.constant 7.0 : f32
// -----
// CHECK-LABEL: func @should_not_fuse_across_load_in_loop_at_depth1() {
-func @should_not_fuse_across_load_in_loop_at_depth1() {
+func.func @should_not_fuse_across_load_in_loop_at_depth1() {
%0 = memref.alloc() : memref<10x10xf32>
%c0 = arith.constant 0 : index
%cf7 = arith.constant 7.0 : f32
// -----
// CHECK-LABEL: func @should_not_fuse_across_store_at_depth1() {
-func @should_not_fuse_across_store_at_depth1() {
+func.func @should_not_fuse_across_store_at_depth1() {
%0 = memref.alloc() : memref<10x10xf32>
%c0 = arith.constant 0 : index
%cf7 = arith.constant 7.0 : f32
// -----
// CHECK-LABEL: func @should_not_fuse_across_store_in_loop_at_depth1() {
-func @should_not_fuse_across_store_in_loop_at_depth1() {
+func.func @should_not_fuse_across_store_in_loop_at_depth1() {
%0 = memref.alloc() : memref<10x10xf32>
%c0 = arith.constant 0 : index
%cf7 = arith.constant 7.0 : f32
// -----
// CHECK-LABEL: func @should_not_fuse_across_ssa_value_def_at_depth1() {
-func @should_not_fuse_across_ssa_value_def_at_depth1() {
+func.func @should_not_fuse_across_ssa_value_def_at_depth1() {
%0 = memref.alloc() : memref<10x10xf32>
%1 = memref.alloc() : memref<10x10xf32>
%c0 = arith.constant 0 : index
// -----
// CHECK-LABEL: func @slice_depth1_loop_nest() {
-func @slice_depth1_loop_nest() {
+func.func @slice_depth1_loop_nest() {
%0 = memref.alloc() : memref<100xf32>
%cst = arith.constant 7.000000e+00 : f32
affine.for %i0 = 0 to 16 {
// -----
// CHECK-LABEL: func @forward_slice_slice_depth1_loop_nest() {
-func @forward_slice_slice_depth1_loop_nest() {
+func.func @forward_slice_slice_depth1_loop_nest() {
%0 = memref.alloc() : memref<100xf32>
%cst = arith.constant 7.000000e+00 : f32
affine.for %i0 = 0 to 5 {
// Slice loop bounds should be adjusted such that the load/store are for the
// same location.
// CHECK-LABEL: func @slice_depth1_loop_nest_with_offsets() {
-func @slice_depth1_loop_nest_with_offsets() {
+func.func @slice_depth1_loop_nest_with_offsets() {
%0 = memref.alloc() : memref<100xf32>
%cst = arith.constant 7.000000e+00 : f32
affine.for %i0 = 0 to 16 {
// Slices at loop depth 1 should only slice the loop bounds of the first scf.
// Slices at loop depth 2 should slice loop bounds of both loops.
// CHECK-LABEL: func @slice_depth2_loop_nest() {
-func @slice_depth2_loop_nest() {
+func.func @slice_depth2_loop_nest() {
%0 = memref.alloc() : memref<100x100xf32>
%cst = arith.constant 7.000000e+00 : f32
affine.for %i0 = 0 to 16 {
// greater than 1. However, loop nest %i2 can be sliced into loop nest %i0 at
// depths 1 and 2 because the dependent store in loop nest %i0 is at depth 2.
// CHECK-LABEL: func @slice_depth2_loop_nest_two_loads() {
-func @slice_depth2_loop_nest_two_loads() {
+func.func @slice_depth2_loop_nest_two_loads() {
%0 = memref.alloc() : memref<100x100xf32>
%c0 = arith.constant 0 : index
%cst = arith.constant 7.000000e+00 : f32
// sliced into loop nest %i2 at depths 1 and 2 because the dependent load in
// loop nest %i2 is at depth 2.
// CHECK-LABEL: func @slice_depth2_loop_nest_two_stores() {
-func @slice_depth2_loop_nest_two_stores() {
+func.func @slice_depth2_loop_nest_two_stores() {
%0 = memref.alloc() : memref<100x100xf32>
%c0 = arith.constant 0 : index
%cst = arith.constant 7.000000e+00 : f32
// Test loop nest which has a smaller outer trip count than its inner scf.
// CHECK-LABEL: func @slice_loop_nest_with_smaller_outer_trip_count() {
-func @slice_loop_nest_with_smaller_outer_trip_count() {
+func.func @slice_loop_nest_with_smaller_outer_trip_count() {
%0 = memref.alloc() : memref<100x100xf32>
%c0 = arith.constant 0 : index
%cst = arith.constant 7.000000e+00 : f32
// RUN: mlir-opt %s -allow-unregistered-dialect -test-loop-fusion -test-loop-fusion-transformation -split-input-file -canonicalize | FileCheck %s
// CHECK-LABEL: func @slice_depth1_loop_nest() {
-func @slice_depth1_loop_nest() {
+func.func @slice_depth1_loop_nest() {
%0 = memref.alloc() : memref<100xf32>
%cst = arith.constant 7.000000e+00 : f32
affine.for %i0 = 0 to 16 {
// -----
// CHECK-LABEL: func @should_fuse_reduction_to_pointwise() {
-func @should_fuse_reduction_to_pointwise() {
+func.func @should_fuse_reduction_to_pointwise() {
%a = memref.alloc() : memref<10x10xf32>
%b = memref.alloc() : memref<10xf32>
%c = memref.alloc() : memref<10xf32>
// -----
// CHECK-LABEL: func @should_fuse_avoiding_dependence_cycle() {
-func @should_fuse_avoiding_dependence_cycle() {
+func.func @should_fuse_avoiding_dependence_cycle() {
%a = memref.alloc() : memref<10xf32>
%b = memref.alloc() : memref<10xf32>
%c = memref.alloc() : memref<10xf32>
// -----
// CHECK-LABEL: func @should_fuse_raw_dep_for_locality() {
-func @should_fuse_raw_dep_for_locality() {
+func.func @should_fuse_raw_dep_for_locality() {
%m = memref.alloc() : memref<10xf32>
%cf7 = arith.constant 7.0 : f32
// -----
// CHECK-LABEL: func @should_fuse_reduction_to_pointwise() {
-func @should_fuse_reduction_to_pointwise() {
+func.func @should_fuse_reduction_to_pointwise() {
%a = memref.alloc() : memref<10x10xf32>
%b = memref.alloc() : memref<10xf32>
%c = memref.alloc() : memref<10xf32>
// CHECK-DAG: [[$MAP_SHIFT_D1_BY_ONE:#map[0-9]+]] = affine_map<(d0, d1) -> (d1 + 1)>
// CHECK-LABEL: func @should_fuse_loop_nests_with_shifts() {
-func @should_fuse_loop_nests_with_shifts() {
+func.func @should_fuse_loop_nests_with_shifts() {
%a = memref.alloc() : memref<10x10xf32>
%cf7 = arith.constant 7.0 : f32
// -----
// CHECK-LABEL: func @should_fuse_loop_nest() {
-func @should_fuse_loop_nest() {
+func.func @should_fuse_loop_nest() {
%a = memref.alloc() : memref<10x10xf32>
%b = memref.alloc() : memref<10x10xf32>
%cf7 = arith.constant 7.0 : f32
// -----
// CHECK-LABEL: func @should_fuse_across_intermediate_loop_with_no_deps() {
-func @should_fuse_across_intermediate_loop_with_no_deps() {
+func.func @should_fuse_across_intermediate_loop_with_no_deps() {
%a = memref.alloc() : memref<10xf32>
%b = memref.alloc() : memref<10xf32>
%c = memref.alloc() : memref<10xf32>
// -----
// CHECK-LABEL: func @should_fuse_all_loops() {
-func @should_fuse_all_loops() {
+func.func @should_fuse_all_loops() {
%a = memref.alloc() : memref<10xf32>
%b = memref.alloc() : memref<10xf32>
%cf7 = arith.constant 7.0 : f32
// -----
// CHECK-LABEL: func @should_fuse_first_and_second_loops() {
-func @should_fuse_first_and_second_loops() {
+func.func @should_fuse_first_and_second_loops() {
%a = memref.alloc() : memref<10xf32>
%b = memref.alloc() : memref<10xf32>
%c = memref.alloc() : memref<10xf32>
// -----
// CHECK-LABEL: func @should_not_fuse_would_create_cycle() {
-func @should_not_fuse_would_create_cycle() {
+func.func @should_not_fuse_would_create_cycle() {
%a = memref.alloc() : memref<10xf32>
%b = memref.alloc() : memref<10xf32>
%c = memref.alloc() : memref<10xf32>
// -----
// CHECK-LABEL: func @should_fuse_producer_consumer() {
-func @should_fuse_producer_consumer() {
+func.func @should_fuse_producer_consumer() {
%m = memref.alloc() : memref<10xf32>
%cf7 = arith.constant 7.0 : f32
// -----
// CHECK-LABEL: func @should_fuse_and_move_to_preserve_war_dep() {
-func @should_fuse_and_move_to_preserve_war_dep() {
+func.func @should_fuse_and_move_to_preserve_war_dep() {
%a = memref.alloc() : memref<10xf32>
%b = memref.alloc() : memref<10xf32>
%cf7 = arith.constant 7.0 : f32
// -----
// CHECK-LABEL: func @should_fuse_if_top_level_access() {
-func @should_fuse_if_top_level_access() {
+func.func @should_fuse_if_top_level_access() {
%m = memref.alloc() : memref<10xf32>
%cf7 = arith.constant 7.0 : f32
// -----
// CHECK-LABEL: func @should_fuse_but_not_remove_src() {
-func @should_fuse_but_not_remove_src() {
+func.func @should_fuse_but_not_remove_src() {
%m = memref.alloc() : memref<100xf32>
%cf7 = arith.constant 7.0 : f32
// -----
// CHECK-LABEL: func @should_fuse_no_top_level_access() {
-func @should_fuse_no_top_level_access() {
+func.func @should_fuse_no_top_level_access() {
%m = memref.alloc() : memref<10xf32>
%cf7 = arith.constant 7.0 : f32
#set0 = affine_set<(d0) : (1 == 0)>
// CHECK-LABEL: func @should_not_fuse_if_op_at_top_level() {
-func @should_not_fuse_if_op_at_top_level() {
+func.func @should_not_fuse_if_op_at_top_level() {
%m = memref.alloc() : memref<10xf32>
%cf7 = arith.constant 7.0 : f32
#set0 = affine_set<(d0) : (1 == 0)>
// CHECK-LABEL: func @should_not_fuse_if_op_in_loop_nest() {
-func @should_not_fuse_if_op_in_loop_nest() {
+func.func @should_not_fuse_if_op_in_loop_nest() {
%m = memref.alloc() : memref<10xf32>
%cf7 = arith.constant 7.0 : f32
%c4 = arith.constant 4 : index
#set = affine_set<(d0) : (d0 - 1 >= 0)>
// CHECK-LABEL: func @should_fuse_if_op_in_loop_nest_not_sandwiched() -> memref<10xf32> {
-func @should_fuse_if_op_in_loop_nest_not_sandwiched() -> memref<10xf32> {
+func.func @should_fuse_if_op_in_loop_nest_not_sandwiched() -> memref<10xf32> {
%a = memref.alloc() : memref<10xf32>
%b = memref.alloc() : memref<10xf32>
%cf7 = arith.constant 7.0 : f32
#set = affine_set<(d0) : (d0 - 1 >= 0)>
// CHECK-LABEL: func @should_not_fuse_if_op_in_loop_nest_between_src_and_dest() -> memref<10xf32> {
-func @should_not_fuse_if_op_in_loop_nest_between_src_and_dest() -> memref<10xf32> {
+func.func @should_not_fuse_if_op_in_loop_nest_between_src_and_dest() -> memref<10xf32> {
%a = memref.alloc() : memref<10xf32>
%b = memref.alloc() : memref<10xf32>
%cf7 = arith.constant 7.0 : f32
// -----
// CHECK-LABEL: func @permute_and_fuse() {
-func @permute_and_fuse() {
+func.func @permute_and_fuse() {
%m = memref.alloc() : memref<10x20x30xf32>
%cf7 = arith.constant 7.0 : f32
// Reshape from a 64 x f32 to 16 x 4 x f32.
// CHECK-LABEL: func @fuse_reshape_64_16_4
-func @fuse_reshape_64_16_4(%in : memref<64xf32>) {
+func.func @fuse_reshape_64_16_4(%in : memref<64xf32>) {
%out = memref.alloc() : memref<16x4xf32>
affine.for %i0 = 0 to 64 {
// Reshape a 16x4xf32 to 64xf32.
// CHECK-LABEL: func @fuse_reshape_16_4_64
-func @fuse_reshape_16_4_64() {
+func.func @fuse_reshape_16_4_64() {
%in = memref.alloc() : memref<16x4xf32>
%out = memref.alloc() : memref<64xf32>
// All three loop nests below (6-d one, 2-d one, 2-d one is fused into a single
// 2-d loop nest).
-func @R6_to_R2_reshape_square() -> memref<64x9xi32> {
+func.func @R6_to_R2_reshape_square() -> memref<64x9xi32> {
%in = memref.alloc() : memref<2x2x3x3x16x1xi32>
%out = memref.alloc() : memref<64x9xi32>
%live_out = memref.alloc() : memref<64x9xi32>
// -----
// CHECK-LABEL: func @fuse_symbolic_bounds
-func @fuse_symbolic_bounds(%M : index, %N : index) {
+func.func @fuse_symbolic_bounds(%M : index, %N : index) {
%N_plus_5 = affine.apply affine_map<(d0) -> (d0 + 5)>(%N)
%m = memref.alloc(%M, %N_plus_5) : memref<? x ? x f32>
// -----
// CHECK-LABEL: func @should_fuse_reduction_at_depth_of_one
-func @should_fuse_reduction_at_depth_of_one() {
+func.func @should_fuse_reduction_at_depth_of_one() {
%a = memref.alloc() : memref<10x100xf32>
%b = memref.alloc() : memref<10xf32>
// -----
// CHECK-LABEL: func @should_fuse_at_src_depth1_and_dst_depth1
-func @should_fuse_at_src_depth1_and_dst_depth1() {
+func.func @should_fuse_at_src_depth1_and_dst_depth1() {
%a = memref.alloc() : memref<100x16xf32>
%b = memref.alloc() : memref<100x16xf32>
// CHECK: [[$MAP0:#map[0-9]*]] = affine_map<(d0, d1) -> (d0 * 10 + d1)>
// CHECK-LABEL: func @should_fuse_src_depth1_at_dst_depth2
-func @should_fuse_src_depth1_at_dst_depth2() {
+func.func @should_fuse_src_depth1_at_dst_depth2() {
%a = memref.alloc() : memref<100xf32>
%c0 = arith.constant 0.0 : f32
// -----
// CHECK-LABEL: func @fusion_at_depth0_not_currently_supported
-func @fusion_at_depth0_not_currently_supported() {
+func.func @fusion_at_depth0_not_currently_supported() {
%0 = memref.alloc() : memref<10xf32>
%c0 = arith.constant 0 : index
%cst = arith.constant 0.000000e+00 : f32
// -----
// CHECK-LABEL: func @should_fuse_deep_loop_nests
-func @should_fuse_deep_loop_nests() {
+func.func @should_fuse_deep_loop_nests() {
%0 = memref.alloc() : memref<2x2x3x3x16x10xf32, 2>
%1 = memref.alloc() : memref<2x2x3x3x16x10xf32, 2>
%2 = memref.alloc() : memref<3x3x3x3x16x10xf32, 2>
// -----
// CHECK-LABEL: func @should_fuse_at_depth1_and_reduce_slice_trip_count
-func @should_fuse_at_depth1_and_reduce_slice_trip_count() {
+func.func @should_fuse_at_depth1_and_reduce_slice_trip_count() {
%a = memref.alloc() : memref<4x256xf32>
%b = memref.alloc() : memref<4x256xf32>
// -----
// CHECK-LABEL: func @should_fuse_at_depth1_with_trip_count_20
-func @should_fuse_at_depth1_with_trip_count_20() {
+func.func @should_fuse_at_depth1_with_trip_count_20() {
%a = memref.alloc() : memref<100xf32>
%c0 = arith.constant 0 : index
%cf0 = arith.constant 0.0 : f32
// -----
// CHECK-LABEL: func @should_fuse_at_depth1_with_trip_count_19
-func @should_fuse_at_depth1_with_trip_count_19() {
+func.func @should_fuse_at_depth1_with_trip_count_19() {
%a = memref.alloc() : memref<100xf32>
%c0 = arith.constant 0 : index
%cf0 = arith.constant 0.0 : f32
// -----
// CHECK-LABEL: func @should_fuse_with_private_memrefs_with_diff_shapes() {
-func @should_fuse_with_private_memrefs_with_diff_shapes() {
+func.func @should_fuse_with_private_memrefs_with_diff_shapes() {
%m = memref.alloc() : memref<100xf32>
%cf7 = arith.constant 7.0 : f32
// -----
// CHECK-LABEL: func @should_fuse_live_out_arg_but_preserve_src_loop(%{{.*}}: memref<10xf32>) {
-func @should_fuse_live_out_arg_but_preserve_src_loop(%arg0: memref<10xf32>) {
+func.func @should_fuse_live_out_arg_but_preserve_src_loop(%arg0: memref<10xf32>) {
%cf7 = arith.constant 7.0 : f32
affine.for %i0 = 0 to 10 {
// -----
// CHECK-LABEL: func @should_fuse_live_out_arg(%{{.*}}: memref<10xf32>) {
-func @should_fuse_live_out_arg(%arg0: memref<10xf32>) {
+func.func @should_fuse_live_out_arg(%arg0: memref<10xf32>) {
%cf7 = arith.constant 7.0 : f32
affine.for %i0 = 0 to 10 {
// -----
// CHECK-LABEL: func @should_fuse_escaping_memref_but_preserve_src_loop() -> memref<10xf32>
-func @should_fuse_escaping_memref_but_preserve_src_loop() -> memref<10xf32> {
+func.func @should_fuse_escaping_memref_but_preserve_src_loop() -> memref<10xf32> {
%cf7 = arith.constant 7.0 : f32
%m = memref.alloc() : memref<10xf32>
affine.for %i0 = 0 to 10 {
// -----
// This should fuse with the %in becoming a 1x1x1.
-func @R3_to_R2_reshape() {
+func.func @R3_to_R2_reshape() {
%in = memref.alloc() : memref<2x3x16xi32>
%c0 = arith.constant 0 : index
// -----
-func @should_fuse_multi_output_producer() {
+func.func @should_fuse_multi_output_producer() {
%a = memref.alloc() : memref<10xf32>
%b = memref.alloc() : memref<10xf32>
// -----
// CHECK-LABEL: func @fusion_preventing_deps_on_middle_loop() {
-func @fusion_preventing_deps_on_middle_loop() {
+func.func @fusion_preventing_deps_on_middle_loop() {
%a = memref.alloc() : memref<10xf32>
%b = memref.alloc() : memref<10xf32>
%c = memref.alloc() : memref<10xf32>
// -----
// CHECK-LABEL: func @should_fuse_and_move_to_preserve_war_dep() {
-func @should_fuse_and_move_to_preserve_war_dep() {
+func.func @should_fuse_and_move_to_preserve_war_dep() {
%a = memref.alloc() : memref<10xf32>
%b = memref.alloc() : memref<10xf32>
%c = memref.alloc() : memref<10xf32>
// -----
// CHECK-LABEL: func @fusion_preventing_dep_on_constant() {
-func @fusion_preventing_dep_on_constant() {
+func.func @fusion_preventing_dep_on_constant() {
%a = memref.alloc() : memref<10xf32>
%b = memref.alloc() : memref<10xf32>
%c = memref.alloc() : memref<10xf32>
// -----
// CHECK-LABEL: func @should_fuse_and_preserve_dep_on_constant() {
-func @should_fuse_and_preserve_dep_on_constant() {
+func.func @should_fuse_and_preserve_dep_on_constant() {
%a = memref.alloc() : memref<10xf32>
%b = memref.alloc() : memref<10xf32>
%c = memref.alloc() : memref<10xf32>
// RUN: mlir-opt %s -split-input-file -loop-invariant-code-motion | FileCheck %s
-func @nested_loops_both_having_invariant_code() {
+func.func @nested_loops_both_having_invariant_code() {
%m = memref.alloc() : memref<10xf32>
%cf7 = arith.constant 7.0 : f32
%cf8 = arith.constant 8.0 : f32
// -----
-func @nested_loops_code_invariant_to_both() {
+func.func @nested_loops_code_invariant_to_both() {
%m = memref.alloc() : memref<10xf32>
%cf7 = arith.constant 7.0 : f32
%cf8 = arith.constant 8.0 : f32
// -----
-func @single_loop_nothing_invariant() {
+func.func @single_loop_nothing_invariant() {
%m1 = memref.alloc() : memref<10xf32>
%m2 = memref.alloc() : memref<10xf32>
affine.for %arg0 = 0 to 10 {
// -----
-func @invariant_code_inside_affine_if() {
+func.func @invariant_code_inside_affine_if() {
%m = memref.alloc() : memref<10xf32>
%cf8 = arith.constant 8.0 : f32
// -----
-func @invariant_affine_if() {
+func.func @invariant_affine_if() {
%m = memref.alloc() : memref<10xf32>
%cf8 = arith.constant 8.0 : f32
affine.for %arg0 = 0 to 10 {
// -----
-func @invariant_affine_if2() {
+func.func @invariant_affine_if2() {
%m = memref.alloc() : memref<10xf32>
%cf8 = arith.constant 8.0 : f32
affine.for %arg0 = 0 to 10 {
// -----
-func @invariant_affine_nested_if() {
+func.func @invariant_affine_nested_if() {
%m = memref.alloc() : memref<10xf32>
%cf8 = arith.constant 8.0 : f32
affine.for %arg0 = 0 to 10 {
// -----
-func @invariant_affine_nested_if_else() {
+func.func @invariant_affine_nested_if_else() {
%m = memref.alloc() : memref<10xf32>
%cf8 = arith.constant 8.0 : f32
affine.for %arg0 = 0 to 10 {
// -----
-func @invariant_loop_dialect() {
+func.func @invariant_loop_dialect() {
%ci0 = arith.constant 0 : index
%ci10 = arith.constant 10 : index
%ci1 = arith.constant 1 : index
// -----
-func @variant_loop_dialect() {
+func.func @variant_loop_dialect() {
%ci0 = arith.constant 0 : index
%ci10 = arith.constant 10 : index
%ci1 = arith.constant 1 : index
// -----
-func @parallel_loop_with_invariant() {
+func.func @parallel_loop_with_invariant() {
%c0 = arith.constant 0 : index
%c10 = arith.constant 10 : index
%c1 = arith.constant 1 : index
// -----
-func private @make_val() -> (index)
+func.func private @make_val() -> (index)
// CHECK-LABEL: func @nested_uses_inside
-func @nested_uses_inside(%lb: index, %ub: index, %step: index) {
+func.func @nested_uses_inside(%lb: index, %ub: index, %step: index) {
%true = arith.constant true
// Check that ops that contain nested uses to values not defiend outside
// dominance in non-graph regions.
// CHECK-LABEL: func @invariant_subgraph
// CHECK-SAME: %{{.*}}: index, %{{.*}}: index, %{{.*}}: index, %[[ARG:.*]]: i32
-func @invariant_subgraph(%lb: index, %ub: index, %step: index, %arg: i32) {
+func.func @invariant_subgraph(%lb: index, %ub: index, %step: index, %arg: i32) {
// CHECK: %[[V0:.*]] = arith.addi %[[ARG]], %[[ARG]]
// CHECK-NEXT: %[[V1:.*]] = arith.addi %[[ARG]], %[[V0]]
// CHECK-NEXT: scf.for
// Test invariant nested loop is hoisted.
// CHECK-LABEL: func @test_invariant_nested_loop
-func @test_invariant_nested_loop() {
+func.func @test_invariant_nested_loop() {
// CHECK: %[[C:.*]] = arith.constant
%0 = arith.constant 5 : i32
// CHECK: %[[V0:.*]] = arith.addi %[[C]], %[[C]]
// Test ops in a graph region are hoisted.
// CHECK-LABEL: func @test_invariants_in_graph_region
-func @test_invariants_in_graph_region() {
+func.func @test_invariants_in_graph_region() {
// CHECK: test.single_no_terminator_op
test.single_no_terminator_op : {
// CHECK-NEXT: %[[C:.*]] = arith.constant
// Test ops in a graph region are hoisted in topological order into non-graph
// regions and that dominance is preserved.
// CHECK-LABEL: func @test_invariant_backedge
-func @test_invariant_backedge() {
+func.func @test_invariant_backedge() {
// CHECK-NEXT: %[[C:.*]] = arith.constant
// CHECK-NEXT: %[[V1:.*]] = arith.addi %[[C]], %[[C]]
// CHECK-NEXT: %[[V0:.*]] = arith.addi %[[C]], %[[V1]]
// Test that cycles aren't hoisted from graph regions to non-graph regions.
// CHECK-LABEL: func @test_invariant_cycle_not_hoisted
-func @test_invariant_cycle_not_hoisted() {
+func.func @test_invariant_cycle_not_hoisted() {
// CHECK: test.graph_loop
test.graph_loop {
// CHECK-NEXT: %[[A:.*]] = "test.a"(%[[B:.*]]) :
// -----
// CHECK-LABEL: func @test() {
-func @test() {
+func.func @test() {
%zero = arith.constant 0 : index
%minusone = arith.constant -1 : index
%sym = arith.constant 111 : index
}
// CHECK-LABEL: func @test_mod_floordiv_ceildiv
-func @test_mod_floordiv_ceildiv() {
+func.func @test_mod_floordiv_ceildiv() {
%zero = arith.constant 0 : index
%A = memref.alloc() : memref<128 x 64 x 64 x i32>
}
// CHECK-LABEL: func @test_no_out_of_bounds()
-func @test_no_out_of_bounds() {
+func.func @test_no_out_of_bounds() {
%zero = arith.constant 0 : index
%A = memref.alloc() : memref<257 x 256 x i32>
%C = memref.alloc() : memref<257 x i32>
}
// CHECK-LABEL: func @mod_div
-func @mod_div() {
+func.func @mod_div() {
%zero = arith.constant 0 : index
%A = memref.alloc() : memref<128 x 64 x 64 x i32>
// Tests with nested mod's and floordiv's.
// CHECK-LABEL: func @mod_floordiv_nested() {
-func @mod_floordiv_nested() {
+func.func @mod_floordiv_nested() {
%A = memref.alloc() : memref<256 x 256 x i32>
affine.for %i = 0 to 256 {
affine.for %j = 0 to 256 {
}
// CHECK-LABEL: func @test_semi_affine_bailout
-func @test_semi_affine_bailout(%N : index) {
+func.func @test_semi_affine_bailout(%N : index) {
%B = memref.alloc() : memref<10 x i32>
affine.for %i = 0 to 10 {
%idx = affine.apply affine_map<(d0)[s0] -> (d0 * s0)>(%i)[%N]
}
// CHECK-LABEL: func @multi_mod_floordiv
-func @multi_mod_floordiv() {
+func.func @multi_mod_floordiv() {
%A = memref.alloc() : memref<2x2xi32>
affine.for %ii = 0 to 64 {
%idx0 = affine.apply affine_map<(d0) -> ((d0 mod 147456) floordiv 1152)> (%ii)
}
// CHECK-LABEL: func @delinearize_mod_floordiv
-func @delinearize_mod_floordiv() {
+func.func @delinearize_mod_floordiv() {
%c0 = arith.constant 0 : index
%in = memref.alloc() : memref<2x2x3x3x16x1xi32>
%out = memref.alloc() : memref<64x9xi32>
}
// CHECK-LABEL: func @zero_d_memref
-func @zero_d_memref(%arg0: memref<i32>) {
+func.func @zero_d_memref(%arg0: memref<i32>) {
%c0 = arith.constant 0 : i32
// A 0-d memref always has in-bound accesses!
affine.store %c0, %arg0[] : memref<i32>
}
// CHECK-LABEL: func @out_of_bounds
-func @out_of_bounds() {
+func.func @out_of_bounds() {
%in = memref.alloc() : memref<1xi32>
%c9 = arith.constant 9 : i32
#map4 = affine_map<(d0, d1) -> ((d0 * 72 + d1) mod 2304 - (((d0 * 72 + d1) mod 2304) floordiv 1152) * 1151 - ((((d0 * 72 + d1) mod 2304) mod 1152) floordiv 9) * 9 - (((((d0 * 72 + d1) mod 2304) mod 1152) mod 9) floordiv 3) * 3)>
#map5 = affine_map<(d0, d1) -> (((((d0 * 72 + d1) mod 2304) mod 1152) floordiv 9) floordiv 8)>
// CHECK-LABEL: func @test_complex_mod_floordiv
-func @test_complex_mod_floordiv(%arg0: memref<4x4x16x1xf32>) {
+func.func @test_complex_mod_floordiv(%arg0: memref<4x4x16x1xf32>) {
%c0 = arith.constant 0 : index
%0 = memref.alloc() : memref<1x2x3x3x16x1xf32>
affine.for %i0 = 0 to 64 {
#map1 = affine_map<(d0) -> (d0 mod 4 + 4)>
// CHECK-LABEL: func @test_mod_bound
-func @test_mod_bound() {
+func.func @test_mod_bound() {
%0 = memref.alloc() : memref<7 x f32>
%1 = memref.alloc() : memref<6 x f32>
affine.for %i0 = 0 to 4096 {
#map2 = affine_map<(d0) -> (4 * (d0 floordiv 4) + d0 mod 4)>
// CHECK-LABEL: func @test_floordiv_bound
-func @test_floordiv_bound() {
+func.func @test_floordiv_bound() {
%0 = memref.alloc() : memref<1027 x f32>
%1 = memref.alloc() : memref<1026 x f32>
%2 = memref.alloc() : memref<4096 x f32>
#map_ub = affine_map<(d0) -> (d0 + 4)>
// CHECK-LABEL: func @non_composed_bound_operand
-func @non_composed_bound_operand(%arg0: memref<1024xf32>) {
+func.func @non_composed_bound_operand(%arg0: memref<1024xf32>) {
affine.for %i0 = 4 to 1028 step 4 {
%i1 = affine.apply affine_map<(d0) -> (d0 - 4)> (%i0)
affine.for %i2 = #map_lb(%i1) to #map_ub(%i1) {
}
// CHECK-LABEL: func @zero_d_memref
-func @zero_d_memref() {
+func.func @zero_d_memref() {
%Z = memref.alloc() : memref<f32>
affine.for %i = 0 to 100 {
affine.load %Z[] : memref<f32>
#set0 = affine_set<(d0) : (1 == 0)>
// CHECK-LABEL: func @store_may_execute_before_load() {
-func @store_may_execute_before_load() {
+func.func @store_may_execute_before_load() {
%m = memref.alloc() : memref<10xf32>
%cf7 = arith.constant 7.0 : f32
%c0 = arith.constant 4 : index
// -----
// CHECK-LABEL: func @dependent_loops() {
-func @dependent_loops() {
+func.func @dependent_loops() {
%0 = memref.alloc() : memref<10xf32>
%cst = arith.constant 7.000000e+00 : f32
// There is a dependence from 0 to 1 at depth 1 (common surrounding loops 0)
// -----
// CHECK-LABEL: func @different_memrefs() {
-func @different_memrefs() {
+func.func @different_memrefs() {
%m.a = memref.alloc() : memref<100xf32>
%m.b = memref.alloc() : memref<100xf32>
%c0 = arith.constant 0 : index
// -----
// CHECK-LABEL: func @store_load_different_elements() {
-func @store_load_different_elements() {
+func.func @store_load_different_elements() {
%m = memref.alloc() : memref<100xf32>
%c0 = arith.constant 0 : index
%c1 = arith.constant 1 : index
// -----
// CHECK-LABEL: func @load_store_different_elements() {
-func @load_store_different_elements() {
+func.func @load_store_different_elements() {
%m = memref.alloc() : memref<100xf32>
%c0 = arith.constant 0 : index
%c1 = arith.constant 1 : index
// -----
// CHECK-LABEL: func @store_load_same_element() {
-func @store_load_same_element() {
+func.func @store_load_same_element() {
%m = memref.alloc() : memref<100xf32>
%c11 = arith.constant 11 : index
%c7 = arith.constant 7.0 : f32
// -----
// CHECK-LABEL: func @load_load_same_element() {
-func @load_load_same_element() {
+func.func @load_load_same_element() {
%m = memref.alloc() : memref<100xf32>
%c11 = arith.constant 11 : index
%c7 = arith.constant 7.0 : f32
// -----
// CHECK-LABEL: func @store_load_same_symbol(%arg0: index) {
-func @store_load_same_symbol(%arg0: index) {
+func.func @store_load_same_symbol(%arg0: index) {
%m = memref.alloc() : memref<100xf32>
%c7 = arith.constant 7.0 : f32
affine.store %c7, %m[%arg0] : memref<100xf32>
// -----
// CHECK-LABEL: func @store_load_different_symbols(%arg0: index, %arg1: index) {
-func @store_load_different_symbols(%arg0: index, %arg1: index) {
+func.func @store_load_different_symbols(%arg0: index, %arg1: index) {
%m = memref.alloc() : memref<100xf32>
%c7 = arith.constant 7.0 : f32
affine.store %c7, %m[%arg0] : memref<100xf32>
// -----
// CHECK-LABEL: func @store_load_diff_element_affine_apply_const() {
-func @store_load_diff_element_affine_apply_const() {
+func.func @store_load_diff_element_affine_apply_const() {
%m = memref.alloc() : memref<100xf32>
%c1 = arith.constant 1 : index
%c8 = arith.constant 8.0 : f32
// -----
// CHECK-LABEL: func @store_load_same_element_affine_apply_const() {
-func @store_load_same_element_affine_apply_const() {
+func.func @store_load_same_element_affine_apply_const() {
%m = memref.alloc() : memref<100xf32>
%c7 = arith.constant 7.0 : f32
%c9 = arith.constant 9 : index
// -----
// CHECK-LABEL: func @store_load_affine_apply_symbol(%arg0: index) {
-func @store_load_affine_apply_symbol(%arg0: index) {
+func.func @store_load_affine_apply_symbol(%arg0: index) {
%m = memref.alloc() : memref<100xf32>
%c7 = arith.constant 7.0 : f32
%a0 = affine.apply affine_map<(d0) -> (d0)> (%arg0)
// -----
// CHECK-LABEL: func @store_load_affine_apply_symbol_offset(%arg0: index) {
-func @store_load_affine_apply_symbol_offset(%arg0: index) {
+func.func @store_load_affine_apply_symbol_offset(%arg0: index) {
%m = memref.alloc() : memref<100xf32>
%c7 = arith.constant 7.0 : f32
%a0 = affine.apply affine_map<(d0) -> (d0)> (%arg0)
// -----
// CHECK-LABEL: func @store_range_load_after_range() {
-func @store_range_load_after_range() {
+func.func @store_range_load_after_range() {
%m = memref.alloc() : memref<100xf32>
%c7 = arith.constant 7.0 : f32
%c10 = arith.constant 10 : index
// -----
// CHECK-LABEL: func @store_load_func_symbol(%arg0: index, %arg1: index) {
-func @store_load_func_symbol(%arg0: index, %arg1: index) {
+func.func @store_load_func_symbol(%arg0: index, %arg1: index) {
%m = memref.alloc() : memref<100xf32>
%c7 = arith.constant 7.0 : f32
%c10 = arith.constant 10 : index
// -----
// CHECK-LABEL: func @store_range_load_last_in_range() {
-func @store_range_load_last_in_range() {
+func.func @store_range_load_last_in_range() {
%m = memref.alloc() : memref<100xf32>
%c7 = arith.constant 7.0 : f32
%c10 = arith.constant 10 : index
// -----
// CHECK-LABEL: func @store_range_load_before_range() {
-func @store_range_load_before_range() {
+func.func @store_range_load_before_range() {
%m = memref.alloc() : memref<100xf32>
%c7 = arith.constant 7.0 : f32
%c0 = arith.constant 0 : index
// -----
// CHECK-LABEL: func @store_range_load_first_in_range() {
-func @store_range_load_first_in_range() {
+func.func @store_range_load_first_in_range() {
%m = memref.alloc() : memref<100xf32>
%c7 = arith.constant 7.0 : f32
%c0 = arith.constant 0 : index
// -----
// CHECK-LABEL: func @store_plus_3() {
-func @store_plus_3() {
+func.func @store_plus_3() {
%m = memref.alloc() : memref<100xf32>
%c7 = arith.constant 7.0 : f32
affine.for %i0 = 1 to 11 {
// -----
// CHECK-LABEL: func @load_minus_2() {
-func @load_minus_2() {
+func.func @load_minus_2() {
%m = memref.alloc() : memref<100xf32>
%c7 = arith.constant 7.0 : f32
affine.for %i0 = 2 to 11 {
// -----
// CHECK-LABEL: func @perfectly_nested_loops_loop_independent() {
-func @perfectly_nested_loops_loop_independent() {
+func.func @perfectly_nested_loops_loop_independent() {
%m = memref.alloc() : memref<10x10xf32>
%c7 = arith.constant 7.0 : f32
affine.for %i0 = 0 to 11 {
// -----
// CHECK-LABEL: func @perfectly_nested_loops_loop_carried_at_depth1() {
-func @perfectly_nested_loops_loop_carried_at_depth1() {
+func.func @perfectly_nested_loops_loop_carried_at_depth1() {
%m = memref.alloc() : memref<10x10xf32>
%c7 = arith.constant 7.0 : f32
affine.for %i0 = 0 to 9 {
// -----
// CHECK-LABEL: func @perfectly_nested_loops_loop_carried_at_depth2() {
-func @perfectly_nested_loops_loop_carried_at_depth2() {
+func.func @perfectly_nested_loops_loop_carried_at_depth2() {
%m = memref.alloc() : memref<10x10xf32>
%c7 = arith.constant 7.0 : f32
affine.for %i0 = 0 to 10 {
// -----
// CHECK-LABEL: func @one_common_loop() {
-func @one_common_loop() {
+func.func @one_common_loop() {
%m = memref.alloc() : memref<10x10xf32>
%c7 = arith.constant 7.0 : f32
// There is a loop-independent dependence from access 0 to 1 at depth 2.
// -----
// CHECK-LABEL: func @dependence_cycle() {
-func @dependence_cycle() {
+func.func @dependence_cycle() {
%m.a = memref.alloc() : memref<100xf32>
%m.b = memref.alloc() : memref<100xf32>
// -----
// CHECK-LABEL: func @negative_and_positive_direction_vectors(%arg0: index, %arg1: index) {
-func @negative_and_positive_direction_vectors(%arg0: index, %arg1: index) {
+func.func @negative_and_positive_direction_vectors(%arg0: index, %arg1: index) {
%m = memref.alloc() : memref<10x10xf32>
%c7 = arith.constant 7.0 : f32
affine.for %i0 = 0 to %arg0 {
// -----
// CHECK-LABEL: func @war_raw_waw_deps() {
-func @war_raw_waw_deps() {
+func.func @war_raw_waw_deps() {
%m = memref.alloc() : memref<100xf32>
%c7 = arith.constant 7.0 : f32
affine.for %i0 = 0 to 10 {
// -----
// CHECK-LABEL: func @mod_deps() {
-func @mod_deps() {
+func.func @mod_deps() {
%m = memref.alloc() : memref<100xf32>
%c7 = arith.constant 7.0 : f32
affine.for %i0 = 0 to 10 {
// -----
// CHECK-LABEL: func @loop_nest_depth() {
-func @loop_nest_depth() {
+func.func @loop_nest_depth() {
%0 = memref.alloc() : memref<100x100xf32>
%c7 = arith.constant 7.0 : f32
// Test case to exercise sanity when flattening multiple expressions involving
// mod/div's successively.
// CHECK-LABEL: func @mod_div_3d() {
-func @mod_div_3d() {
+func.func @mod_div_3d() {
%M = memref.alloc() : memref<2x2x2xi32>
%c0 = arith.constant 0 : i32
affine.for %i0 = 0 to 8 {
// -----
// This test case arises in the context of a 6-d to 2-d reshape.
// CHECK-LABEL: func @delinearize_mod_floordiv
-func @delinearize_mod_floordiv() {
+func.func @delinearize_mod_floordiv() {
%c0 = arith.constant 0 : index
%val = arith.constant 0 : i32
%in = memref.alloc() : memref<2x2x3x3x16x1xi32>
// Load and store ops access the same elements in strided scf.
// CHECK-LABEL: func @strided_loop_with_dependence_at_depth2
-func @strided_loop_with_dependence_at_depth2() {
+func.func @strided_loop_with_dependence_at_depth2() {
%0 = memref.alloc() : memref<10xf32>
%cf0 = arith.constant 0.0 : f32
affine.for %i0 = 0 to 8 step 2 {
// Load and store ops access alternating memref elements: no dependence.
// CHECK-LABEL: func @strided_loop_with_no_dependence
-func @strided_loop_with_no_dependence() {
+func.func @strided_loop_with_no_dependence() {
%0 = memref.alloc() : memref<10xf32>
%cf0 = arith.constant 0.0 : f32
affine.for %i0 = 0 to 8 step 2 {
// Affine.Store op accesses memref elements at offset causing loop-carried dependence.
// CHECK-LABEL: func @strided_loop_with_loop_carried_dependence_at_depth1
-func @strided_loop_with_loop_carried_dependence_at_depth1() {
+func.func @strided_loop_with_loop_carried_dependence_at_depth1() {
%0 = memref.alloc() : memref<10xf32>
%cf0 = arith.constant 0.0 : f32
affine.for %i0 = 0 to 8 step 2 {
// Test that the loop carried dependence from load to store on '%i0' is
// properly computed when the load and store are at different loop depths.
// CHECK-LABEL: func @test_dep_store_depth1_load_depth2
-func @test_dep_store_depth1_load_depth2() {
+func.func @test_dep_store_depth1_load_depth2() {
%0 = memref.alloc() : memref<100xf32>
%cst = arith.constant 7.000000e+00 : f32
affine.for %i0 = 0 to 10 {
// Test that the loop carried dependence from store to load on '%i0' is
// properly computed when the load and store are at different loop depths.
// CHECK-LABEL: func @test_dep_store_depth2_load_depth1
-func @test_dep_store_depth2_load_depth1() {
+func.func @test_dep_store_depth2_load_depth1() {
%0 = memref.alloc() : memref<100xf32>
%cst = arith.constant 7.000000e+00 : f32
affine.for %i0 = 0 to 10 {
#set = affine_set<(d0): (d0 - 50 >= 0)>
// CHECK-LABEL: func @test_affine_for_if_same_block() {
-func @test_affine_for_if_same_block() {
+func.func @test_affine_for_if_same_block() {
%0 = memref.alloc() : memref<100xf32>
%cf7 = arith.constant 7.0 : f32
#set = affine_set<(d0): (d0 - 50 >= 0)>
// CHECK-LABEL: func @test_affine_for_if_separated() {
-func @test_affine_for_if_separated() {
+func.func @test_affine_for_if_separated() {
%0 = memref.alloc() : memref<100xf32>
%cf7 = arith.constant 7.0 : f32
#set2 = affine_set<(d0): (- d0 + 75 >= 0)>
// CHECK-LABEL: func @test_affine_for_if_partially_joined() {
-func @test_affine_for_if_partially_joined() {
+func.func @test_affine_for_if_partially_joined() {
%0 = memref.alloc() : memref<100xf32>
%cf7 = arith.constant 7.0 : f32
#set2 = affine_set<(d0, d1): (d0 - 75 >= 0, d1 - 50 >= 0)>
// CHECK-LABEL: func @test_interleaved_affine_for_if() {
-func @test_interleaved_affine_for_if() {
+func.func @test_interleaved_affine_for_if() {
%0 = memref.alloc() : memref<100x100xf32>
%cf7 = arith.constant 7.0 : f32
#set2 = affine_set<(d0): (- d0 + 51 >= 0)>
// CHECK-LABEL: func @test_interleaved_affine_for_if() {
-func @test_interleaved_affine_for_if() {
+func.func @test_interleaved_affine_for_if() {
%0 = memref.alloc() : memref<101xf32>
%c0 = arith.constant 0 : index
%N = memref.dim %0, %c0 : memref<101xf32>
// CHECK-LABEL: test_norm_dynamic12
// CHECK-SAME: ([[ARG_0_:%.+]]: memref<1x?x?x1x?x64xf32>) {
-func @test_norm_dynamic12(%arg0 : memref<1x?x?x14xf32, #map_tiled>) -> () {
+func.func @test_norm_dynamic12(%arg0 : memref<1x?x?x14xf32, #map_tiled>) -> () {
%c1 = arith.constant 1 : index
%c2 = arith.constant 2 : index
%0 = memref.dim %arg0, %c1 :memref<1x?x?x14xf32, #map_tiled>
// CHECK-LABEL: test_norm_dynamic1234
// CHECK-SAME: ([[ARG_0_:%.+]]: memref<?x?x?x?x?x?xf32>) {
-func @test_norm_dynamic1234(%arg0 : memref<?x?x?x?xf32, #map_tiled1>) -> () {
+func.func @test_norm_dynamic1234(%arg0 : memref<?x?x?x?xf32, #map_tiled1>) -> () {
%c0 = arith.constant 0 : index
%c1 = arith.constant 1 : index
%c2 = arith.constant 2 : index
// CHECK-LABEL: func @test_norm_dynamic_not_tiled0
// CHECK-SAME: ([[ARG_0_:%.+]]: memref<1x?x?x14xf32, #[[$MAP6]]>) {
-func @test_norm_dynamic_not_tiled0(%arg0 : memref<1x?x?x14xf32, #map_not_tiled0>) -> () {
+func.func @test_norm_dynamic_not_tiled0(%arg0 : memref<1x?x?x14xf32, #map_not_tiled0>) -> () {
%c1 = arith.constant 1 : index
%c2 = arith.constant 2 : index
%0 = memref.dim %arg0, %c1 :memref<1x?x?x14xf32, #map_not_tiled0>
// CHECK-LABEL: func @test_norm_dynamic_not_tiled1
// CHECK-SAME: ([[ARG_0_:%.+]]: memref<1x?x?x14xf32, #[[$MAP6]]>) {
-func @test_norm_dynamic_not_tiled1(%arg0 : memref<1x?x?x14xf32, #map_not_tiled1>) -> () {
+func.func @test_norm_dynamic_not_tiled1(%arg0 : memref<1x?x?x14xf32, #map_not_tiled1>) -> () {
%c1 = arith.constant 1 : index
%c2 = arith.constant 2 : index
%0 = memref.dim %arg0, %c1 :memref<1x?x?x14xf32, #map_not_tiled1>
// CHECK-LABEL: func @test_norm_dynamic_not_tiled2
// CHECK-SAME: ([[ARG_0_:%.+]]: memref<1x?x?x14xf32, #[[$MAP7]]>) {
-func @test_norm_dynamic_not_tiled2(%arg0 : memref<1x?x?x14xf32, #map_not_tiled2>) -> () {
+func.func @test_norm_dynamic_not_tiled2(%arg0 : memref<1x?x?x14xf32, #map_not_tiled2>) -> () {
%c1 = arith.constant 1 : index
%c2 = arith.constant 2 : index
%0 = memref.dim %arg0, %c1 :memref<1x?x?x14xf32, #map_not_tiled2>
// CHECK-LABEL: func @test_norm_dynamic_not_tiled3
// CHECK-SAME: ([[ARG_0_:%.+]]: memref<1x?x?x14xf32, #[[$MAP8]]>) {
-func @test_norm_dynamic_not_tiled3(%arg0 : memref<1x?x?x14xf32, #map_not_tiled3>) -> () {
+func.func @test_norm_dynamic_not_tiled3(%arg0 : memref<1x?x?x14xf32, #map_not_tiled3>) -> () {
%c1 = arith.constant 1 : index
%c2 = arith.constant 2 : index
%0 = memref.dim %arg0, %c1 :memref<1x?x?x14xf32, #map_not_tiled3>
// CHECK-LABEL: func @test_norm_dynamic_not_tiled4
// CHECK-SAME: ([[ARG_0_:%.+]]: memref<1x?x?x14xf32, #[[$MAP9]]>) {
-func @test_norm_dynamic_not_tiled4(%arg0 : memref<1x?x?x14xf32, #map_not_tiled4>) -> () {
+func.func @test_norm_dynamic_not_tiled4(%arg0 : memref<1x?x?x14xf32, #map_not_tiled4>) -> () {
%c1 = arith.constant 1 : index
%c2 = arith.constant 2 : index
%0 = memref.dim %arg0, %c1 :memref<1x?x?x14xf32, #map_not_tiled4>
// CHECK-LABEL: test_norm
// CHECK-SAME: (%[[ARG0:.*]]: memref<1x16x1x1x32x64xf32>)
-func @test_norm(%arg0 : memref<1x16x14x14xf32, #map0>) -> () {
+func.func @test_norm(%arg0 : memref<1x16x14x14xf32, #map0>) -> () {
%0 = memref.alloc() : memref<1x16x14x14xf32, #map0>
"test.op_norm"(%arg0, %0) : (memref<1x16x14x14xf32, #map0>, memref<1x16x14x14xf32, #map0>) -> ()
memref.dealloc %0 : memref<1x16x14x14xf32, #map0>
// CHECK-LABEL: test_nonnorm
// CHECK-SAME: (%[[ARG0:.*]]: memref<1x16x14x14xf32, #map>)
-func @test_nonnorm(%arg0 : memref<1x16x14x14xf32, #map0>) -> () {
+func.func @test_nonnorm(%arg0 : memref<1x16x14x14xf32, #map0>) -> () {
%0 = memref.alloc() : memref<1x16x14x14xf32, #map0>
"test.op_nonnorm"(%arg0, %0) : (memref<1x16x14x14xf32, #map0>, memref<1x16x14x14xf32, #map0>) -> ()
memref.dealloc %0 : memref<1x16x14x14xf32, #map0>
// CHECK-LABEL: test_norm_mix
// CHECK-SAME: (%[[ARG0:.*]]: memref<1x16x1x1x32x64xf32>
-func @test_norm_mix(%arg0 : memref<1x16x1x1x32x64xf32>) -> () {
+func.func @test_norm_mix(%arg0 : memref<1x16x1x1x32x64xf32>) -> () {
%0 = memref.alloc() : memref<1x16x14x14xf32, #map0>
"test.op_norm"(%arg0, %0) : (memref<1x16x1x1x32x64xf32>, memref<1x16x14x14xf32, #map0>) -> ()
memref.dealloc %0 : memref<1x16x14x14xf32, #map0>
// CHECK-LABEL: test_load_store
// CHECK-SAME: (%[[ARG0:.*]]: memref<1x16x14x14xf32>
-func @test_load_store(%arg0 : memref<1x16x14x14xf32>) -> () {
+func.func @test_load_store(%arg0 : memref<1x16x14x14xf32>) -> () {
%0 = memref.alloc() : memref<1x16x14x14xf32, #map_tile>
// CHECK: %[[v0:.*]] = memref.alloc() : memref<1x16x1x1x32x32xf32>
%1 = memref.alloc() : memref<1x16x14x14xf32>
// CHECK-LABEL: test_norm_ret
// CHECK-SAME: (%[[ARG0:.*]]: memref<1x16x1x1x32x32xf32>) -> (memref<1x16x1x1x32x32xf32>, memref<1x16x14x14xf32>) {
-func @test_norm_ret(%arg0: memref<1x16x14x14xf32, #map_tile>) -> (memref<1x16x14x14xf32, #map_tile>, memref<1x16x14x14xf32>) {
+func.func @test_norm_ret(%arg0: memref<1x16x14x14xf32, #map_tile>) -> (memref<1x16x14x14xf32, #map_tile>, memref<1x16x14x14xf32>) {
%0 = memref.alloc() : memref<1x16x14x14xf32, #map_tile>
// CHECK-NEXT: %[[v0:.*]] = memref.alloc() : memref<1x16x1x1x32x32xf32>
%1, %2 = "test.op_norm_ret"(%arg0) : (memref<1x16x14x14xf32, #map_tile>) -> (memref<1x16x14x14xf32, #map_tile>, memref<1x16x14x14xf32>)
// CHECK-LABEL: test_norm_reinterpret_cast
// CHECK-SAME: (%[[ARG0:.*]]: memref<1x32xf32>) -> memref<3x1x1xf32> {
-func @test_norm_reinterpret_cast(%arg0 : memref<3xf32, #map_1d_tile>) -> (memref<3x1x1xf32>) {
+func.func @test_norm_reinterpret_cast(%arg0 : memref<3xf32, #map_1d_tile>) -> (memref<3x1x1xf32>) {
%0 = memref.alloc() : memref<3xf32>
"test.op_norm"(%arg0, %0) : (memref<3xf32, #map_1d_tile>, memref<3xf32>) -> ()
%1 = memref.reinterpret_cast %0 to offset: [0], sizes: [3, 1, 1], strides: [1, 1, 1] : memref<3xf32> to memref<3x1x1xf32>
// are normalized to trivial (identity) layouts.
// CHECK-LABEL: func @permute()
-func @permute() {
+func.func @permute() {
%A = memref.alloc() : memref<64x256xf32, affine_map<(d0, d1) -> (d1, d0)>>
affine.for %i = 0 to 64 {
affine.for %j = 0 to 256 {
// CHECK-NEXT: return
// CHECK-LABEL: func @shift
-func @shift(%idx : index) {
+func.func @shift(%idx : index) {
// CHECK-NEXT: memref.alloc() : memref<65xf32>
%A = memref.alloc() : memref<64xf32, affine_map<(d0) -> (d0 + 1)>>
// CHECK-NEXT: affine.load %{{.*}}[symbol(%arg0) + 1] : memref<65xf32>
}
// CHECK-LABEL: func @high_dim_permute()
-func @high_dim_permute() {
+func.func @high_dim_permute() {
// CHECK-NOT: memref<64x128x256xf32,
%A = memref.alloc() : memref<64x128x256xf32, affine_map<(d0, d1, d2) -> (d2, d0, d1)>>
// CHECK: %[[I:arg[0-9]+]]
}
// CHECK-LABEL: func @invalid_map
-func @invalid_map() {
+func.func @invalid_map() {
%A = memref.alloc() : memref<64x128xf32, affine_map<(d0, d1) -> (d0, -d1 - 10)>>
// CHECK: %{{.*}} = memref.alloc() : memref<64x128xf32,
return
// A tiled layout.
// CHECK-LABEL: func @data_tiling
-func @data_tiling(%idx : index) {
+func.func @data_tiling(%idx : index) {
// CHECK: memref.alloc() : memref<8x32x8x16xf32>
%A = memref.alloc() : memref<64x512xf32, affine_map<(d0, d1) -> (d0 floordiv 8, d1 floordiv 16, d0 mod 8, d1 mod 16)>>
// CHECK: affine.load %{{.*}}[symbol(%arg0) floordiv 8, symbol(%arg0) floordiv 16, symbol(%arg0) mod 8, symbol(%arg0) mod 16]
// Strides 2 and 4 along respective dimensions.
// CHECK-LABEL: func @strided
-func @strided() {
+func.func @strided() {
%A = memref.alloc() : memref<64x128xf32, affine_map<(d0, d1) -> (2*d0, 4*d1)>>
// CHECK: affine.for %[[IV0:.*]] =
affine.for %i = 0 to 64 {
// Strided, but the strides are in the linearized space.
// CHECK-LABEL: func @strided_cumulative
-func @strided_cumulative() {
+func.func @strided_cumulative() {
%A = memref.alloc() : memref<2x5xf32, affine_map<(d0, d1) -> (3*d0 + 17*d1)>>
// CHECK: affine.for %[[IV0:.*]] =
affine.for %i = 0 to 2 {
// Symbolic operand for alloc, although unused. Tests replaceAllMemRefUsesWith
// when the index remap has symbols.
// CHECK-LABEL: func @symbolic_operands
-func @symbolic_operands(%s : index) {
+func.func @symbolic_operands(%s : index) {
// CHECK: memref.alloc() : memref<100xf32>
%A = memref.alloc()[%s] : memref<10x10xf32, affine_map<(d0,d1)[s0] -> (10*d0 + d1)>>
affine.for %i = 0 to 10 {
// Semi-affine maps, normalization not implemented yet.
// CHECK-LABEL: func @semi_affine_layout_map
-func @semi_affine_layout_map(%s0: index, %s1: index) {
+func.func @semi_affine_layout_map(%s0: index, %s1: index) {
%A = memref.alloc()[%s0, %s1] : memref<256x1024xf32, affine_map<(d0, d1)[s0, s1] -> (d0*s0 + d1*s1)>>
affine.for %i = 0 to 256 {
affine.for %j = 0 to 1024 {
}
// CHECK-LABEL: func @alignment
-func @alignment() {
+func.func @alignment() {
%A = memref.alloc() {alignment = 32 : i64}: memref<64x128x256xf32, affine_map<(d0, d1, d2) -> (d2, d0, d1)>>
// CHECK-NEXT: memref.alloc() {alignment = 32 : i64} : memref<256x64x128xf32>
return
// Test case 1: Check normalization for multiple memrefs in a function argument list.
// CHECK-LABEL: func @multiple_argument_type
// CHECK-SAME: (%[[A:arg[0-9]+]]: memref<4x4xf64>, %[[B:arg[0-9]+]]: f64, %[[C:arg[0-9]+]]: memref<2x4xf64>, %[[D:arg[0-9]+]]: memref<24xf64>) -> f64
-func @multiple_argument_type(%A: memref<16xf64, #tile>, %B: f64, %C: memref<8xf64, #tile>, %D: memref<24xf64>) -> f64 {
+func.func @multiple_argument_type(%A: memref<16xf64, #tile>, %B: f64, %C: memref<8xf64, #tile>, %D: memref<24xf64>) -> f64 {
%a = affine.load %A[0] : memref<16xf64, #tile>
%p = arith.mulf %a, %a : f64
affine.store %p, %A[10] : memref<16xf64, #tile>
// Test case 2: Check normalization for single memref argument in a function.
// CHECK-LABEL: func @single_argument_type
// CHECK-SAME: (%[[C:arg[0-9]+]]: memref<2x4xf64>)
-func @single_argument_type(%C : memref<8xf64, #tile>) {
+func.func @single_argument_type(%C : memref<8xf64, #tile>) {
%a = memref.alloc(): memref<8xf64, #tile>
%b = memref.alloc(): memref<16xf64, #tile>
%d = arith.constant 23.0 : f64
// Test case 3: Check function returning any other type except memref.
// CHECK-LABEL: func @non_memref_ret
// CHECK-SAME: (%[[C:arg[0-9]+]]: memref<2x4xf64>) -> i1
-func @non_memref_ret(%A: memref<8xf64, #tile>) -> i1 {
+func.func @non_memref_ret(%A: memref<8xf64, #tile>) -> i1 {
%d = arith.constant 1 : i1
return %d : i1
}
// Test case 4: Check successful memref normalization in case of inter/intra-recursive calls.
// CHECK-LABEL: func @ret_multiple_argument_type
// CHECK-SAME: (%[[A:arg[0-9]+]]: memref<4x4xf64>, %[[B:arg[0-9]+]]: f64, %[[C:arg[0-9]+]]: memref<2x4xf64>) -> (memref<2x4xf64>, f64)
-func @ret_multiple_argument_type(%A: memref<16xf64, #tile>, %B: f64, %C: memref<8xf64, #tile>) -> (memref<8xf64, #tile>, f64) {
+func.func @ret_multiple_argument_type(%A: memref<16xf64, #tile>, %B: f64, %C: memref<8xf64, #tile>) -> (memref<8xf64, #tile>, f64) {
%a = affine.load %A[0] : memref<16xf64, #tile>
%p = arith.mulf %a, %a : f64
%cond = arith.constant 1 : i1
// CHECK-LABEL: func @ret_single_argument_type
// CHECK-SAME: (%[[C:arg[0-9]+]]: memref<2x4xf64>) -> (memref<4x4xf64>, memref<2x4xf64>)
-func @ret_single_argument_type(%C: memref<8xf64, #tile>) -> (memref<16xf64, #tile>, memref<8xf64, #tile>){
+func.func @ret_single_argument_type(%C: memref<8xf64, #tile>) -> (memref<16xf64, #tile>, memref<8xf64, #tile>){
%a = memref.alloc() : memref<8xf64, #tile>
%b = memref.alloc() : memref<16xf64, #tile>
%d = arith.constant 23.0 : f64
// Test case set #5: To check normalization in a chain of interconnected functions.
// CHECK-LABEL: func @func_A
// CHECK-SAME: (%[[A:arg[0-9]+]]: memref<2x4xf64>)
-func @func_A(%A: memref<8xf64, #tile>) {
+func.func @func_A(%A: memref<8xf64, #tile>) {
call @func_B(%A) : (memref<8xf64, #tile>) -> ()
return
}
// CHECK-LABEL: func @func_B
// CHECK-SAME: (%[[A:arg[0-9]+]]: memref<2x4xf64>)
-func @func_B(%A: memref<8xf64, #tile>) {
+func.func @func_B(%A: memref<8xf64, #tile>) {
call @func_C(%A) : (memref<8xf64, #tile>) -> ()
return
}
// CHECK-LABEL: func @func_C
// CHECK-SAME: (%[[A:arg[0-9]+]]: memref<2x4xf64>)
-func @func_C(%A: memref<8xf64, #tile>) {
+func.func @func_C(%A: memref<8xf64, #tile>) {
return
}
// Test case set #6: Checking if no normalization takes place in a scenario: A -> B -> C and B has an unsupported type.
// CHECK-LABEL: func @some_func_A
// CHECK-SAME: (%[[A:arg[0-9]+]]: memref<8xf64, #map{{[0-9]+}}>)
-func @some_func_A(%A: memref<8xf64, #tile>) {
+func.func @some_func_A(%A: memref<8xf64, #tile>) {
call @some_func_B(%A) : (memref<8xf64, #tile>) -> ()
return
}
// CHECK-LABEL: func @some_func_B
// CHECK-SAME: (%[[A:arg[0-9]+]]: memref<8xf64, #map{{[0-9]+}}>)
-func @some_func_B(%A: memref<8xf64, #tile>) {
+func.func @some_func_B(%A: memref<8xf64, #tile>) {
"test.test"(%A) : (memref<8xf64, #tile>) -> ()
call @some_func_C(%A) : (memref<8xf64, #tile>) -> ()
return
// CHECK-LABEL: func @some_func_C
// CHECK-SAME: (%[[A:arg[0-9]+]]: memref<8xf64, #map{{[0-9]+}}>)
-func @some_func_C(%A: memref<8xf64, #tile>) {
+func.func @some_func_C(%A: memref<8xf64, #tile>) {
return
}
// Test case set #7: Check normalization in case of external functions.
// CHECK-LABEL: func private @external_func_A
// CHECK-SAME: (memref<4x4xf64>)
-func private @external_func_A(memref<16xf64, #tile>) -> ()
+func.func private @external_func_A(memref<16xf64, #tile>) -> ()
// CHECK-LABEL: func private @external_func_B
// CHECK-SAME: (memref<4x4xf64>, f64) -> memref<2x4xf64>
-func private @external_func_B(memref<16xf64, #tile>, f64) -> (memref<8xf64, #tile>)
+func.func private @external_func_B(memref<16xf64, #tile>, f64) -> (memref<8xf64, #tile>)
// CHECK-LABEL: func @simply_call_external()
-func @simply_call_external() {
+func.func @simply_call_external() {
%a = memref.alloc() : memref<16xf64, #tile>
call @external_func_A(%a) : (memref<16xf64, #tile>) -> ()
return
// CHECK-LABEL: func @use_value_of_external
// CHECK-SAME: (%[[A:arg[0-9]+]]: memref<4x4xf64>, %[[B:arg[0-9]+]]: f64) -> memref<2x4xf64>
-func @use_value_of_external(%A: memref<16xf64, #tile>, %B: f64) -> (memref<8xf64, #tile>) {
+func.func @use_value_of_external(%A: memref<16xf64, #tile>, %B: f64) -> (memref<8xf64, #tile>) {
%res = call @external_func_B(%A, %B) : (memref<16xf64, #tile>, f64) -> (memref<8xf64, #tile>)
return %res : memref<8xf64, #tile>
}
// CHECK: return %{{.*}} : memref<2x4xf64>
// CHECK-LABEL: func @affine_parallel_norm
-func @affine_parallel_norm() -> memref<8xf32, #tile> {
+func.func @affine_parallel_norm() -> memref<8xf32, #tile> {
%c = arith.constant 23.0 : f32
%a = memref.alloc() : memref<8xf32, #tile>
// CHECK: affine.parallel (%{{.*}}) = (0) to (8) reduce ("assign") -> (memref<2x4xf32>)
// RUN: mlir-opt -allow-unregistered-dialect %s -pass-pipeline='func.func(scf-parallel-loop-collapsing{collapsed-indices-0=0,3 collapsed-indices-1=1,4 collapsed-indices-2=2}, canonicalize)' | FileCheck %s
// CHECK-LABEL: func @parallel_many_dims() {
-func @parallel_many_dims() {
+func.func @parallel_many_dims() {
%c0 = arith.constant 0 : index
%c1 = arith.constant 1 : index
%c2 = arith.constant 2 : index
// CHECK: func @map1d
// CHECK-SAME: (%[[lb:.*]]: index, %[[ub:.*]]: index, %[[step:.*]]: index)
-func @map1d(%lb: index, %ub: index, %step: index) {
+func.func @map1d(%lb: index, %ub: index, %step: index) {
// CHECK: %[[threads:.*]]:2 = "new_processor_id_and_range"() : () -> (index, index)
%0:2 = "new_processor_id_and_range"() : () -> (index, index)
// CHECK: func @map2d
// CHECK-SAME: (%[[lb:.*]]: index, %[[ub:.*]]: index, %[[step:.*]]: index)
-func @map2d(%lb : index, %ub : index, %step : index) {
+func.func @map2d(%lb : index, %ub : index, %step : index) {
// CHECK: %[[blocks:.*]]:2 = "new_processor_id_and_range"() : () -> (index, index)
%0:2 = "new_processor_id_and_range"() : () -> (index, index)
// RUN: mlir-opt -test-extract-fixed-outer-loops='test-outer-loop-sizes=7,4' %s | FileCheck %s --check-prefixes=COMMON,TILE_74
// COMMON-LABEL: @rectangular
-func @rectangular(%arg0: memref<?x?xf32>) {
+func.func @rectangular(%arg0: memref<?x?xf32>) {
%c2 = arith.constant 2 : index
%c44 = arith.constant 44 : index
%c1 = arith.constant 1 : index
}
// COMMON-LABEL: @triangular
-func @triangular(%arg0: memref<?x?xf32>) {
+func.func @triangular(%arg0: memref<?x?xf32>) {
%c2 = arith.constant 2 : index
%c44 = arith.constant 44 : index
%c1 = arith.constant 1 : index
// CHECK-DAG: [[$MAP_MINUS_1:#map[0-9]+]] = affine_map<(d0) -> (d0 - 1)>
// CHECK-LABEL: func @loop_nest_dma() {
-func @loop_nest_dma() {
+func.func @loop_nest_dma() {
%A = memref.alloc() : memref<256 x f32, affine_map<(d0) -> (d0)>, 0>
%Ah = memref.alloc() : memref<32 x f32, affine_map<(d0) -> (d0)>, 1>
// CHECK-DAG: [[$REMAP_SHIFT_MINUS_4:#map[0-9]+]] = affine_map<(d0) -> (d0 - 4)>
// CHECK-LABEL: @loop_step
-func @loop_step(%arg0: memref<512xf32>,
+func.func @loop_step(%arg0: memref<512xf32>,
%arg1: memref<512xf32>) {
%c0 = arith.constant 0 : index
%c4 = arith.constant 4 : index
#map1 = affine_map<(d0, d1) -> ((d0 * 2048 + d1 * 256) floordiv 32)>
#map2 = affine_map<(d0) -> ((d0 * 2048) floordiv 32)>
// CHECK-LABEL: func @loop_dma_nested(%{{.*}}: memref<512x32xvector<8xf32>
-func @loop_dma_nested(%arg0: memref<512x32xvector<8xf32>>, %arg1: memref<512x32xvector<8xf32>>, %arg2: memref<512x32xvector<8xf32>>) {
+func.func @loop_dma_nested(%arg0: memref<512x32xvector<8xf32>>, %arg1: memref<512x32xvector<8xf32>>, %arg2: memref<512x32xvector<8xf32>>) {
%num_elts = arith.constant 256 : index
%c0 = arith.constant 0 : index
%0 = memref.alloc() : memref<64x4xvector<8xf32>, 2>
#map2 = affine_map<(d0) -> ((d0 * 2048) floordiv 32)>
// CHECK: func @loop_dma_dependent
-func @loop_dma_dependent(%arg2: memref<512x32xvector<8xf32>>) {
+func.func @loop_dma_dependent(%arg2: memref<512x32xvector<8xf32>>) {
%num_elts = arith.constant 256 : index
%c0 = arith.constant 0 : index
%0 = memref.alloc() : memref<64x4xvector<8xf32>, 2>
// -----
// CHECK-LABEL: func @escaping_use
-func @escaping_use(%arg0: memref<512 x 32 x f32>) {
+func.func @escaping_use(%arg0: memref<512 x 32 x f32>) {
%c32 = arith.constant 32 : index
%num_elt = arith.constant 512 : index
%zero = arith.constant 0 : index
// -----
// CHECK-LABEL: func @escaping_tag
-func @escaping_tag(%arg0: memref<512 x 32 x f32>) {
+func.func @escaping_tag(%arg0: memref<512 x 32 x f32>) {
%c32 = arith.constant 32 : index
%num_elt = arith.constant 512 : index
%zero = arith.constant 0 : index
// -----
// CHECK-LABEL: func @live_out_use
-func @live_out_use(%arg0: memref<512 x 32 x f32>) -> f32 {
+func.func @live_out_use(%arg0: memref<512 x 32 x f32>) -> f32 {
%c32 = arith.constant 32 : index
%num_elt = arith.constant 512 : index
%zero = arith.constant 0 : index
// -----
// CHECK-LABEL: func @dynamic_shape_dma_buffer
-func @dynamic_shape_dma_buffer(%arg0: memref<512 x 32 x f32>, %Av: memref<? x ? x f32, 2>) {
+func.func @dynamic_shape_dma_buffer(%arg0: memref<512 x 32 x f32>, %Av: memref<? x ? x f32, 2>) {
%num_elt = arith.constant 512 : index
%zero = arith.constant 0 : index
%tag = memref.alloc() : memref<1 x i32>
// dereferencing one since replaceAllMemRefUsesWith checks for escaping uses
// before performing any replacement.
// CHECK-LABEL: func @escaping_and_indexed_use_mix
-func @escaping_and_indexed_use_mix() {
+func.func @escaping_and_indexed_use_mix() {
%A = memref.alloc() : memref<256 x f32, affine_map<(d0) -> (d0)>, 0>
%Ah = memref.alloc() : memref<32 x f32, affine_map<(d0) -> (d0)>, 1>
%tag = memref.alloc() : memref<1 x f32>
// CFG: v[[TEST_FUNC]] -> v[[ANCHOR]] [{{.*}}, lhead = [[CLUSTER_MERGE_BLOCKS]]]
// CFG: v[[ANCHOR]] -> v[[TEST_RET]] [{{.*}}, ltail = [[CLUSTER_MERGE_BLOCKS]]]
-func @merge_blocks(%arg0: i32, %arg1 : i32) -> () {
+func.func @merge_blocks(%arg0: i32, %arg1 : i32) -> () {
%0 = arith.constant dense<[[0, 1], [2, 3]]> : tensor<2x2xi32>
%1 = arith.constant dense<1> : tensor<5xi32>
%2 = arith.constant dense<[[0, 1]]> : tensor<1x2xi32>
// AllocaOp.
// CHECK-LABEL: func @condBranch
-func @condBranch(%arg0: i1, %arg1: memref<2xf32>, %arg2: memref<2xf32>) {
+func.func @condBranch(%arg0: i1, %arg1: memref<2xf32>, %arg2: memref<2xf32>) {
cf.cond_br %arg0, ^bb1, ^bb2
^bb1:
cf.br ^bb3(%arg1 : memref<2xf32>)
// Since the alloc has dynamic type, it is not converted into an alloca.
// CHECK-LABEL: func @condBranchDynamicType
-func @condBranchDynamicType(
+func.func @condBranchDynamicType(
%arg0: i1,
%arg1: memref<?xf32>,
%arg2: memref<?xf32>,
// -----
// CHECK-LABEL: func @dynamicRanked
-func @dynamicRanked(%memref: memref<*xf32>) {
+func.func @dynamicRanked(%memref: memref<*xf32>) {
%0 = memref.rank %memref : memref<*xf32>
%1 = memref.alloc(%0) : memref<?xindex>
return
// -----
// CHECK-LABEL: func @dynamicRanked2D
-func @dynamicRanked2D(%memref: memref<*xf32>) {
+func.func @dynamicRanked2D(%memref: memref<*xf32>) {
%0 = memref.rank %memref : memref<*xf32>
%1 = memref.alloc(%0, %0) : memref<?x?xindex>
return
// -----
// CHECK-LABEL: func @dynamicNoRank
-func @dynamicNoRank(%arg0: index) {
+func.func @dynamicNoRank(%arg0: index) {
%0 = memref.alloc(%arg0) : memref<?xindex>
return
}
// AllocaOp.
// CHECK-LABEL: func @emptyUsesValue
-func @emptyUsesValue(%arg0: memref<4xf32>) {
+func.func @emptyUsesValue(%arg0: memref<4xf32>) {
%0 = memref.alloc() : memref<4xf32>
return
}
// AllocaOp.
// CHECK-LABEL: func @criticalEdge
-func @criticalEdge(%arg0: i1, %arg1: memref<2xf32>, %arg2: memref<2xf32>) {
+func.func @criticalEdge(%arg0: i1, %arg1: memref<2xf32>, %arg2: memref<2xf32>) {
cf.cond_br %arg0, ^bb1, ^bb2(%arg1 : memref<2xf32>)
^bb1:
%0 = memref.alloc() : memref<2xf32>
// PromoteBuffersToStack expected behavior: It converts the alloc in an alloca.
// CHECK-LABEL: func @invCriticalEdge
-func @invCriticalEdge(%arg0: i1, %arg1: memref<2xf32>, %arg2: memref<2xf32>) {
+func.func @invCriticalEdge(%arg0: i1, %arg1: memref<2xf32>, %arg2: memref<2xf32>) {
%0 = memref.alloc() : memref<2xf32>
test.buffer_based in(%arg1: memref<2xf32>) out(%0: memref<2xf32>)
cf.cond_br %arg0, ^bb1, ^bb2(%arg1 : memref<2xf32>)
// PromoteBuffersToStack expected behavior: It converts the allocs into allocas.
// CHECK-LABEL: func @ifElse
-func @ifElse(%arg0: i1, %arg1: memref<2xf32>, %arg2: memref<2xf32>) {
+func.func @ifElse(%arg0: i1, %arg1: memref<2xf32>, %arg2: memref<2xf32>) {
%0 = memref.alloc() : memref<2xf32>
test.buffer_based in(%arg1: memref<2xf32>) out(%0: memref<2xf32>)
cf.cond_br %arg0,
// PromoteBuffersToStack expected behavior: It converts the alloc into alloca.
// CHECK-LABEL: func @ifElseNoUsers
-func @ifElseNoUsers(%arg0: i1, %arg1: memref<2xf32>, %arg2: memref<2xf32>) {
+func.func @ifElseNoUsers(%arg0: i1, %arg1: memref<2xf32>, %arg2: memref<2xf32>) {
%0 = memref.alloc() : memref<2xf32>
test.buffer_based in(%arg1: memref<2xf32>) out(%0: memref<2xf32>)
cf.cond_br %arg0,
// into allocas.
// CHECK-LABEL: func @ifElseNested
-func @ifElseNested(%arg0: i1, %arg1: memref<2xf32>, %arg2: memref<2xf32>) {
+func.func @ifElseNested(%arg0: i1, %arg1: memref<2xf32>, %arg2: memref<2xf32>) {
%0 = memref.alloc() : memref<2xf32>
test.buffer_based in(%arg1: memref<2xf32>) out(%0: memref<2xf32>)
cf.cond_br %arg0,
// allocas.
// CHECK-LABEL: func @redundantOperations
-func @redundantOperations(%arg0: memref<2xf32>) {
+func.func @redundantOperations(%arg0: memref<2xf32>) {
%0 = memref.alloc() : memref<2xf32>
test.buffer_based in(%arg0: memref<2xf32>) out(%0: memref<2xf32>)
%1 = memref.alloc() : memref<2xf32>
// allocas.
// CHECK-LABEL: func @moving_alloc_and_inserting_missing_dealloc
-func @moving_alloc_and_inserting_missing_dealloc(
+func.func @moving_alloc_and_inserting_missing_dealloc(
%cond: i1,
%arg0: memref<2xf32>,
%arg1: memref<2xf32>) {
// allocas.
// CHECK-LABEL: func @nested_regions_and_cond_branch
-func @nested_regions_and_cond_branch(
+func.func @nested_regions_and_cond_branch(
%arg0: i1,
%arg1: memref<2xf32>,
%arg2: memref<2xf32>) {
// only remains in the scope of the function.
// CHECK-LABEL: func @memref_in_function_results
-func @memref_in_function_results(
+func.func @memref_in_function_results(
%arg0: memref<5xf32>,
%arg1: memref<10xf32>,
%arg2: memref<5xf32>) -> (memref<10xf32>, memref<15xf32>) {
// due to its dynamic memory allocation behavior.
// CHECK-LABEL: func @nested_region_control_flow
-func @nested_region_control_flow(
+func.func @nested_region_control_flow(
%arg0 : index,
%arg1 : index) -> memref<?x?xf32> {
%0 = arith.cmpi eq, %arg0, %arg1 : index
// allocation finally escapes the method.
// CHECK-LABEL: func @inner_region_control_flow
-func @inner_region_control_flow(%arg0 : index) -> memref<2x2xf32> {
+func.func @inner_region_control_flow(%arg0 : index) -> memref<2x2xf32> {
%0 = memref.alloc() : memref<2x2xf32>
%1 = test.region_if %0 : memref<2x2xf32> -> (memref<2x2xf32>) then {
^bb0(%arg1 : memref<2x2xf32>):
// Alloc %0 will be converted to an alloca. %3 is not transformed.
// CHECK-LABEL: func @loop_alloc
-func @loop_alloc(
+func.func @loop_alloc(
%lb: index,
%ub: index,
%step: index,
// that are passed via the backedges. The alloc is converted to an AllocaOp.
// CHECK-LABEL: func @loop_nested_if_no_alloc
-func @loop_nested_if_no_alloc(
+func.func @loop_nested_if_no_alloc(
%lb: index,
%ub: index,
%step: index,
// The allocs are not converted in this case.
// CHECK-LABEL: func @loop_nested_if_alloc
-func @loop_nested_if_alloc(
+func.func @loop_nested_if_alloc(
%lb: index,
%ub: index,
%step: index,
// converted. In the actual implementation the largest size is 1KB.
// CHECK-LABEL: func @large_buffer_allocation
-func @large_buffer_allocation(%arg0: memref<2048xf32>) {
+func.func @large_buffer_allocation(%arg0: memref<2048xf32>) {
%0 = memref.alloc() : memref<2048xf32>
test.copy(%0, %arg0) : (memref<2048xf32>, memref<2048xf32>)
return
// AllocaOp.
// CHECK-LABEL: func @indexElementType
-func @indexElementType() {
+func.func @indexElementType() {
%0 = memref.alloc() : memref<4xindex>
return
}
// CHECK-LABEL: func @bigIndexElementType
module attributes { dlti.dl_spec = #dlti.dl_spec<#dlti.dl_entry<index, 256>>} {
- func @bigIndexElementType() {
+ func.func @bigIndexElementType() {
%0 = memref.alloc() : memref<4xindex>
return
}
/// results of a private function.
// CHECK-LABEL: func private @private(
-func private @private(%arg0 : i32) -> i32 {
+func.func private @private(%arg0 : i32) -> i32 {
// CHECK: %[[CST:.*]] = arith.constant 1 : i32
// CHECK: return %[[CST]] : i32
}
// CHECK-LABEL: func @simple_private(
-func @simple_private() -> i32 {
+func.func @simple_private() -> i32 {
// CHECK: %[[CST:.*]] = arith.constant 1 : i32
// CHECK: return %[[CST]] : i32
/// results of a visible nested function.
// CHECK: func nested @nested(
-func nested @nested(%arg0 : i32) -> i32 {
+func.func nested @nested(%arg0 : i32) -> i32 {
// CHECK: %[[CST:.*]] = arith.constant 1 : i32
// CHECK: return %[[CST]] : i32
}
// CHECK-LABEL: func @simple_nested(
-func @simple_nested() -> i32 {
+func.func @simple_nested() -> i32 {
// CHECK: %[[CST:.*]] = arith.constant 1 : i32
// CHECK: return %[[CST]] : i32
module @nested_module attributes { sym_visibility = "public" } {
// NESTED: func nested @nested(
- func nested @nested(%arg0 : i32) -> (i32, i32) {
+ func.func nested @nested(%arg0 : i32) -> (i32, i32) {
// NESTED: %[[CST:.*]] = arith.constant 1 : i32
// NESTED: return %[[CST]], %arg0 : i32, i32
}
// NESTED: func @nested_not_all_uses_visible(
- func @nested_not_all_uses_visible() -> (i32, i32) {
+ func.func @nested_not_all_uses_visible() -> (i32, i32) {
// NESTED: %[[CST:.*]] = arith.constant 1 : i32
// NESTED: %[[CALL:.*]]:2 = call @nested
// NESTED: return %[[CST]], %[[CALL]]#1 : i32, i32
/// Check that public functions do not track arguments.
// CHECK-LABEL: func @public(
-func @public(%arg0 : i32) -> (i32, i32) {
+func.func @public(%arg0 : i32) -> (i32, i32) {
%1 = arith.constant 1 : i32
return %1, %arg0 : i32, i32
}
// CHECK-LABEL: func @simple_public(
-func @simple_public() -> (i32, i32) {
+func.func @simple_public() -> (i32, i32) {
// CHECK: %[[CST:.*]] = arith.constant 1 : i32
// CHECK: %[[CALL:.*]]:2 = call @public
// CHECK: return %[[CST]], %[[CALL]]#1 : i32, i32
/// Check that functions with non-call users don't have arguments tracked.
-func private @callable(%arg0 : i32) -> (i32, i32) {
+func.func private @callable(%arg0 : i32) -> (i32, i32) {
%1 = arith.constant 1 : i32
return %1, %arg0 : i32, i32
}
// CHECK-LABEL: func @non_call_users(
-func @non_call_users() -> (i32, i32) {
+func.func @non_call_users() -> (i32, i32) {
// CHECK: %[[CST:.*]] = arith.constant 1 : i32
// CHECK: %[[CALL:.*]]:2 = call @callable
// CHECK: return %[[CST]], %[[CALL]]#1 : i32, i32
/// Check that return values are overdefined in the presence of an unknown terminator.
-func private @callable(%arg0 : i32) -> i32 {
+func.func private @callable(%arg0 : i32) -> i32 {
"unknown.return"(%arg0) : (i32) -> ()
}
// CHECK-LABEL: func @unknown_terminator(
-func @unknown_terminator() -> i32 {
+func.func @unknown_terminator() -> i32 {
// CHECK: %[[CALL:.*]] = call @callable
// CHECK: return %[[CALL]] : i32
/// Check that return values are overdefined when the constant conflicts.
-func private @callable(%arg0 : i32) -> i32 {
+func.func private @callable(%arg0 : i32) -> i32 {
return %arg0 : i32
}
// CHECK-LABEL: func @conflicting_constant(
-func @conflicting_constant() -> (i32, i32) {
+func.func @conflicting_constant() -> (i32, i32) {
// CHECK: %[[CALL1:.*]] = call @callable
// CHECK: %[[CALL2:.*]] = call @callable
// CHECK: return %[[CALL1]], %[[CALL2]] : i32, i32
/// Check that return values are overdefined when the constant conflicts with a
/// non-constant.
-func private @callable(%arg0 : i32) -> i32 {
+func.func private @callable(%arg0 : i32) -> i32 {
"unknown.return"(%arg0) : (i32) -> ()
}
// CHECK-LABEL: func @conflicting_constant(
-func @conflicting_constant(%arg0 : i32) -> (i32, i32) {
+func.func @conflicting_constant(%arg0 : i32) -> (i32, i32) {
// CHECK: %[[CALL1:.*]] = call @callable
// CHECK: %[[CALL2:.*]] = call @callable
// CHECK: return %[[CALL1]], %[[CALL2]] : i32, i32
/// Check a more complex interaction with calls and control flow.
// CHECK-LABEL: func private @complex_inner_if(
-func private @complex_inner_if(%arg0 : i32) -> i32 {
+func.func private @complex_inner_if(%arg0 : i32) -> i32 {
// CHECK-DAG: %[[TRUE:.*]] = arith.constant true
// CHECK-DAG: %[[CST:.*]] = arith.constant 1 : i32
// CHECK: cf.cond_br %[[TRUE]], ^bb1
return %arg_inc : i32
}
-func private @complex_cond() -> i1
+func.func private @complex_cond() -> i1
// CHECK-LABEL: func private @complex_callee(
-func private @complex_callee(%arg0 : i32) -> i32 {
+func.func private @complex_callee(%arg0 : i32) -> i32 {
// CHECK: %[[CST:.*]] = arith.constant 1 : i32
%loop_cond = call @complex_cond() : () -> i1
}
// CHECK-LABEL: func @complex_caller(
-func @complex_caller(%arg0 : i32) -> i32 {
+func.func @complex_caller(%arg0 : i32) -> i32 {
// CHECK: %[[CST:.*]] = arith.constant 1 : i32
// CHECK: return %[[CST]] : i32
/// Check that non-symbol defining callables currently go to overdefined.
// CHECK-LABEL: func @non_symbol_defining_callable
-func @non_symbol_defining_callable() -> i32 {
+func.func @non_symbol_defining_callable() -> i32 {
// CHECK: %[[RES:.*]] = call_indirect
// CHECK: return %[[RES]] : i32
/// Check that private callables don't get processed if they have no uses.
// CHECK-LABEL: func private @unreferenced_private_function
-func private @unreferenced_private_function() -> i32 {
+func.func private @unreferenced_private_function() -> i32 {
// CHECK: %[[RES:.*]] = arith.select
// CHECK: return %[[RES]] : i32
%true = arith.constant true
/// Check that a constant is properly propagated when only one edge is taken.
// CHECK-LABEL: func @simple(
-func @simple(%arg0 : i32) -> i32 {
+func.func @simple(%arg0 : i32) -> i32 {
// CHECK: %[[CST:.*]] = arith.constant 1 : i32
// CHECK-NOT: scf.if
// CHECK: return %[[CST]] : i32
/// same value.
// CHECK-LABEL: func @simple_both_same(
-func @simple_both_same(%cond : i1) -> i32 {
+func.func @simple_both_same(%cond : i1) -> i32 {
// CHECK: %[[CST:.*]] = arith.constant 1 : i32
// CHECK-NOT: scf.if
// CHECK: return %[[CST]] : i32
/// a specific successor is taken.
// CHECK-LABEL: func @overdefined_unknown_condition(
-func @overdefined_unknown_condition(%cond : i1, %arg0 : i32) -> i32 {
+func.func @overdefined_unknown_condition(%cond : i1, %arg0 : i32) -> i32 {
// CHECK: %[[RES:.*]] = scf.if
// CHECK: return %[[RES]] : i32
/// constants.
// CHECK-LABEL: func @overdefined_different_constants(
-func @overdefined_different_constants(%cond : i1) -> i32 {
+func.func @overdefined_different_constants(%cond : i1) -> i32 {
// CHECK: %[[RES:.*]] = scf.if
// CHECK: return %[[RES]] : i32
/// Check that arguments are properly merged across loop-like control flow.
// CHECK-LABEL: func @simple_loop(
-func @simple_loop(%arg0 : index, %arg1 : index, %arg2 : index) -> i32 {
+func.func @simple_loop(%arg0 : index, %arg1 : index, %arg2 : index) -> i32 {
// CHECK: %[[CST:.*]] = arith.constant 0 : i32
// CHECK-NOT: scf.for
// CHECK: return %[[CST]] : i32
/// conflicting value.
// CHECK-LABEL: func @loop_overdefined(
-func @loop_overdefined(%arg0 : index, %arg1 : index, %arg2 : index) -> i32 {
+func.func @loop_overdefined(%arg0 : index, %arg1 : index, %arg2 : index) -> i32 {
// CHECK: %[[RES:.*]] = scf.for
// CHECK: return %[[RES]] : i32
/// of the analysis.
// CHECK-LABEL: func @loop_inner_control_flow(
-func @loop_inner_control_flow(%arg0 : index, %arg1 : index, %arg2 : index) -> i32 {
+func.func @loop_inner_control_flow(%arg0 : index, %arg1 : index, %arg2 : index) -> i32 {
// CHECK: %[[CST:.*]] = arith.constant 1 : i32
// CHECK-NOT: scf.for
// CHECK-NOT: scf.if
/// implements the RegionBranchTerminatorOpInterface.
// CHECK-LABEL: func @loop_region_branch_terminator_op(
-func @loop_region_branch_terminator_op(%arg1 : i32) {
+func.func @loop_region_branch_terminator_op(%arg1 : i32) {
// CHECK: %c2_i32 = arith.constant 2 : i32
// CHECK-NEXT: return
/// interface as well.
// CHECK-LABEL: func @affine_loop_one_iter(
-func @affine_loop_one_iter(%arg0 : index, %arg1 : index, %arg2 : index) -> i32 {
+func.func @affine_loop_one_iter(%arg0 : index, %arg1 : index, %arg2 : index) -> i32 {
// CHECK: %[[C1:.*]] = arith.constant 1 : i32
%s0 = arith.constant 0 : i32
%s1 = arith.constant 1 : i32
}
// CHECK-LABEL: func @affine_loop_zero_iter(
-func @affine_loop_zero_iter(%arg0 : index, %arg1 : index, %arg2 : index) -> i32 {
+func.func @affine_loop_zero_iter(%arg0 : index, %arg1 : index, %arg2 : index) -> i32 {
// This exposes a crash in sccp/forward data flow analysis: https://github.com/llvm/llvm-project/issues/54928
// CHECK: %[[C0:.*]] = arith.constant 0 : i32
%s0 = arith.constant 0 : i32
/// Check simple forward constant propagation without any control flow.
// CHECK-LABEL: func @no_control_flow
-func @no_control_flow(%arg0: i32) -> i32 {
+func.func @no_control_flow(%arg0: i32) -> i32 {
// CHECK: %[[CST:.*]] = arith.constant 1 : i32
// CHECK: return %[[CST]] : i32
/// is taken.
// CHECK-LABEL: func @simple_control_flow
-func @simple_control_flow(%arg0 : i32) -> i32 {
+func.func @simple_control_flow(%arg0 : i32) -> i32 {
// CHECK: %[[CST:.*]] = arith.constant 1 : i32
%cond = arith.constant true
/// a specific successor is taken.
// CHECK-LABEL: func @simple_control_flow_overdefined
-func @simple_control_flow_overdefined(%arg0 : i32, %arg1 : i1) -> i32 {
+func.func @simple_control_flow_overdefined(%arg0 : i32, %arg1 : i1) -> i32 {
%1 = arith.constant 1 : i32
cf.cond_br %arg1, ^bb1, ^bb2(%arg0 : i32)
/// constants.
// CHECK-LABEL: func @simple_control_flow_constant_overdefined
-func @simple_control_flow_constant_overdefined(%arg0 : i32, %arg1 : i1) -> i32 {
+func.func @simple_control_flow_constant_overdefined(%arg0 : i32, %arg1 : i1) -> i32 {
%1 = arith.constant 1 : i32
%2 = arith.constant 2 : i32
cf.cond_br %arg1, ^bb1, ^bb2(%arg0 : i32)
/// Check that the arguments go to overdefined if the branch is unknown.
// CHECK-LABEL: func @unknown_terminator
-func @unknown_terminator(%arg0 : i32, %arg1 : i1) -> i32 {
+func.func @unknown_terminator(%arg0 : i32, %arg1 : i1) -> i32 {
%1 = arith.constant 1 : i32
"foo.cond_br"() [^bb1, ^bb2] : () -> ()
/// Check that arguments are properly merged across loop-like control flow.
-func private @ext_cond_fn() -> i1
+func.func private @ext_cond_fn() -> i1
// CHECK-LABEL: func @simple_loop
-func @simple_loop(%arg0 : i32, %cond1 : i1) -> i32 {
+func.func @simple_loop(%arg0 : i32, %cond1 : i1) -> i32 {
// CHECK: %[[CST:.*]] = arith.constant 1 : i32
%cst_1 = arith.constant 1 : i32
/// of the analysis.
// CHECK-LABEL: func @simple_loop_inner_control_flow
-func @simple_loop_inner_control_flow(%arg0 : i32) -> i32 {
+func.func @simple_loop_inner_control_flow(%arg0 : i32) -> i32 {
// CHECK-DAG: %[[CST:.*]] = arith.constant 1 : i32
// CHECK-DAG: %[[TRUE:.*]] = arith.constant true
/// Check that arguments go to overdefined when loop backedges produce a
/// conflicting value.
-func private @ext_cond_and_value_fn() -> (i1, i32)
+func.func private @ext_cond_and_value_fn() -> (i1, i32)
// CHECK-LABEL: func @simple_loop_overdefined
-func @simple_loop_overdefined(%arg0 : i32, %cond1 : i1) -> i32 {
+func.func @simple_loop_overdefined(%arg0 : i32, %cond1 : i1) -> i32 {
%cst_1 = arith.constant 1 : i32
cf.cond_br %cond1, ^bb1(%cst_1 : i32), ^bb2(%cst_1 : i32)
// Check that we reprocess executable edges when information changes.
// CHECK-LABEL: func @recheck_executable_edge
-func @recheck_executable_edge(%cond0: i1) -> (i1, i1) {
+func.func @recheck_executable_edge(%cond0: i1) -> (i1, i1) {
%true = arith.constant true
%false = arith.constant false
cf.cond_br %cond0, ^bb_1a, ^bb2(%false : i1)
}
// CHECK-LABEL: func @simple_produced_operand
-func @simple_produced_operand() -> (i32, i32) {
+func.func @simple_produced_operand() -> (i32, i32) {
// CHECK: %[[ONE:.*]] = arith.constant 1
%1 = arith.constant 1 : i32
"test.internal_br"(%1) [^bb1, ^bb2] {
// CHECK-NEXT: }
// CHECK-NEXT: return
// CHECK-NEXT: }
-func @outline_if_else(%cond: i1, %a: index, %b: memref<?xf32>, %c: i8) {
+func.func @outline_if_else(%cond: i1, %a: index, %b: memref<?xf32>, %c: i8) {
%r = scf.if %cond -> (i8) {
%r = "some_op"(%cond, %b) : (i1, memref<?xf32>) -> (i8)
scf.yield %r : i8
// CHECK-NEXT: }
// CHECK-NEXT: return
// CHECK-NEXT: }
-func @outline_if(%cond: i1, %a: index, %b: memref<?xf32>, %c: i8) {
+func.func @outline_if(%cond: i1, %a: index, %b: memref<?xf32>, %c: i8) {
scf.if %cond {
"some_op"(%cond, %b) : (i1, memref<?xf32>) -> ()
scf.yield
// CHECK-NEXT: }
// CHECK-NEXT: return
// CHECK-NEXT: }
-func @outline_empty_if_else(%cond: i1, %a: index, %b: memref<?xf32>, %c: i8) {
+func.func @outline_empty_if_else(%cond: i1, %a: index, %b: memref<?xf32>, %c: i8) {
scf.if %cond {
} else {
"some_op"(%cond, %b) : (i1, memref<?xf32>) -> ()
// RUN: mlir-opt %s --test-loop-unrolling="unroll-factor=1" -split-input-file -canonicalize | FileCheck %s --check-prefix UNROLL-BY-1
// CHECK-LABEL: scf_loop_unroll_single
-func @scf_loop_unroll_single(%arg0 : f32, %arg1 : f32) -> f32 {
+func.func @scf_loop_unroll_single(%arg0 : f32, %arg1 : f32) -> f32 {
%from = arith.constant 0 : index
%to = arith.constant 10 : index
%step = arith.constant 1 : index
// CHECK-LABEL: scf_loop_unroll_double_symbolic_ub
// CHECK-SAME: (%{{.*}}: f32, %{{.*}}: f32, %[[N:.*]]: index)
-func @scf_loop_unroll_double_symbolic_ub(%arg0 : f32, %arg1 : f32, %n : index) -> (f32,f32) {
+func.func @scf_loop_unroll_double_symbolic_ub(%arg0 : f32, %arg1 : f32, %n : index) -> (f32,f32) {
%from = arith.constant 0 : index
%step = arith.constant 1 : index
%sum:2 = scf.for %iv = %from to %n step %step iter_args(%i0 = %arg0, %i1 = %arg1) -> (f32, f32) {
}
// UNROLL-BY-1-LABEL: scf_loop_unroll_factor_1_promote
-func @scf_loop_unroll_factor_1_promote() -> () {
+func.func @scf_loop_unroll_factor_1_promote() -> () {
%step = arith.constant 1 : index
%lo = arith.constant 0 : index
%hi = arith.constant 1 : index
// CHECK-SAME: %[[lb:[a-zA-Z0-9]*]]: index,
// CHECK-SAME: %[[ub:[a-zA-Z0-9]*]]: index,
// CHECK-SAME: %[[step:[a-zA-Z0-9]*]]: index
-func @hoist(%lb: index, %ub: index, %step: index) {
+func.func @hoist(%lb: index, %ub: index, %step: index) {
// CHECK: %[[A:.*]] = "fake_read"() : () -> index
// CHECK: %[[RES:.*]] = scf.for %[[I:.*]] = %[[lb]] to %[[ub]] step %[[step]] iter_args(%[[VAL:.*]] = %[[A]]) -> (index)
// CHECK: %[[YIELD:.*]] = "fake_compute"(%[[VAL]]) : (index) -> index
// CHECK-SAME: %[[ub:[a-zA-Z0-9]*]]: index,
// CHECK-SAME: %[[step:[a-zA-Z0-9]*]]: index
// CHECK-SAME: %[[extra_arg:[a-zA-Z0-9]*]]: f32
-func @hoist2(%lb: index, %ub: index, %step: index, %extra_arg: f32) -> f32 {
+func.func @hoist2(%lb: index, %ub: index, %step: index, %extra_arg: f32) -> f32 {
// CHECK: %[[A:.*]] = "fake_read"() : () -> index
// CHECK: %[[RES:.*]]:2 = scf.for %[[I:.*]] = %[[lb]] to %[[ub]] step %[[step]] iter_args(%[[VAL0:.*]] = %[[extra_arg]], %[[VAL1:.*]] = %[[A]]) -> (f32, index)
// CHECK: %[[YIELD:.*]] = "fake_compute"(%[[VAL1]]) : (index) -> index
// RUN: mlir-opt -allow-unregistered-dialect %s -pass-pipeline='func.func(scf-parallel-loop-collapsing{collapsed-indices-0=0,1}, canonicalize)' | FileCheck %s
-func @collapse_to_single() {
+func.func @collapse_to_single() {
%c0 = arith.constant 3 : index
%c1 = arith.constant 7 : index
%c2 = arith.constant 11 : index
#set0 = affine_set<(d0) : (1 == 0)>
// CHECK-LABEL: func @inline_notation
-func @inline_notation() -> i32 {
+func.func @inline_notation() -> i32 {
// CHECK: "foo"() : () -> i32 loc(unknown)
%1 = "foo"() : () -> i32 loc("foo")
// FILTER_ENABLE-NEXT: return
// FILTER_DISABLE-LABEL: func @remove_op_with_inner_ops_pattern
// FILTER_DISABLE-NEXT: "test.op_with_region_pattern"()
-func @remove_op_with_inner_ops_pattern() {
+func.func @remove_op_with_inner_ops_pattern() {
"test.op_with_region_pattern"() ({
"test.op_with_region_terminator"() : () -> ()
}) : () -> ()
// RUN: mlir-opt %s -pass-pipeline='func.func(canonicalize)' | FileCheck %s
// CHECK-LABEL: func @remove_op_with_inner_ops_pattern
-func @remove_op_with_inner_ops_pattern() {
+func.func @remove_op_with_inner_ops_pattern() {
// CHECK-NEXT: return
"test.op_with_region_pattern"() ({
"test.op_with_region_terminator"() : () -> ()
}
// CHECK-LABEL: func @remove_op_with_inner_ops_fold_no_side_effect
-func @remove_op_with_inner_ops_fold_no_side_effect() {
+func.func @remove_op_with_inner_ops_fold_no_side_effect() {
// CHECK-NEXT: return
"test.op_with_region_fold_no_side_effect"() ({
"test.op_with_region_terminator"() : () -> ()
// CHECK-LABEL: func @remove_op_with_inner_ops_fold
// CHECK-SAME: (%[[ARG_0:[a-z0-9]*]]: i32)
-func @remove_op_with_inner_ops_fold(%arg0 : i32) -> (i32) {
+func.func @remove_op_with_inner_ops_fold(%arg0 : i32) -> (i32) {
// CHECK-NEXT: return %[[ARG_0]]
%0 = "test.op_with_region_fold"(%arg0) ({
"test.op_with_region_terminator"() : () -> ()
// CHECK-LABEL: func @remove_op_with_variadic_results_and_folder
// CHECK-SAME: (%[[ARG_0:[a-z0-9]*]]: i32, %[[ARG_1:[a-z0-9]*]]: i32)
-func @remove_op_with_variadic_results_and_folder(%arg0 : i32, %arg1 : i32) -> (i32, i32) {
+func.func @remove_op_with_variadic_results_and_folder(%arg0 : i32, %arg1 : i32) -> (i32, i32) {
// CHECK-NEXT: return %[[ARG_0]], %[[ARG_1]]
%0, %1 = "test.op_with_variadic_results_and_folder"(%arg0, %arg1) : (i32, i32) -> (i32, i32)
return %0, %1 : i32, i32
// CHECK-LABEL: func @test_commutative_multi
// CHECK-SAME: (%[[ARG_0:[a-z0-9]*]]: i32, %[[ARG_1:[a-z0-9]*]]: i32)
-func @test_commutative_multi(%arg0: i32, %arg1: i32) -> (i32, i32) {
+func.func @test_commutative_multi(%arg0: i32, %arg1: i32) -> (i32, i32) {
// CHECK-DAG: %[[C42:.*]] = arith.constant 42 : i32
%c42_i32 = arith.constant 42 : i32
// CHECK-DAG: %[[C43:.*]] = arith.constant 43 : i32
// CHECK-LABEL: func @test_commutative_multi_cst
-func @test_commutative_multi_cst(%arg0: i32, %arg1: i32) -> (i32, i32) {
+func.func @test_commutative_multi_cst(%arg0: i32, %arg1: i32) -> (i32, i32) {
// CHECK-NEXT: %c42_i32 = arith.constant 42 : i32
%c42_i32 = arith.constant 42 : i32
%c42_i32_2 = arith.constant 42 : i32
// CHECK-LABEL: func @typemismatch
-func @typemismatch() -> i32 {
+func.func @typemismatch() -> i32 {
%c42 = arith.constant 42.0 : f32
// The "passthrough_fold" folder will naively return its operand, but we don't
}
// CHECK-LABEL: test_dialect_canonicalizer
-func @test_dialect_canonicalizer() -> (i32) {
+func.func @test_dialect_canonicalizer() -> (i32) {
%0 = "test.dialect_canonicalizable"() : () -> (i32)
// CHECK: %[[CST:.*]] = arith.constant 42 : i32
// CHECK: return %[[CST]]
// RUN: mlir-opt %s -test-convert-call-op | FileCheck %s
// CHECK-LABEL: llvm.func @callee(!llvm.ptr<i8>) -> i32
-func private @callee(!test.test_type) -> i32
+func.func private @callee(!test.test_type) -> i32
// CHECK-NEXT: llvm.func @caller() -> i32
-func @caller() -> i32 {
+func.func @caller() -> i32 {
%arg = "test.type_producer"() : () -> !test.test_type
%out = call @callee(%arg) : (!test.test_type) -> i32
return %out : i32
// RUN: mlir-opt -allow-unregistered-dialect %s -test-inline | FileCheck %s
// CHECK-LABEL: func @inline_with_arg
-func @inline_with_arg(%arg0 : i32) -> i32 {
+func.func @inline_with_arg(%arg0 : i32) -> i32 {
// CHECK-NEXT: %[[ADD:.*]] = arith.addi %{{.*}}, %{{.*}} : i32
// CHECK-NEXT: return %[[ADD]] : i32
%fn = "test.functional_region_op"() ({
}
// CHECK-LABEL: func @no_inline_invalid_nested_operation
-func @no_inline_invalid_nested_operation() {
+func.func @no_inline_invalid_nested_operation() {
// CHECK: call_indirect
// test.region is analyzed recursively, so it must not have an invalid op.
}
// CHECK-LABEL: func @inline_ignore_invalid_nested_operation
-func @inline_ignore_invalid_nested_operation() {
+func.func @inline_ignore_invalid_nested_operation() {
// CHECK-NOT: call_indirect
// test.functional_region_op is not analyzed recursively, so it may have an
}
// CHECK-LABEL: func @no_inline_invalid_dest_region
-func @no_inline_invalid_dest_region() {
+func.func @no_inline_invalid_dest_region() {
// CHECK: call_indirect
// foo.unknown_region is unknown, so we can't inline into it.
// Test that an error is emitted when an operation is marked as "erased", but
// has users that live across the conversion.
-func @remove_all_ops(%arg0: i32) -> i32 {
+func.func @remove_all_ops(%arg0: i32) -> i32 {
// expected-error@below {{failed to legalize operation 'test.illegal_op_a' marked as erased}}
%0 = "test.illegal_op_a"() : () -> i32
// expected-note@below {{found live user of result #0: return %0 : i32}}
// CHECK-NEXT: %[[VAL:.*]] = "test.one_variadic_out_one_variadic_in1"(%[[ARG]], %[[ARG]])
// CHECK-NEXT: "test.one_variadic_out_one_variadic_in1"(%[[VAL]], %[[VAL]])
-func @remap_input_1_to_1(%arg0: i32) {
+func.func @remap_input_1_to_1(%arg0: i32) {
%0 = "test.one_variadic_out_one_variadic_in1"(%arg0) : (i32) -> i32
%1 = "test.one_variadic_out_one_variadic_in1"(%0) : (i32) -> i32
"test.return"() : () -> ()
// CHECK-LABEL: func @remap_unconverted
// CHECK-NEXT: %[[VAL:.*]] = "test.type_producer"() : () -> f64
// CHECK-NEXT: "test.type_consumer"(%[[VAL]]) : (f64)
-func @remap_unconverted() {
+func.func @remap_unconverted() {
%region_result = "test.remapped_value_region"() ({
%result = "test.type_producer"() : () -> f32
"test.return"(%result) : (f32) -> ()
// dummy cast to be dead.
// CHECK-LABEL: @foo
-func @foo() {
+func.func @foo() {
%0 = "test.type_producer"() : () -> i32
// CHECK: test.cast
// CHECK-NOT: test.type_changer
// RUN: mlir-opt %s -test-legalize-type-conversion -allow-unregistered-dialect -split-input-file -verify-diagnostics | FileCheck %s
-func @test_invalid_arg_materialization(
+func.func @test_invalid_arg_materialization(
// expected-error@below {{failed to materialize conversion for block argument #0 that remained live after conversion, type was 'i16'}}
%arg0: i16) {
// expected-note@below {{see existing live user here}}
// -----
// CHECK-LABEL: func @test_valid_arg_materialization
-func @test_valid_arg_materialization(%arg0: i64) {
+func.func @test_valid_arg_materialization(%arg0: i64) {
// CHECK: %[[ARG:.*]] = "test.type_producer"
// CHECK: "foo.return"(%[[ARG]]) : (i64)
// -----
-func @test_invalid_result_materialization() {
+func.func @test_invalid_result_materialization() {
// expected-error@below {{failed to materialize conversion for result #0 of operation 'test.type_producer' that remained live after conversion}}
%result = "test.type_producer"() : () -> f16
// -----
-func @test_invalid_result_materialization() {
+func.func @test_invalid_result_materialization() {
// expected-error@below {{failed to materialize conversion for result #0 of operation 'test.type_producer' that remained live after conversion}}
%result = "test.type_producer"() : () -> f16
// -----
// CHECK-LABEL: @test_transitive_use_materialization
-func @test_transitive_use_materialization() {
+func.func @test_transitive_use_materialization() {
// CHECK: %[[V:.*]] = "test.type_producer"() : () -> f64
// CHECK: %[[C:.*]] = "test.cast"(%[[V]]) : (f64) -> f32
%result = "test.another_type_producer"() : () -> f32
// -----
-func @test_transitive_use_invalid_materialization() {
+func.func @test_transitive_use_invalid_materialization() {
// expected-error@below {{failed to materialize conversion for result #0 of operation 'test.type_producer' that remained live after conversion}}
%result = "test.another_type_producer"() : () -> f16
// expected-note@below {{see existing live user here}}
// -----
// CHECK-LABEL: func @test_valid_result_legalization
-func @test_valid_result_legalization() {
+func.func @test_valid_result_legalization() {
// CHECK: %[[RESULT:.*]] = "test.type_producer"() : () -> f64
// CHECK: %[[CAST:.*]] = "test.cast"(%[[RESULT]]) : (f64) -> f32
// CHECK: "foo.return"(%[[CAST]]) : (f32)
// Should not segfault here but gracefully fail.
// CHECK-LABEL: func @test_signature_conversion_undo
-func @test_signature_conversion_undo() {
+func.func @test_signature_conversion_undo() {
// CHECK: test.signature_conversion_undo
"test.signature_conversion_undo"() ({
// CHECK: ^{{.*}}(%{{.*}}: f32):
// Should not segfault here but gracefully fail.
// CHECK-LABEL: func @test_block_argument_not_converted
-func @test_block_argument_not_converted() {
+func.func @test_block_argument_not_converted() {
"test.unsupported_block_arg_type"() ({
// NOTE: The test pass does not convert `index` types.
// CHECK: ^bb0({{.*}}: index):
// -----
// Make sure argument type changes aren't implicitly forwarded.
-func @test_signature_conversion_no_converter() {
+func.func @test_signature_conversion_no_converter() {
"test.signature_conversion_no_converter"() ({
// expected-error@below {{failed to materialize conversion for block argument #0 that remained live after conversion}}
^bb0(%arg0: f32):
// -----
// CHECK-LABEL: @recursive_type_conversion
-func @recursive_type_conversion() {
+func.func @recursive_type_conversion() {
// CHECK: !test.test_rec<outer_converted_type, smpla>
"test.type_producer"() : () -> !test.test_rec<something, test_rec<something>>
return
// Test that all `test` dialect operations are removed.
// CHECK-LABEL: func @remove_all_ops
-func @remove_all_ops(%arg0: i32) {
+func.func @remove_all_ops(%arg0: i32) {
// CHECK-NEXT: return
%0 = "test.illegal_op_a"() : () -> i32
%1 = "test.illegal_op_b"() : () -> i32
// expected-remark@-2 {{op 'builtin.module' is legalizable}}
// expected-remark@+1 {{op 'func.func' is legalizable}}
-func @test(%arg0: f32) {
+func.func @test(%arg0: f32) {
// expected-remark@+1 {{op 'test.illegal_op_a' is legalizable}}
%result = "test.illegal_op_a"() : () -> (i32)
"foo.region"() ({
// RUN: mlir-opt -allow-unregistered-dialect -test-legalize-patterns -test-legalize-mode=full -split-input-file -verify-diagnostics %s | FileCheck %s
// CHECK-LABEL: func @multi_level_mapping
-func @multi_level_mapping() {
+func.func @multi_level_mapping() {
// CHECK: "test.type_producer"() : () -> f64
// CHECK: "test.type_consumer"(%{{.*}}) : (f64) -> ()
%result = "test.type_producer"() : () -> i32
// Test that operations that are erased don't need to be legalized.
// CHECK-LABEL: func @dropped_region_with_illegal_ops
-func @dropped_region_with_illegal_ops() {
+func.func @dropped_region_with_illegal_ops() {
// CHECK-NEXT: test.return
"test.drop_region_op"() ({
%ignored = "test.illegal_op_f"() : () -> (i32)
"test.return"() : () -> ()
}
// CHECK-LABEL: func @replace_non_root_illegal_op
-func @replace_non_root_illegal_op() {
+func.func @replace_non_root_illegal_op() {
// CHECK-NEXT: "test.legal_op_b"
// CHECK-NEXT: test.return
%result = "test.replace_non_root"() : () -> (i32)
// -----
// Test that children of recursively legal operations are ignored.
-func @recursively_legal_invalid_op() {
+func.func @recursively_legal_invalid_op() {
/// Operation that is statically legal.
builtin.module attributes {test.recursively_legal} {
%ignored = "test.illegal_op_f"() : () -> (i32)
builtin.module {
// Test that region cloning can be properly undone.
- func @test_undo_region_clone() {
+ func.func @test_undo_region_clone() {
"test.region"() ({
^bb1(%i0: i64):
"test.invalid"(%i0) : (i64) -> ()
builtin.module {
// Test that unknown operations can be dynamically legal.
- func @test_unknown_dynamically_legal() {
+ func.func @test_unknown_dynamically_legal() {
"foo.unknown_op"() {test.dynamically_legal} : () -> ()
// expected-error@+1 {{failed to legalize operation 'foo.unknown_op'}}
builtin.module {
// Test that region inlining can be properly undone.
- func @test_undo_region_inline() {
+ func.func @test_undo_region_inline() {
"test.region"() ({
^bb1(%i0: i64):
// expected-error@+1 {{failed to legalize operation 'cf.br'}}
builtin.module {
// Test that multiple block erases can be properly undone.
- func @test_undo_block_erase() {
+ func.func @test_undo_block_erase() {
// expected-error@+1 {{failed to legalize operation 'test.region'}}
"test.region"() ({
^bb1(%i0: i64):
// expected-remark@+1 {{applyFullConversion failed}}
builtin.module {
- func @create_unregistered_op_in_pattern() -> i32 {
+ func.func @create_unregistered_op_in_pattern() -> i32 {
// expected-error@+1 {{failed to legalize operation 'test.illegal_op_g'}}
%0 = "test.illegal_op_g"() : () -> (i32)
"test.return"(%0) : (i32) -> ()
// RUN: mlir-opt -allow-unregistered-dialect -split-input-file -test-legalize-patterns -verify-diagnostics %s | FileCheck %s
// CHECK-LABEL: verifyDirectPattern
-func @verifyDirectPattern() -> i32 {
+func.func @verifyDirectPattern() -> i32 {
// CHECK-NEXT: "test.legal_op_a"() {status = "Success"}
%result = "test.illegal_op_a"() : () -> (i32)
// expected-remark@+1 {{op 'func.return' is not legalizable}}
}
// CHECK-LABEL: verifyLargerBenefit
-func @verifyLargerBenefit() -> i32 {
+func.func @verifyLargerBenefit() -> i32 {
// CHECK-NEXT: "test.legal_op_a"() {status = "Success"}
%result = "test.illegal_op_c"() : () -> (i32)
// expected-remark@+1 {{op 'func.return' is not legalizable}}
}
// CHECK-LABEL: func private @remap_input_1_to_0()
-func private @remap_input_1_to_0(i16)
+func.func private @remap_input_1_to_0(i16)
// CHECK-LABEL: func @remap_input_1_to_1(%arg0: f64)
-func @remap_input_1_to_1(%arg0: i64) {
+func.func @remap_input_1_to_1(%arg0: i64) {
// CHECK-NEXT: "test.valid"{{.*}} : (f64)
"test.invalid"(%arg0) : (i64) -> ()
}
// CHECK-LABEL: func @remap_call_1_to_1(%arg0: f64)
-func @remap_call_1_to_1(%arg0: i64) {
+func.func @remap_call_1_to_1(%arg0: i64) {
// CHECK-NEXT: call @remap_input_1_to_1(%arg0) : (f64) -> ()
call @remap_input_1_to_1(%arg0) : (i64) -> ()
// expected-remark@+1 {{op 'func.return' is not legalizable}}
}
// CHECK-LABEL: func @remap_input_1_to_N({{.*}}f16, {{.*}}f16)
-func @remap_input_1_to_N(%arg0: f32) -> f32 {
+func.func @remap_input_1_to_N(%arg0: f32) -> f32 {
// CHECK-NEXT: "test.return"{{.*}} : (f16, f16) -> ()
"test.return"(%arg0) : (f32) -> ()
}
// CHECK-LABEL: func @remap_input_1_to_N_remaining_use(%arg0: f16, %arg1: f16)
-func @remap_input_1_to_N_remaining_use(%arg0: f32) {
+func.func @remap_input_1_to_N_remaining_use(%arg0: f32) {
// CHECK-NEXT: [[CAST:%.*]] = "test.cast"(%arg0, %arg1) : (f16, f16) -> f32
// CHECK-NEXT: "work"([[CAST]]) : (f32) -> ()
// expected-remark@+1 {{op 'work' is not legalizable}}
}
// CHECK-LABEL: func @remap_materialize_1_to_1(%{{.*}}: i43)
-func @remap_materialize_1_to_1(%arg0: i42) {
+func.func @remap_materialize_1_to_1(%arg0: i42) {
// CHECK: %[[V:.*]] = "test.cast"(%arg0) : (i43) -> i42
// CHECK: "test.return"(%[[V]])
"test.return"(%arg0) : (i42) -> ()
}
// CHECK-LABEL: func @remap_input_to_self
-func @remap_input_to_self(%arg0: index) {
+func.func @remap_input_to_self(%arg0: index) {
// CHECK-NOT: test.cast
// CHECK: "work"
// expected-remark@+1 {{op 'work' is not legalizable}}
}
// CHECK-LABEL: func @remap_multi(%arg0: f64, %arg1: f64) -> (f64, f64)
-func @remap_multi(%arg0: i64, %unused: i16, %arg1: i64) -> (i64, i64) {
+func.func @remap_multi(%arg0: i64, %unused: i16, %arg1: i64) -> (i64, i64) {
// CHECK-NEXT: "test.valid"{{.*}} : (f64, f64)
"test.invalid"(%arg0, %arg1) : (i64, i64) -> ()
}
// CHECK-LABEL: func @no_remap_nested
-func @no_remap_nested() {
+func.func @no_remap_nested() {
// CHECK-NEXT: "foo.region"
// expected-remark@+1 {{op 'foo.region' is not legalizable}}
"foo.region"() ({
}
// CHECK-LABEL: func @remap_moved_region_args
-func @remap_moved_region_args() {
+func.func @remap_moved_region_args() {
// CHECK-NEXT: return
// CHECK-NEXT: ^bb1(%{{.*}}: f64, %{{.*}}: f64, %{{.*}}: f16, %{{.*}}: f16):
// CHECK-NEXT: "test.cast"{{.*}} : (f16, f16) -> f32
}
// CHECK-LABEL: func @remap_cloned_region_args
-func @remap_cloned_region_args() {
+func.func @remap_cloned_region_args() {
// CHECK-NEXT: return
// CHECK-NEXT: ^bb1(%{{.*}}: f64, %{{.*}}: f64, %{{.*}}: f16, %{{.*}}: f16):
// CHECK-NEXT: "test.cast"{{.*}} : (f16, f16) -> f32
}
// CHECK-LABEL: func @remap_drop_region
-func @remap_drop_region() {
+func.func @remap_drop_region() {
// CHECK-NEXT: return
// CHECK-NEXT: }
"test.drop_region_op"() ({
}
// CHECK-LABEL: func @dropped_input_in_use
-func @dropped_input_in_use(%arg: i16, %arg2: i64) {
+func.func @dropped_input_in_use(%arg: i16, %arg2: i64) {
// CHECK-NEXT: "test.cast"{{.*}} : () -> i16
// CHECK-NEXT: "work"{{.*}} : (i16)
// expected-remark@+1 {{op 'work' is not legalizable}}
}
// CHECK-LABEL: func @up_to_date_replacement
-func @up_to_date_replacement(%arg: i8) -> i8 {
+func.func @up_to_date_replacement(%arg: i8) -> i8 {
// CHECK-NEXT: return
%repl_1 = "test.rewrite"(%arg) : (i8) -> i8
%repl_2 = "test.rewrite"(%repl_1) : (i8) -> i8
// CHECK-LABEL: func @remove_foldable_op
// CHECK-SAME: (%[[ARG_0:[a-z0-9]*]]: i32)
-func @remove_foldable_op(%arg0 : i32) -> (i32) {
+func.func @remove_foldable_op(%arg0 : i32) -> (i32) {
// CHECK-NEXT: return %[[ARG_0]]
%0 = "test.op_with_region_fold"(%arg0) ({
"foo.op_with_region_terminator"() : () -> ()
}
// CHECK-LABEL: @create_block
-func @create_block() {
+func.func @create_block() {
// Check that we created a block with arguments.
// CHECK-NOT: test.create_block
// CHECK: ^{{.*}}(%{{.*}}: i32, %{{.*}}: i32):
}
// CHECK-LABEL: @bounded_recursion
-func @bounded_recursion() {
+func.func @bounded_recursion() {
// CHECK: test.recursive_rewrite 0
test.recursive_rewrite 3
// expected-remark@+1 {{op 'func.return' is not legalizable}}
// expected-remark@+1 {{applyPartialConversion failed}}
builtin.module {
- func @fail_to_convert_illegal_op() -> i32 {
+ func.func @fail_to_convert_illegal_op() -> i32 {
// expected-error@+1 {{failed to legalize operation 'test.illegal_op_f'}}
%result = "test.illegal_op_f"() : () -> (i32)
return %result : i32
// expected-remark@+1 {{applyPartialConversion failed}}
builtin.module {
- func @fail_to_convert_illegal_op_in_region() {
+ func.func @fail_to_convert_illegal_op_in_region() {
// expected-error@+1 {{failed to legalize operation 'test.region_builder'}}
"test.region_builder"() : () -> ()
return
// expected-remark@+1 {{applyPartialConversion failed}}
builtin.module {
- func @fail_to_convert_region() {
+ func.func @fail_to_convert_region() {
// CHECK: "test.region"
// CHECK-NEXT: ^bb{{.*}}(%{{.*}}: i64):
"test.region"() ({
// -----
// CHECK-LABEL: @create_illegal_block
-func @create_illegal_block() {
+func.func @create_illegal_block() {
// Check that we can undo block creation, i.e. that the block was removed.
// CHECK: test.create_illegal_block
// CHECK-NOT: ^{{.*}}(%{{.*}}: i32, %{{.*}}: i32):
// -----
// CHECK-LABEL: @undo_block_arg_replace
-func @undo_block_arg_replace() {
+func.func @undo_block_arg_replace() {
// expected-remark@+1 {{op 'test.undo_block_arg_replace' is not legalizable}}
"test.undo_block_arg_replace"() ({
^bb0(%arg0: i32):
// a pattern that removes its second block after adding an operation into it.
// Check that we can undo block removal successfully.
// CHECK-LABEL: @undo_block_erase
-func @undo_block_erase() {
+func.func @undo_block_erase() {
// CHECK: test.undo_block_erase
"test.undo_block_erase"() ({
// expected-remark@-1 {{not legalizable}}
// created ops in the inverse order, i.e. deleting the parent op and then the
// child op.
// CHECK-LABEL: @undo_child_created_before_parent
-func @undo_child_created_before_parent() {
+func.func @undo_child_created_before_parent() {
// expected-remark@+1 {{is not legalizable}}
"test.illegal_op_with_region_anchor"() : () -> ()
// expected-remark@+1 {{op 'func.return' is not legalizable}}
// Check that a conversion pattern on `test.blackhole` can mark the producer
// for deletion.
// CHECK-LABEL: @blackhole
-func @blackhole() {
+func.func @blackhole() {
%input = "test.blackhole_producer"() : () -> (i32)
"test.blackhole"(%input) : (i32) -> ()
// expected-remark@+1 {{op 'func.return' is not legalizable}}
// expected-remark@+1 {{applyPartialConversion failed}}
builtin.module {
- func @create_unregistered_op_in_pattern() -> i32 {
+ func.func @create_unregistered_op_in_pattern() -> i32 {
// expected-error@+1 {{failed to legalize operation 'test.illegal_op_g'}}
%0 = "test.illegal_op_g"() : () -> (i32)
"test.return"(%0) : (i32) -> ()
// The "passthrough_fold" folder will naively return its operand, but we don't
// want to fold here because of the type mismatch.
-func @typemismatch(%arg: f32) -> i32 {
+func.func @typemismatch(%arg: f32) -> i32 {
// expected-remark@+1 {{op 'test.passthrough_fold' is not legalizable}}
%0 = "test.passthrough_fold"(%arg) : (f32) -> (i32)
"test.return"(%0) : (i32) -> ()
// RUN: mlir-opt -allow-unregistered-dialect -split-input-file -test-merge-blocks -verify-diagnostics %s | FileCheck %s
// CHECK-LABEL: @merge_blocks
-func @merge_blocks(%arg0: i32, %arg1 : i32) -> () {
+func.func @merge_blocks(%arg0: i32, %arg1 : i32) -> () {
// CHECK: "test.merge_blocks"() ({
// CHECK-NEXT: "test.return"
// CHECK-NEXT: })
// after adding an operation into it. Check that we can undo block
// removal successfully.
// CHECK-LABEL: @undo_blocks_merge
-func @undo_blocks_merge(%arg0: i32) {
+func.func @undo_blocks_merge(%arg0: i32) {
"test.undo_blocks_merge"() ({
// expected-remark@-1 {{op 'test.undo_blocks_merge' is not legalizable}}
// CHECK: "unregistered.return"(%{{.*}})[^[[BB:.*]]]
// -----
// CHECK-LABEL: @inline_regions()
-func @inline_regions() -> ()
+func.func @inline_regions() -> ()
{
// CHECK: test.SingleBlockImplicitTerminator
// CHECK-NEXT: %[[T0:.*]] = "test.type_producer"
// RUN: mlir-opt --pass-pipeline="func.func(test-patterns)" %s | FileCheck %s
// CHECK-LABEL: func @test_reorder_constants_and_match
-func @test_reorder_constants_and_match(%arg0 : i32) -> (i32) {
+func.func @test_reorder_constants_and_match(%arg0 : i32) -> (i32) {
// CHECK: %[[CST:.+]] = arith.constant 43
%cst = arith.constant 43 : i32
// CHECK: return %[[CST]]
// RUN: mlir-opt -test-patterns -test-patterns %s | FileCheck %s
-func @foo() -> i32 {
+func.func @foo() -> i32 {
%c42 = arith.constant 42 : i32
// The new operation should be present in the output and contain an attribute
return %0 : i32
}
-func @test_fold_before_previously_folded_op() -> (i32, i32) {
+func.func @test_fold_before_previously_folded_op() -> (i32, i32) {
// When folding two constants will be generated and uniqued. Check that the
// uniqued constant properly dominates both uses.
// CHECK: %[[CST:.+]] = arith.constant true
return %0, %1 : i32, i32
}
-func @test_dont_reorder_constants() -> (i32, i32, i32) {
+func.func @test_dont_reorder_constants() -> (i32, i32, i32) {
// Test that we don't reorder existing constants during folding if it isn't necessary.
// CHECK: %[[CST:.+]] = arith.constant 1
// CHECK-NEXT: %[[CST:.+]] = arith.constant 2
// CHECK-LABEL: @test1
// CHECK-SAME: %[[ARG0:.*]]: i32, %[[ARG1:.*]]: i32
-func @test1(%arg0: i32, %arg1 : i32) -> () {
+func.func @test1(%arg0: i32, %arg1 : i32) -> () {
// CHECK: arith.addi %[[ARG1]], %[[ARG1]]
// CHECK-NEXT: "test.return"(%[[ARG0]]
%cast = "test.cast"(%arg0, %arg1) : (i32, i32) -> (i32)
// CHECK-LABEL: module attributes {test.simple}
module attributes {test.simple} {
// CHECK-NOT: func private @dead_private_function
- func private @dead_private_function()
+ func.func private @dead_private_function()
// CHECK-NOT: func nested @dead_nested_function
- func nested @dead_nested_function()
+ func.func nested @dead_nested_function()
// CHECK: func private @live_private_function
- func private @live_private_function()
+ func.func private @live_private_function()
// CHECK: func nested @live_nested_function
- func nested @live_nested_function()
+ func.func nested @live_nested_function()
// CHECK: func @public_function
- func @public_function() {
+ func.func @public_function() {
"foo.return"() {uses = [@live_private_function, @live_nested_function]} : () -> ()
}
}
// CHECK: module @public_module
module @public_module {
// CHECK-NOT: func nested @dead_nested_function
- func nested @dead_nested_function()
+ func.func nested @dead_nested_function()
// CHECK: func private @private_function
- func private @private_function()
+ func.func private @private_function()
// CHECK: func nested @nested_function
- func nested @nested_function() {
+ func.func nested @nested_function() {
"foo.return"() {uses = [@private_function]} : () -> ()
}
}
// NESTED: module @public_module
module @public_module {
// NESTED: func nested @nested_function
- func nested @nested_function()
+ func.func nested @nested_function()
}
// NESTED: module @nested_module
module @nested_module attributes { sym_visibility = "nested" } {
// NESTED: func nested @nested_function
- func nested @nested_function()
+ func.func nested @nested_function()
}
// Only private modules can be assumed to be hidden.
// NESTED: module @private_module
module @private_module attributes { sym_visibility = "private" } {
// NESTED-NOT: func nested @nested_function
- func nested @nested_function()
+ func.func nested @nested_function()
}
"live.user"() {uses = [@nested_module, @private_module]} : () -> ()
// -----
module {
- func private @private_symbol()
+ func.func private @private_symbol()
// expected-error@+1 {{contains potentially unknown symbol table}}
"foo.possibly_unknown_symbol_table"() ({
// Check that unknown symbol references are OK.
module {
// CHECK-NOT: func private @dead_private_function
- func private @dead_private_function()
+ func.func private @dead_private_function()
// CHECK: func private @live_private_function
- func private @live_private_function()
+ func.func private @live_private_function()
// CHECK: "live.user"() {uses = [@live_private_function]} : () -> ()
"live.user"() {uses = [@live_private_function]} : () -> ()
// CHECK-LABEL: module attributes {test.simple}
module attributes {test.simple} {
// CHECK: func @aap
- func @aap() { return }
+ func.func @aap() { return }
// CHECK: func private @kat
- func @kat() { return }
+ func.func @kat() { return }
}