1// RUN: mlir-opt -allow-unregistered-dialect %s -symbol-dce -split-input-file -verify-diagnostics | FileCheck %s
2// RUN: mlir-opt -allow-unregistered-dialect %s -pass-pipeline="module(symbol-dce)" -split-input-file | FileCheck %s --check-prefix=NESTED
3
4// Check that trivially dead and trivially live non-nested cases are handled.
5
6// CHECK-LABEL: module attributes {test.simple}
7module attributes {test.simple} {
8  // CHECK-NOT: func private @dead_private_function
9  func private @dead_private_function()
10
11  // CHECK-NOT: func nested @dead_nested_function
12  func nested @dead_nested_function()
13
14  // CHECK: func private @live_private_function
15  func private @live_private_function()
16
17  // CHECK: func nested @live_nested_function
18  func nested @live_nested_function()
19
20  // CHECK: func @public_function
21  func @public_function() {
22    "foo.return"() {uses = [@live_private_function, @live_nested_function]} : () -> ()
23  }
24}
25
26// -----
27
28// Check that we don't DCE nested symbols if they are used.
29// CHECK-LABEL: module attributes {test.nested}
30module attributes {test.nested} {
31  // CHECK: module @public_module
32  module @public_module {
33    // CHECK-NOT: func nested @dead_nested_function
34    func nested @dead_nested_function()
35
36    // CHECK: func private @private_function
37    func private @private_function()
38
39    // CHECK: func nested @nested_function
40    func nested @nested_function() {
41      "foo.return"() {uses = [@private_function]} : () -> ()
42    }
43  }
44
45  "live.user"() {uses = [@public_module::@nested_function]} : () -> ()
46}
47
48// -----
49
50// Check that we don't DCE symbols if we can't prove that the top-level symbol
51// table that we are running on is hidden from above.
52// NESTED-LABEL: module attributes {test.no_dce_non_hidden_parent}
53module attributes {test.no_dce_non_hidden_parent} {
54  // NESTED: module @public_module
55  module @public_module {
56    // NESTED: func nested @nested_function
57    func nested @nested_function()
58  }
59  // NESTED: module @nested_module
60  module @nested_module attributes { sym_visibility = "nested" } {
61    // NESTED: func nested @nested_function
62    func nested @nested_function()
63  }
64
65  // Only private modules can be assumed to be hidden.
66  // NESTED: module @private_module
67  module @private_module attributes { sym_visibility = "private" } {
68    // NESTED-NOT: func nested @nested_function
69    func nested @nested_function()
70  }
71
72  "live.user"() {uses = [@nested_module, @private_module]} : () -> ()
73}
74
75// -----
76
77module {
78  func private @private_symbol()
79
80  // expected-error@+1 {{contains potentially unknown symbol table}}
81  "foo.possibly_unknown_symbol_table"() ({
82  }) : () -> ()
83}
84
85// -----
86
87module {
88  // expected-error@+1 {{unable to resolve reference to symbol}}
89  "live.user"() {uses = [@unknown_symbol]} : () -> ()
90}
91