// RUN: mlir-opt -test-last-modified %s 2>&1 | FileCheck %s // CHECK-LABEL: test_tag: test_simple_mod // CHECK: operand #0 // CHECK-NEXT: - a // CHECK: operand #1 // CHECK-NEXT: - b func.func @test_simple_mod(%arg0: memref, %arg1: memref) -> (memref, memref) { %c0 = arith.constant 0 : i32 %c1 = arith.constant 1 : i32 memref.store %c0, %arg0[] {tag_name = "a"} : memref memref.store %c1, %arg1[] {tag_name = "b"} : memref return {tag = "test_simple_mod"} %arg0, %arg1 : memref, memref } // CHECK-LABEL: test_tag: test_simple_mod_overwrite_a // CHECK: operand #1 // CHECK-NEXT: - a // CHECK-LABEL: test_tag: test_simple_mod_overwrite_b // CHECK: operand #0 // CHECK-NEXT: - b func.func @test_simple_mod_overwrite(%arg0: memref) -> memref { %c0 = arith.constant 0 : i32 memref.store %c0, %arg0[] {tag = "test_simple_mod_overwrite_a", tag_name = "a"} : memref %c1 = arith.constant 1 : i32 memref.store %c1, %arg0[] {tag_name = "b"} : memref return {tag = "test_simple_mod_overwrite_b"} %arg0 : memref } // CHECK-LABEL: test_tag: test_mod_control_flow // CHECK: operand #0 // CHECK-NEXT: - b // CHECK-NEXT: - a func.func @test_mod_control_flow(%cond: i1, %ptr: memref) -> memref { cf.cond_br %cond, ^a, ^b ^a: %c0 = arith.constant 0 : i32 memref.store %c0, %ptr[] {tag_name = "a"} : memref cf.br ^c ^b: %c1 = arith.constant 1 : i32 memref.store %c1, %ptr[] {tag_name = "b"} : memref cf.br ^c ^c: return {tag = "test_mod_control_flow"} %ptr : memref } // CHECK-LABEL: test_tag: test_mod_dead_branch // CHECK: operand #0 // CHECK-NEXT: - a func.func @test_mod_dead_branch(%arg: i32, %ptr: memref) -> memref { %0 = arith.subi %arg, %arg : i32 %1 = arith.constant -1 : i32 %2 = arith.cmpi sgt, %0, %1 : i32 cf.cond_br %2, ^a, ^b ^a: %c0 = arith.constant 0 : i32 memref.store %c0, %ptr[] {tag_name = "a"} : memref cf.br ^c ^b: %c1 = arith.constant 1 : i32 memref.store %c1, %ptr[] {tag_name = "b"} : memref cf.br ^c ^c: return {tag = "test_mod_dead_branch"} %ptr : memref } // CHECK-LABEL: test_tag: test_mod_region_control_flow // CHECK: operand #0 // CHECK-NEXT: then // CHECK-NEXT: else func.func @test_mod_region_control_flow(%cond: i1, %ptr: memref) -> memref { scf.if %cond { %c0 = arith.constant 0 : i32 memref.store %c0, %ptr[] {tag_name = "then"}: memref } else { %c1 = arith.constant 1 : i32 memref.store %c1, %ptr[] {tag_name = "else"} : memref } return {tag = "test_mod_region_control_flow"} %ptr : memref } // CHECK-LABEL: test_tag: test_mod_dead_region // CHECK: operand #0 // CHECK-NEXT: else func.func @test_mod_dead_region(%ptr: memref) -> memref { %false = arith.constant false scf.if %false { %c0 = arith.constant 0 : i32 memref.store %c0, %ptr[] {tag_name = "then"}: memref } else { %c1 = arith.constant 1 : i32 memref.store %c1, %ptr[] {tag_name = "else"} : memref } return {tag = "test_mod_dead_region"} %ptr : memref } // CHECK-LABEL: test_tag: unknown_memory_effects_a // CHECK: operand #1 // CHECK-NEXT: - a // CHECK-LABEL: test_tag: unknown_memory_effects_b // CHECK: operand #0 // CHECK-NEXT: - func.func @unknown_memory_effects(%ptr: memref) -> memref { %c0 = arith.constant 0 : i32 memref.store %c0, %ptr[] {tag = "unknown_memory_effects_a", tag_name = "a"} : memref "test.unknown_effects"() : () -> () return {tag = "unknown_memory_effects_b"} %ptr : memref } // CHECK-LABEL: test_tag: store_with_a_region_before::before: // CHECK: operand #0 // CHECK: - pre // CHECK: test_tag: inside_region: // CHECK: operand #0 // CHECK: - region // CHECK: test_tag: after: // CHECK: operand #0 // CHECK: - region // CHECK: test_tag: return: // CHECK: operand #0 // CHECK: - post func.func @store_with_a_region_before(%arg0: memref) -> memref { %0 = arith.constant 0.0 : f32 %1 = arith.constant 1.0 : f32 memref.store %0, %arg0[] {tag_name = "pre"} : memref memref.load %arg0[] {tag = "store_with_a_region_before::before"} : memref test.store_with_a_region %arg0 attributes { tag_name = "region", store_before_region = true } { memref.load %arg0[] {tag = "inside_region"} : memref test.store_with_a_region_terminator } : memref memref.load %arg0[] {tag = "after"} : memref memref.store %1, %arg0[] {tag_name = "post"} : memref return {tag = "return"} %arg0 : memref } // CHECK-LABEL: test_tag: store_with_a_region_after::before: // CHECK: operand #0 // CHECK: - pre // CHECK: test_tag: inside_region: // CHECK: operand #0 // CHECK: - pre // CHECK: test_tag: after: // CHECK: operand #0 // CHECK: - region // CHECK: test_tag: return: // CHECK: operand #0 // CHECK: - post func.func @store_with_a_region_after(%arg0: memref) -> memref { %0 = arith.constant 0.0 : f32 %1 = arith.constant 1.0 : f32 memref.store %0, %arg0[] {tag_name = "pre"} : memref memref.load %arg0[] {tag = "store_with_a_region_after::before"} : memref test.store_with_a_region %arg0 attributes { tag_name = "region", store_before_region = false } { memref.load %arg0[] {tag = "inside_region"} : memref test.store_with_a_region_terminator } : memref memref.load %arg0[] {tag = "after"} : memref memref.store %1, %arg0[] {tag_name = "post"} : memref return {tag = "return"} %arg0 : memref } // CHECK-LABEL: test_tag: store_with_a_region_before_containing_a_store::before: // CHECK: operand #0 // CHECK: - pre // CHECK: test_tag: enter_region: // CHECK: operand #0 // CHECK: - region // CHECK: test_tag: exit_region: // CHECK: operand #0 // CHECK: - inner // CHECK: test_tag: after: // CHECK: operand #0 // CHECK: - inner // CHECK: test_tag: return: // CHECK: operand #0 // CHECK: - post func.func @store_with_a_region_before_containing_a_store(%arg0: memref) -> memref { %0 = arith.constant 0.0 : f32 %1 = arith.constant 1.0 : f32 memref.store %0, %arg0[] {tag_name = "pre"} : memref memref.load %arg0[] {tag = "store_with_a_region_before_containing_a_store::before"} : memref test.store_with_a_region %arg0 attributes { tag_name = "region", store_before_region = true } { memref.load %arg0[] {tag = "enter_region"} : memref %2 = arith.constant 2.0 : f32 memref.store %2, %arg0[] {tag_name = "inner"} : memref memref.load %arg0[] {tag = "exit_region"} : memref test.store_with_a_region_terminator } : memref memref.load %arg0[] {tag = "after"} : memref memref.store %1, %arg0[] {tag_name = "post"} : memref return {tag = "return"} %arg0 : memref } // CHECK-LABEL: test_tag: store_with_a_region_after_containing_a_store::before: // CHECK: operand #0 // CHECK: - pre // CHECK: test_tag: enter_region: // CHECK: operand #0 // CHECK: - pre // CHECK: test_tag: exit_region: // CHECK: operand #0 // CHECK: - inner // CHECK: test_tag: after: // CHECK: operand #0 // CHECK: - region // CHECK: test_tag: return: // CHECK: operand #0 // CHECK: - post func.func @store_with_a_region_after_containing_a_store(%arg0: memref) -> memref { %0 = arith.constant 0.0 : f32 %1 = arith.constant 1.0 : f32 memref.store %0, %arg0[] {tag_name = "pre"} : memref memref.load %arg0[] {tag = "store_with_a_region_after_containing_a_store::before"} : memref test.store_with_a_region %arg0 attributes { tag_name = "region", store_before_region = false } { memref.load %arg0[] {tag = "enter_region"} : memref %2 = arith.constant 2.0 : f32 memref.store %2, %arg0[] {tag_name = "inner"} : memref memref.load %arg0[] {tag = "exit_region"} : memref test.store_with_a_region_terminator } : memref memref.load %arg0[] {tag = "after"} : memref memref.store %1, %arg0[] {tag_name = "post"} : memref return {tag = "return"} %arg0 : memref } // CHECK-LABEL: test_tag: store_with_a_loop_region_before::before: // CHECK: operand #0 // CHECK: - pre // CHECK: test_tag: inside_region: // CHECK: operand #0 // CHECK: - region // CHECK: test_tag: after: // CHECK: operand #0 // CHECK: - region // CHECK: test_tag: return: // CHECK: operand #0 // CHECK: - post func.func @store_with_a_loop_region_before(%arg0: memref) -> memref { %0 = arith.constant 0.0 : f32 %1 = arith.constant 1.0 : f32 memref.store %0, %arg0[] {tag_name = "pre"} : memref memref.load %arg0[] {tag = "store_with_a_loop_region_before::before"} : memref test.store_with_a_loop_region %arg0 attributes { tag_name = "region", store_before_region = true } { memref.load %arg0[] {tag = "inside_region"} : memref test.store_with_a_region_terminator } : memref memref.load %arg0[] {tag = "after"} : memref memref.store %1, %arg0[] {tag_name = "post"} : memref return {tag = "return"} %arg0 : memref } // CHECK-LABEL: test_tag: store_with_a_loop_region_after::before: // CHECK: operand #0 // CHECK: - pre // CHECK: test_tag: inside_region: // CHECK: operand #0 // CHECK: - pre // CHECK: test_tag: after: // CHECK: operand #0 // CHECK: - region // CHECK: test_tag: return: // CHECK: operand #0 // CHECK: - post func.func @store_with_a_loop_region_after(%arg0: memref) -> memref { %0 = arith.constant 0.0 : f32 %1 = arith.constant 1.0 : f32 memref.store %0, %arg0[] {tag_name = "pre"} : memref memref.load %arg0[] {tag = "store_with_a_loop_region_after::before"} : memref test.store_with_a_loop_region %arg0 attributes { tag_name = "region", store_before_region = false } { memref.load %arg0[] {tag = "inside_region"} : memref test.store_with_a_region_terminator } : memref memref.load %arg0[] {tag = "after"} : memref memref.store %1, %arg0[] {tag_name = "post"} : memref return {tag = "return"} %arg0 : memref } // CHECK-LABEL: test_tag: store_with_a_loop_region_before_containing_a_store::before: // CHECK: operand #0 // CHECK: - pre // CHECK: test_tag: enter_region: // CHECK: operand #0 // CHECK-DAG: - region // CHECK-DAG: - inner // CHECK: test_tag: exit_region: // CHECK: operand #0 // CHECK: - inner // CHECK: test_tag: after: // CHECK: operand #0 // CHECK-DAG: - region // CHECK-DAG: - inner // CHECK: test_tag: return: // CHECK: operand #0 // CHECK: - post func.func @store_with_a_loop_region_before_containing_a_store(%arg0: memref) -> memref { %0 = arith.constant 0.0 : f32 %1 = arith.constant 1.0 : f32 memref.store %0, %arg0[] {tag_name = "pre"} : memref memref.load %arg0[] {tag = "store_with_a_loop_region_before_containing_a_store::before"} : memref test.store_with_a_loop_region %arg0 attributes { tag_name = "region", store_before_region = true } { memref.load %arg0[] {tag = "enter_region"} : memref %2 = arith.constant 2.0 : f32 memref.store %2, %arg0[] {tag_name = "inner"} : memref memref.load %arg0[] {tag = "exit_region"} : memref test.store_with_a_region_terminator } : memref memref.load %arg0[] {tag = "after"} : memref memref.store %1, %arg0[] {tag_name = "post"} : memref return {tag = "return"} %arg0 : memref } // CHECK-LABEL: test_tag: store_with_a_loop_region_after_containing_a_store::before: // CHECK: operand #0 // CHECK: - pre // CHECK: test_tag: enter_region: // CHECK: operand #0 // CHECK-DAG: - pre // CHECK-DAG: - inner // CHECK: test_tag: exit_region: // CHECK: operand #0 // CHECK: - inner // CHECK: test_tag: after: // CHECK: operand #0 // CHECK: - region // CHECK: test_tag: return: // CHECK: operand #0 // CHECK: - post func.func @store_with_a_loop_region_after_containing_a_store(%arg0: memref) -> memref { %0 = arith.constant 0.0 : f32 %1 = arith.constant 1.0 : f32 memref.store %0, %arg0[] {tag_name = "pre"} : memref memref.load %arg0[] {tag = "store_with_a_loop_region_after_containing_a_store::before"} : memref test.store_with_a_loop_region %arg0 attributes { tag_name = "region", store_before_region = false } { memref.load %arg0[] {tag = "enter_region"} : memref %2 = arith.constant 2.0 : f32 memref.store %2, %arg0[] {tag_name = "inner"} : memref memref.load %arg0[] {tag = "exit_region"} : memref test.store_with_a_region_terminator } : memref memref.load %arg0[] {tag = "after"} : memref memref.store %1, %arg0[] {tag_name = "post"} : memref return {tag = "return"} %arg0 : memref }