xref: /llvm-project/mlir/test/Target/LLVMIR/Import/function-attributes.ll (revision 4fc514af516f9434bf5ba3de404943a1f92817f7)
1; RUN: mlir-translate -import-llvm -split-input-file %s --verify-diagnostics | FileCheck %s
2
3; CHECK: llvm.func internal @func_internal
4define internal void @func_internal() {
5  ret void
6}
7
8; CHECK: llvm.func internal spir_funccc @spir_func_internal()
9define internal spir_func void @spir_func_internal() {
10  ret void
11}
12
13; // -----
14
15; Ensure that we have dso_local.
16; CHECK: llvm.func @dsolocal_func()
17; CHECK-SAME: attributes {dso_local}
18define dso_local void @dsolocal_func() {
19  ret void
20}
21
22; // -----
23
24; CHECK-LABEL: @func_readnone
25; CHECK-SAME:  attributes {memory_effects = #llvm.memory_effects<other = none, argMem = none, inaccessibleMem = none>}
26; CHECK:   llvm.return
27define void @func_readnone() readnone {
28  ret void
29}
30
31; CHECK-LABEL: @func_readnone_indirect
32; CHECK-SAME:  attributes {memory_effects = #llvm.memory_effects<other = none, argMem = none, inaccessibleMem = none>}
33declare void @func_readnone_indirect() #0
34attributes #0 = { readnone }
35
36; // -----
37
38; CHECK-LABEL: @func_arg_attrs
39; CHECK-SAME:  !llvm.ptr {llvm.byval = i64}
40; CHECK-SAME:  !llvm.ptr {llvm.byref = i64}
41; CHECK-SAME:  !llvm.ptr {llvm.noalias}
42; CHECK-SAME:  !llvm.ptr {llvm.readonly}
43; CHECK-SAME:  !llvm.ptr {llvm.nest}
44; CHECK-SAME:  i32 {llvm.signext}
45; CHECK-SAME:  i64 {llvm.zeroext}
46; CHECK-SAME:  !llvm.ptr {llvm.align = 64 : i64, llvm.noundef}
47; CHECK-SAME:  !llvm.ptr {llvm.dereferenceable = 12 : i64}
48; CHECK-SAME:  !llvm.ptr {llvm.dereferenceable_or_null = 42 : i64}
49; CHECK-SAME:  f64 {llvm.inreg}
50; CHECK-SAME:  !llvm.ptr {llvm.nocapture}
51; CHECK-SAME:  !llvm.ptr {llvm.nofree}
52; CHECK-SAME:  !llvm.ptr {llvm.nonnull}
53; CHECK-SAME:  !llvm.ptr {llvm.preallocated = f64}
54; CHECK-SAME:  !llvm.ptr {llvm.returned}
55; CHECK-SAME:  !llvm.ptr {llvm.alignstack = 32 : i64}
56; CHECK-SAME:  !llvm.ptr {llvm.writeonly}
57; CHECK-SAME:  i64 {llvm.range = #llvm.constant_range<i64, 0, 4097>}
58define ptr @func_arg_attrs(
59    ptr byval(i64) %arg0,
60    ptr byref(i64) %arg1,
61    ptr noalias %arg4,
62    ptr readonly %arg5,
63    ptr nest %arg6,
64    i32 signext %arg7,
65    i64 zeroext %arg8,
66    ptr align(64) noundef %arg9,
67    ptr dereferenceable(12) %arg10,
68    ptr dereferenceable_or_null(42) %arg11,
69    double inreg %arg12,
70    ptr captures(none) %arg13,
71    ptr nofree %arg14,
72    ptr nonnull %arg15,
73    ptr preallocated(double) %arg16,
74    ptr returned %arg17,
75    ptr alignstack(32) %arg18,
76    ptr writeonly %arg19,
77    i64 range(i64 0, 4097) %arg20) {
78  ret ptr %arg17
79}
80
81; CHECK-LABEL: @sret
82; CHECK-SAME:  !llvm.ptr {llvm.sret = i64}
83define void @sret(ptr sret(i64) %arg0) {
84  ret void
85}
86
87; CHECK-LABEL: @inalloca
88; CHECK-SAME:  !llvm.ptr {llvm.inalloca = i64}
89define void @inalloca(ptr inalloca(i64) %arg0) {
90  ret void
91}
92
93; CHECK-LABEL: @allocator
94; CHECK-SAME:  i64 {llvm.allocalign}
95; CHECK-SAME:  ptr {llvm.allocptr}
96declare ptr @allocator(i64 allocalign, ptr allocptr)
97
98; // -----
99
100; CHECK-LABEL: @func_res_attr_noalias
101; CHECK-SAME:  !llvm.ptr {llvm.noalias}
102declare noalias ptr @func_res_attr_noalias()
103
104; // -----
105
106; CHECK-LABEL: @func_res_attr_nonnull
107; CHECK-SAME:  !llvm.ptr {llvm.nonnull}
108declare nonnull ptr @func_res_attr_nonnull()
109
110; // -----
111
112; CHECK-LABEL: @func_res_attr_signext
113; CHECK-DAG: llvm.noundef
114; CHECK-DAG: llvm.signext
115declare noundef signext i32 @func_res_attr_signext()
116
117; // -----
118
119; CHECK-LABEL: @func_res_attr_zeroext
120; CHECK-SAME:  i32 {llvm.zeroext}
121declare zeroext i32 @func_res_attr_zeroext()
122
123; // -----
124
125; CHECK-LABEL: @func_res_attr_align
126; CHECK-SAME:  !llvm.ptr {llvm.align = 16 : i64}
127declare align(16) ptr @func_res_attr_align()
128
129; // -----
130
131; CHECK-LABEL: @func_res_attr_noundef
132; CHECK-SAME:  !llvm.ptr {llvm.noundef}
133declare noundef ptr @func_res_attr_noundef()
134
135; // -----
136
137; CHECK-LABEL: @func_res_attr_dereferenceable
138; CHECK-SAME:  !llvm.ptr {llvm.dereferenceable = 42 : i64}
139declare dereferenceable(42) ptr @func_res_attr_dereferenceable()
140
141; // -----
142
143; CHECK-LABEL: @func_res_attr_dereferenceable_or_null
144; CHECK-SAME:  !llvm.ptr {llvm.dereferenceable_or_null = 42 : i64}
145declare dereferenceable_or_null(42) ptr @func_res_attr_dereferenceable_or_null()
146
147; // -----
148
149; CHECK-LABEL: @func_res_attr_inreg
150; CHECK-SAME:  !llvm.ptr {llvm.inreg}
151declare inreg ptr @func_res_attr_inreg()
152
153; // -----
154
155; CHECK-LABEL: @func_res_attr_range
156; CHECK-SAME:  (i64 {llvm.range = #llvm.constant_range<i64, 0, 4097>})
157declare range(i64 0, 4097) i64 @func_res_attr_range()
158
159; // -----
160
161; CHECK-LABEL: @entry_count
162; CHECK-SAME:  attributes {function_entry_count = 4242 : i64}
163define void @entry_count() !prof !1 {
164  ret void
165}
166
167!1 = !{!"function_entry_count", i64 4242}
168
169; // -----
170
171; CHECK-LABEL: @func_memory
172; CHECK-SAME:  attributes {memory_effects = #llvm.memory_effects<other = readwrite, argMem = none, inaccessibleMem = readwrite>}
173; CHECK:   llvm.return
174define void @func_memory() memory(readwrite, argmem: none) {
175  ret void
176}
177
178; // -----
179
180; CHECK-LABEL: @passthrough_combined
181; CHECK-SAME: attributes {passthrough = [
182; CHECK-DAG: ["alignstack", "16"]
183; CHECK-DAG: "probe-stack"
184; CHECK-DAG: ["alloc-family", "malloc"]
185; CHECK:   llvm.return
186define void @passthrough_combined() alignstack(16) "probe-stack" "alloc-family"="malloc" {
187  ret void
188}
189
190// -----
191
192; CHECK-LABEL: @passthrough_string_only
193; CHECK-SAME: attributes {passthrough = ["no-enum-attr"]}
194; CHECK:   llvm.return
195define void @passthrough_string_only() "no-enum-attr" {
196  ret void
197}
198
199// -----
200
201; CHECK-LABEL: llvm.func hidden @hidden()
202define hidden void @hidden() {
203  ret void
204}
205
206// -----
207
208; CHECK-LABEL: llvm.func protected @protected()
209define protected void @protected() {
210  ret void
211}
212
213// -----
214
215; CHECK-LABEL: @streaming_func
216; CHECK-SAME: attributes {arm_streaming}
217define void @streaming_func() "aarch64_pstate_sm_enabled" {
218  ret void
219}
220
221// -----
222
223; CHECK-LABEL: @locally_streaming_func
224; CHECK-SAME: attributes {arm_locally_streaming}
225define void @locally_streaming_func() "aarch64_pstate_sm_body" {
226  ret void
227}
228
229// -----
230
231; CHECK-LABEL: @streaming_compatible_func
232; CHECK-SAME: attributes {arm_streaming_compatible}
233define void @streaming_compatible_func() "aarch64_pstate_sm_compatible" {
234  ret void
235}
236
237// -----
238
239; CHECK-LABEL: @arm_new_za_func
240; CHECK-SAME: attributes {arm_new_za}
241define void @arm_new_za_func() "aarch64_new_za" {
242  ret void
243}
244
245
246; CHECK-LABEL: @arm_in_za_func
247; CHECK-SAME: attributes {arm_in_za}
248define void @arm_in_za_func() "aarch64_in_za" {
249  ret void
250}
251
252; CHECK-LABEL: @arm_out_za_func
253; CHECK-SAME: attributes {arm_out_za}
254define void @arm_out_za_func() "aarch64_out_za" {
255  ret void
256}
257
258; CHECK-LABEL: @arm_inout_za_func
259; CHECK-SAME: attributes {arm_inout_za}
260define void @arm_inout_za_func() "aarch64_inout_za" {
261  ret void
262}
263
264; CHECK-LABEL: @arm_preserves_za_func
265; CHECK-SAME: attributes {arm_preserves_za}
266define void @arm_preserves_za_func() "aarch64_preserves_za" {
267  ret void
268}
269
270// -----
271
272; CHECK-LABEL: @section_func
273; CHECK-SAME: attributes {section = ".section.name"}
274define void @section_func() section ".section.name" {
275  ret void
276}
277
278// -----
279
280; CHECK-LABEL: local_unnamed_addr @local_unnamed_addr_func
281define void @local_unnamed_addr_func() local_unnamed_addr {
282  ret void
283}
284
285// -----
286
287; CHECK-LABEL: unnamed_addr @unnamed_addr_func
288declare void @unnamed_addr_func() unnamed_addr
289
290// -----
291
292; CHECK-LABEL: @align_func
293; CHECK-SAME: attributes {alignment = 2 : i64}
294define void @align_func() align 2 {
295  ret void
296}
297
298// -----
299
300; CHECK-LABEL: @align_decl
301; CHECK-SAME: attributes {alignment = 64 : i64}
302declare void @align_decl() align 64
303
304; // -----
305
306; CHECK-LABEL: @func_attr_unsafe_fp_math_true
307; CHECK-SAME: attributes {unsafe_fp_math = true}
308declare void @func_attr_unsafe_fp_math_true() "unsafe-fp-math"="true"
309
310; // -----
311
312; CHECK-LABEL: @func_attr_unsafe_fp_math_false
313; CHECK-SAME: attributes {unsafe_fp_math = false}
314declare void @func_attr_unsafe_fp_math_false() "unsafe-fp-math"="false"
315
316; // -----
317
318; CHECK-LABEL: @func_attr_no_infs_fp_math_true
319; CHECK-SAME: attributes {no_infs_fp_math = true}
320declare void @func_attr_no_infs_fp_math_true() "no-infs-fp-math"="true"
321
322; // -----
323
324; CHECK-LABEL: @func_attr_no_infs_fp_math_false
325; CHECK-SAME: attributes {no_infs_fp_math = false}
326declare void @func_attr_no_infs_fp_math_false() "no-infs-fp-math"="false"
327
328; // -----
329
330; CHECK-LABEL: @func_attr_no_nans_fp_math_true
331; CHECK-SAME: attributes {no_nans_fp_math = true}
332declare void @func_attr_no_nans_fp_math_true() "no-nans-fp-math"="true"
333
334; // -----
335
336; CHECK-LABEL: @func_attr_no_nans_fp_math_false
337; CHECK-SAME: attributes {no_nans_fp_math = false}
338declare void @func_attr_no_nans_fp_math_false() "no-nans-fp-math"="false"
339
340; // -----
341
342; CHECK-LABEL: @func_attr_approx_func_fp_math_true
343; CHECK-SAME: attributes {approx_func_fp_math = true}
344declare void @func_attr_approx_func_fp_math_true() "approx-func-fp-math"="true"
345
346; // -----
347
348; CHECK-LABEL: @func_attr_approx_func_fp_math_false
349; CHECK-SAME: attributes {approx_func_fp_math = false}
350declare void @func_attr_approx_func_fp_math_false() "approx-func-fp-math"="false"
351
352; // -----
353
354; CHECK-LABEL: @func_attr_no_signed_zeros_fp_math_true
355; CHECK-SAME: attributes {no_signed_zeros_fp_math = true}
356declare void @func_attr_no_signed_zeros_fp_math_true() "no-signed-zeros-fp-math"="true"
357
358; // -----
359
360; CHECK-LABEL: @func_attr_no_signed_zeros_fp_math_false
361; CHECK-SAME: attributes {no_signed_zeros_fp_math = false}
362declare void @func_attr_no_signed_zeros_fp_math_false() "no-signed-zeros-fp-math"="false"
363
364; // -----
365
366; CHECK-LABEL: @func_attr_denormal_fp_math_ieee
367; CHECK-SAME: attributes {denormal_fp_math = "ieee"}
368declare void @func_attr_denormal_fp_math_ieee() "denormal-fp-math"="ieee"
369
370; // -----
371
372; CHECK-LABEL: @func_attr_denormal_fp_math_f32_preserve_sign
373; CHECK-SAME: attributes {denormal_fp_math_f32 = "preserve-sign"}
374declare void @func_attr_denormal_fp_math_f32_preserve_sign() "denormal-fp-math-f32"="preserve-sign"
375
376; // -----
377
378; CHECK-LABEL: @func_attr_fp_contract_fast
379; CHECK-SAME: attributes {fp_contract = "fast"}
380declare void @func_attr_fp_contract_fast() "fp-contract"="fast"
381
382// -----
383
384; CHECK-LABEL: @noinline_attribute
385; CHECK-SAME: attributes {no_inline}
386declare void @noinline_attribute() noinline
387
388// -----
389
390; CHECK-LABEL: @alwaysinline_attribute
391; CHECK-SAME: attributes {always_inline}
392declare void @alwaysinline_attribute() alwaysinline
393
394// -----
395
396; CHECK-LABEL: @optnone_attribute
397; CHECK-SAME: attributes {no_inline, optimize_none}
398declare void @optnone_attribute() noinline optnone
399
400// -----
401
402; CHECK-LABEL: @convergent_attribute
403; CHECK-SAME: attributes {convergent}
404declare void @convergent_attribute() convergent
405
406// -----
407
408; CHECK-LABEL: @nounwind_attribute
409; CHECK-SAME: attributes {no_unwind}
410declare void @nounwind_attribute() nounwind
411
412// -----
413
414; CHECK-LABEL: @willreturn_attribute
415; CHECK-SAME: attributes {will_return}
416declare void @willreturn_attribute() willreturn
417