• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// RUN: mlir-opt -split-input-file -verify-diagnostics %s | mlir-opt | FileCheck %s
2// RUN: mlir-opt -split-input-file -verify-diagnostics -mlir-print-op-generic %s | FileCheck %s --check-prefix=GENERIC
3
4module {
5  // GENERIC: "llvm.func"
6  // GENERIC: sym_name = "foo"
7  // GENERIC-SAME: type = !llvm.func<void ()>
8  // GENERIC-SAME: () -> ()
9  // CHECK: llvm.func @foo()
10  "llvm.func"() ({
11  }) {sym_name = "foo", type = !llvm.func<void ()>} : () -> ()
12
13  // GENERIC: "llvm.func"
14  // GENERIC: sym_name = "bar"
15  // GENERIC-SAME: type = !llvm.func<i64 (i64, i64)>
16  // GENERIC-SAME: () -> ()
17  // CHECK: llvm.func @bar(!llvm.i64, !llvm.i64) -> !llvm.i64
18  "llvm.func"() ({
19  }) {sym_name = "bar", type = !llvm.func<i64 (i64, i64)>} : () -> ()
20
21  // GENERIC: "llvm.func"
22  // CHECK: llvm.func @baz(%{{.*}}: !llvm.i64) -> !llvm.i64
23  "llvm.func"() ({
24  // GENERIC: ^bb0
25  ^bb0(%arg0: !llvm.i64):
26    // GENERIC: llvm.return
27    llvm.return %arg0 : !llvm.i64
28
29  // GENERIC: sym_name = "baz"
30  // GENERIC-SAME: type = !llvm.func<i64 (i64)>
31  // GENERIC-SAME: () -> ()
32  }) {sym_name = "baz", type = !llvm.func<i64 (i64)>} : () -> ()
33
34  // CHECK: llvm.func @qux(!llvm.ptr<i64> {llvm.noalias = true}, !llvm.i64)
35  // CHECK: attributes {xxx = {yyy = 42 : i64}}
36  "llvm.func"() ({
37  }) {sym_name = "qux", type = !llvm.func<void (ptr<i64>, i64)>,
38      arg0 = {llvm.noalias = true}, xxx = {yyy = 42}} : () -> ()
39
40  // CHECK: llvm.func @roundtrip1()
41  llvm.func @roundtrip1()
42
43  // CHECK: llvm.func @roundtrip2(!llvm.i64, !llvm.float) -> !llvm.double
44  llvm.func @roundtrip2(!llvm.i64, !llvm.float) -> !llvm.double
45
46  // CHECK: llvm.func @roundtrip3(!llvm.i32, !llvm.i1)
47  llvm.func @roundtrip3(%a: !llvm.i32, %b: !llvm.i1)
48
49  // CHECK: llvm.func @roundtrip4(%{{.*}}: !llvm.i32, %{{.*}}: !llvm.i1) {
50  llvm.func @roundtrip4(%a: !llvm.i32, %b: !llvm.i1) {
51    llvm.return
52  }
53
54  // CHECK: llvm.func @roundtrip5()
55  // CHECK: attributes {baz = 42 : i64, foo = "bar"}
56  llvm.func @roundtrip5() attributes {foo = "bar", baz = 42}
57
58  // CHECK: llvm.func @roundtrip6()
59  // CHECK: attributes {baz = 42 : i64, foo = "bar"}
60  llvm.func @roundtrip6() attributes {foo = "bar", baz = 42} {
61    llvm.return
62  }
63
64  // CHECK: llvm.func @roundtrip7() {
65  llvm.func @roundtrip7() attributes {} {
66    llvm.return
67  }
68
69  // CHECK: llvm.func @roundtrip8() -> !llvm.i32
70  llvm.func @roundtrip8() -> !llvm.i32 attributes {}
71
72  // CHECK: llvm.func @roundtrip9(!llvm.ptr<i32> {llvm.noalias = true})
73  llvm.func @roundtrip9(!llvm.ptr<i32> {llvm.noalias = true})
74
75  // CHECK: llvm.func @roundtrip10(!llvm.ptr<i32> {llvm.noalias = true})
76  llvm.func @roundtrip10(%arg0: !llvm.ptr<i32> {llvm.noalias = true})
77
78  // CHECK: llvm.func @roundtrip11(%{{.*}}: !llvm.ptr<i32> {llvm.noalias = true}) {
79  llvm.func @roundtrip11(%arg0: !llvm.ptr<i32> {llvm.noalias = true}) {
80    llvm.return
81  }
82
83  // CHECK: llvm.func @roundtrip12(%{{.*}}: !llvm.ptr<i32> {llvm.noalias = true})
84  // CHECK: attributes {foo = 42 : i32}
85  llvm.func @roundtrip12(%arg0: !llvm.ptr<i32> {llvm.noalias = true})
86  attributes {foo = 42 : i32} {
87    llvm.return
88  }
89
90  // CHECK: llvm.func @variadic(...)
91  llvm.func @variadic(...)
92
93  // CHECK: llvm.func @variadic_args(!llvm.i32, !llvm.i32, ...)
94  llvm.func @variadic_args(!llvm.i32, !llvm.i32, ...)
95
96  //
97  // Check that functions can have linkage attributes.
98  //
99
100  // CHECK: llvm.func internal
101  llvm.func internal @internal_func() {
102    llvm.return
103  }
104
105  // CHECK: llvm.func weak
106  llvm.func weak @weak_linkage() {
107    llvm.return
108  }
109
110  // Omit the `external` linkage, which is the default, in the custom format.
111  // Check that it is present in the generic format using its numeric value.
112  //
113  // CHECK: llvm.func @external_func
114  // GENERIC: linkage = 10
115  llvm.func external @external_func()
116}
117
118// -----
119
120module {
121  // expected-error@+1 {{requires one region}}
122  "llvm.func"() {sym_name = "no_region", type = !llvm.func<void ()>} : () -> ()
123}
124
125// -----
126
127module {
128  // expected-error@+1 {{requires a type attribute 'type'}}
129  "llvm.func"() ({}) {sym_name = "missing_type"} : () -> ()
130}
131
132// -----
133
134module {
135  // expected-error@+1 {{requires 'type' attribute of wrapped LLVM function type}}
136  "llvm.func"() ({}) {sym_name = "non_llvm_type", type = i64} : () -> ()
137}
138
139// -----
140
141module {
142  // expected-error@+1 {{requires 'type' attribute of wrapped LLVM function type}}
143  "llvm.func"() ({}) {sym_name = "non_function_type", type = !llvm.i64} : () -> ()
144}
145
146// -----
147
148module {
149  // expected-error@+1 {{entry block must have 0 arguments}}
150  "llvm.func"() ({
151  ^bb0(%arg0: !llvm.i64):
152    llvm.return
153  }) {sym_name = "wrong_arg_number", type = !llvm.func<void ()>} : () -> ()
154}
155
156// -----
157
158module {
159  // expected-error@+1 {{entry block argument #0 is not of LLVM type}}
160  "llvm.func"() ({
161  ^bb0(%arg0: i64):
162    llvm.return
163  }) {sym_name = "wrong_arg_number", type = !llvm.func<void (i64)>} : () -> ()
164}
165
166// -----
167
168module {
169  // expected-error@+1 {{entry block argument #0 does not match the function signature}}
170  "llvm.func"() ({
171  ^bb0(%arg0: !llvm.i32):
172    llvm.return
173  }) {sym_name = "wrong_arg_number", type = !llvm.func<void (i64)>} : () -> ()
174}
175
176// -----
177
178module {
179  // expected-error@+1 {{failed to construct function type: expected LLVM type for function arguments}}
180  llvm.func @foo(i64)
181}
182
183// -----
184
185module {
186  // expected-error@+1 {{failed to construct function type: expected LLVM type for function results}}
187  llvm.func @foo() -> i64
188}
189
190// -----
191
192module {
193  // expected-error@+1 {{failed to construct function type: expected zero or one function result}}
194  llvm.func @foo() -> (!llvm.i64, !llvm.i64)
195}
196
197// -----
198
199module {
200  // expected-error@+1 {{only external functions can be variadic}}
201  llvm.func @variadic_def(...) {
202    llvm.return
203  }
204}
205
206// -----
207
208module {
209  // expected-error@+1 {{variadic arguments must be in the end of the argument list}}
210  llvm.func @variadic_inside(%arg0: !llvm.i32, ..., %arg1: !llvm.i32)
211}
212
213// -----
214
215module {
216  // expected-error@+1 {{external functions must have 'external' or 'extern_weak' linkage}}
217  llvm.func internal @internal_external_func()
218}
219
220// -----
221
222module {
223  // expected-error@+1 {{functions cannot have 'common' linkage}}
224  llvm.func common @common_linkage_func()
225}
226