xref: /llvm-project/mlir/test/Target/LLVMIR/loop-metadata.mlir (revision b3037ae1fc6d26459e37f813757ad30872eb2eee)
1// RUN: mlir-translate -mlir-to-llvmir -split-input-file %s | FileCheck %s
2
3// CHECK-LABEL: @disableNonForced
4llvm.func @disableNonForced() {
5  // CHECK: br {{.*}} !llvm.loop ![[LOOP_NODE:[0-9]+]]
6  llvm.br ^bb1 {loop_annotation = #llvm.loop_annotation<disableNonforced = true>}
7^bb1:
8  llvm.return
9}
10
11// CHECK: ![[LOOP_NODE]] = distinct !{![[LOOP_NODE]], !{{[0-9]+}}}
12// CHECK-DAG: ![[VEC_NODE0:[0-9]+]] = !{!"llvm.loop.disable_nonforced"}
13
14// -----
15
16// CHECK-LABEL: @mustprogress
17llvm.func @mustprogress() {
18  // CHECK: br {{.*}} !llvm.loop ![[LOOP_NODE:[0-9]+]]
19  llvm.br ^bb1 {loop_annotation = #llvm.loop_annotation<mustProgress = true>}
20^bb1:
21  llvm.return
22}
23
24// CHECK: ![[LOOP_NODE]] = distinct !{![[LOOP_NODE]], !{{[0-9]+}}}
25// CHECK-DAG: ![[VEC_NODE0:[0-9]+]] = !{!"llvm.loop.mustprogress"}
26
27// -----
28
29// CHECK-LABEL: @isvectorized
30llvm.func @isvectorized() {
31  // CHECK: br {{.*}} !llvm.loop ![[LOOP_NODE:[0-9]+]]
32  llvm.br ^bb1 {loop_annotation = #llvm.loop_annotation<isVectorized = true>}
33^bb1:
34  llvm.return
35}
36
37// CHECK: ![[LOOP_NODE]] = distinct !{![[LOOP_NODE]], !{{[0-9]+}}}
38// CHECK-DAG: ![[VEC_NODE0:[0-9]+]] = !{!"llvm.loop.isvectorized", i32 1}
39
40// -----
41
42#followup = #llvm.loop_annotation<disableNonforced = true>
43
44// CHECK-LABEL: @vectorizeOptions
45llvm.func @vectorizeOptions() {
46  // CHECK: br {{.*}} !llvm.loop ![[LOOP_NODE:[0-9]+]]
47  llvm.br ^bb1 {loop_annotation = #llvm.loop_annotation<vectorize = <
48    disable = false, predicateEnable = true, scalableEnable = false, width = 16 : i32,
49    followupVectorized = #followup, followupEpilogue = #followup, followupAll = #followup>
50  >}
51^bb1:
52  llvm.return
53}
54
55// CHECK-DAG: ![[NON_FORCED:[0-9]+]] = !{!"llvm.loop.disable_nonforced"}
56// CHECK-DAG: ![[FOLLOWUP:[0-9]+]] = distinct !{![[FOLLOWUP]], ![[NON_FORCED]]}
57// CHECK-DAG: ![[LOOP_NODE]] = distinct !{![[LOOP_NODE]], !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}}
58// CHECK-DAG: !{{[0-9]+}} = !{!"llvm.loop.vectorize.enable", i1 true}
59// CHECK-DAG: !{{[0-9]+}} = !{!"llvm.loop.vectorize.predicate.enable", i1 true}
60// CHECK-DAG: !{{[0-9]+}} = !{!"llvm.loop.vectorize.scalable.enable", i1 false}
61// CHECK-DAG: !{{[0-9]+}} = !{!"llvm.loop.vectorize.width", i32 16}
62// CHECK-DAG: !{{[0-9]+}} = !{!"llvm.loop.vectorize.followup_vectorized", ![[FOLLOWUP]]}
63// CHECK-DAG: !{{[0-9]+}} = !{!"llvm.loop.vectorize.followup_epilogue", ![[FOLLOWUP]]}
64// CHECK-DAG: !{{[0-9]+}} = !{!"llvm.loop.vectorize.followup_all", ![[FOLLOWUP]]}
65
66// -----
67
68// CHECK-LABEL: @interleaveOptions
69llvm.func @interleaveOptions() {
70  // CHECK: br {{.*}} !llvm.loop ![[LOOP_NODE:[0-9]+]]
71  llvm.br ^bb1 {loop_annotation = #llvm.loop_annotation<interleave = <count = 32 : i32>>}
72^bb1:
73  llvm.return
74}
75
76// CHECK: ![[LOOP_NODE]] = distinct !{![[LOOP_NODE]], ![[INTERLEAVE_NODE:[0-9]+]]}
77// CHECK: ![[INTERLEAVE_NODE]] = !{!"llvm.loop.interleave.count", i32 32}
78
79// -----
80
81#followup = #llvm.loop_annotation<disableNonforced = true>
82
83// CHECK-LABEL: @unrollOptions
84llvm.func @unrollOptions() {
85  // CHECK: br {{.*}} !llvm.loop ![[LOOP_NODE:[0-9]+]]
86  llvm.br ^bb1 {loop_annotation = #llvm.loop_annotation<unroll = <
87    disable = true, count = 64 : i32, runtimeDisable = false, full = false,
88    followupUnrolled = #followup, followupRemainder = #followup, followupAll = #followup>
89  >}
90^bb1:
91  llvm.return
92}
93
94// CHECK-DAG: ![[NON_FORCED:[0-9]+]] = !{!"llvm.loop.disable_nonforced"}
95// CHECK-DAG: ![[FOLLOWUP:[0-9]+]] = distinct !{![[FOLLOWUP]], ![[NON_FORCED]]}
96// CHECK-DAG: ![[LOOP_NODE]] = distinct !{![[LOOP_NODE]], !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}}
97// CHECK-DAG: !{{[0-9]+}} = !{!"llvm.loop.unroll.disable"}
98// CHECK-DAG: !{{[0-9]+}} = !{!"llvm.loop.unroll.count", i32 64}
99// CHECK-DAG: !{{[0-9]+}} = !{!"llvm.loop.unroll.runtime.disable", i1 false}
100// CHECK-DAG: !{{[0-9]+}} = !{!"llvm.loop.unroll.followup_unrolled", ![[FOLLOWUP]]}
101// CHECK-DAG: !{{[0-9]+}} = !{!"llvm.loop.unroll.followup_remainder", ![[FOLLOWUP]]}
102// CHECK-DAG: !{{[0-9]+}} = !{!"llvm.loop.unroll.followup_all", ![[FOLLOWUP]]}
103
104// -----
105
106// CHECK-LABEL: @unrollOptions2
107llvm.func @unrollOptions2() {
108  // CHECK: br {{.*}} !llvm.loop ![[LOOP_NODE:[0-9]+]]
109  llvm.br ^bb1 {loop_annotation = #llvm.loop_annotation<unroll = <disable = false, full = true>>}
110^bb1:
111  llvm.return
112}
113
114// CHECK: ![[LOOP_NODE]] = distinct !{![[LOOP_NODE]], !{{[0-9]+}}, !{{[0-9]+}}}
115// CHECK-DAG: ![[VEC_NODE0:[0-9]+]] = !{!"llvm.loop.unroll.enable"}
116// CHECK-DAG: ![[VEC_NODE2:[0-9]+]] = !{!"llvm.loop.unroll.full"}
117
118// -----
119
120#followup = #llvm.loop_annotation<disableNonforced = true>
121
122// CHECK-LABEL: @unrollAndJamOptions
123llvm.func @unrollAndJamOptions() {
124  // CHECK: br {{.*}} !llvm.loop ![[LOOP_NODE:[0-9]+]]
125  llvm.br ^bb1 {loop_annotation = #llvm.loop_annotation<unrollAndJam = <
126    disable = false, count = 8 : i32, followupOuter = #followup, followupInner = #followup,
127    followupRemainderOuter = #followup, followupRemainderInner = #followup, followupAll = #followup>
128  >}
129^bb1:
130  llvm.return
131}
132
133// CHECK-DAG: ![[NON_FORCED:[0-9]+]] = !{!"llvm.loop.disable_nonforced"}
134// CHECK-DAG: ![[FOLLOWUP:[0-9]+]] = distinct !{![[FOLLOWUP]], ![[NON_FORCED]]}
135// CHECK-DAG: ![[LOOP_NODE]] = distinct !{![[LOOP_NODE]], !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}}
136// CHECK-DAG: !{{[0-9]+}} = !{!"llvm.loop.unroll_and_jam.enable"}
137// CHECK-DAG: !{{[0-9]+}} = !{!"llvm.loop.unroll_and_jam.count", i32 8}
138// CHECK-DAG: !{{[0-9]+}} = !{!"llvm.loop.unroll_and_jam.followup_outer", ![[FOLLOWUP]]}
139// CHECK-DAG: !{{[0-9]+}} = !{!"llvm.loop.unroll_and_jam.followup_inner", ![[FOLLOWUP]]}
140// CHECK-DAG: !{{[0-9]+}} = !{!"llvm.loop.unroll_and_jam.followup_remainder_outer", ![[FOLLOWUP]]}
141// CHECK-DAG: !{{[0-9]+}} = !{!"llvm.loop.unroll_and_jam.followup_remainder_inner", ![[FOLLOWUP]]}
142// CHECK-DAG: !{{[0-9]+}} = !{!"llvm.loop.unroll_and_jam.followup_all", ![[FOLLOWUP]]}
143
144// -----
145
146// CHECK-LABEL: @licmOptions
147llvm.func @licmOptions() {
148  // CHECK: br {{.*}} !llvm.loop ![[LOOP_NODE:[0-9]+]]
149  llvm.br ^bb1 {loop_annotation = #llvm.loop_annotation<licm = <disable = false, versioningDisable = true>>}
150^bb1:
151  llvm.return
152}
153
154// CHECK: ![[LOOP_NODE]] = distinct !{![[LOOP_NODE]], !{{[0-9]+}}}
155// CHECK-DAG: ![[VEC_NODE0:[0-9]+]] = !{!"llvm.loop.licm_versioning.disable"}
156
157// -----
158
159// CHECK-LABEL: @licmOptions2
160llvm.func @licmOptions2() {
161  // CHECK: br {{.*}} !llvm.loop ![[LOOP_NODE:[0-9]+]]
162  llvm.br ^bb1 {loop_annotation = #llvm.loop_annotation<licm = <disable = true, versioningDisable = false>>}
163^bb1:
164  llvm.return
165}
166
167// CHECK: ![[LOOP_NODE]] = distinct !{![[LOOP_NODE]], !{{[0-9]+}}}
168// CHECK-DAG: ![[VEC_NODE0:[0-9]+]] = !{!"llvm.licm.disable"}
169
170// -----
171
172#followup = #llvm.loop_annotation<disableNonforced = true>
173
174// CHECK-LABEL: @distributeOptions
175llvm.func @distributeOptions() {
176  // CHECK: br {{.*}} !llvm.loop ![[LOOP_NODE:[0-9]+]]
177  llvm.br ^bb1 {loop_annotation = #llvm.loop_annotation<distribute = <
178    disable = true, followupCoincident = #followup, followupSequential = #followup,
179    followupFallback = #followup, followupAll = #followup>
180  >}
181^bb1:
182  llvm.return
183}
184
185// CHECK-DAG: ![[NON_FORCED:[0-9]+]] = !{!"llvm.loop.disable_nonforced"}
186// CHECK-DAG: ![[FOLLOWUP:[0-9]+]] = distinct !{![[FOLLOWUP]], ![[NON_FORCED]]}
187// CHECK-DAG: ![[LOOP_NODE]] = distinct !{![[LOOP_NODE]], !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}}
188// CHECK-DAG: !{{[0-9]+}} = !{!"llvm.loop.distribute.enable", i1 false}
189// CHECK-DAG: !{{[0-9]+}} = !{!"llvm.loop.distribute.followup_coincident", ![[FOLLOWUP]]}
190// CHECK-DAG: !{{[0-9]+}} = !{!"llvm.loop.distribute.followup_sequential", ![[FOLLOWUP]]}
191// CHECK-DAG: !{{[0-9]+}} = !{!"llvm.loop.distribute.followup_fallback", ![[FOLLOWUP]]}
192// CHECK-DAG: !{{[0-9]+}} = !{!"llvm.loop.distribute.followup_all", ![[FOLLOWUP]]}
193
194// -----
195
196// CHECK-LABEL: @pipelineOptions
197llvm.func @pipelineOptions() {
198  // CHECK: br {{.*}} !llvm.loop ![[LOOP_NODE:[0-9]+]]
199  llvm.br ^bb1 {loop_annotation = #llvm.loop_annotation<pipeline = <disable = false, initiationinterval = 1 : i32>>}
200^bb1:
201  llvm.return
202}
203
204// CHECK: ![[LOOP_NODE]] = distinct !{![[LOOP_NODE]], !{{[0-9]+}}, !{{[0-9]+}}}
205// CHECK-DAG: ![[VEC_NODE0:[0-9]+]] = !{!"llvm.loop.pipeline.disable", i1 false}
206// CHECK-DAG: ![[VEC_NODE0:[0-9]+]] = !{!"llvm.loop.pipeline.initiationinterval", i32 1}
207
208// -----
209
210// CHECK-LABEL: @peeledOptions
211llvm.func @peeledOptions() {
212  // CHECK: br {{.*}} !llvm.loop ![[LOOP_NODE:[0-9]+]]
213  llvm.br ^bb1 {loop_annotation = #llvm.loop_annotation<peeled = <count = 3 : i32>>}
214^bb1:
215  llvm.return
216}
217
218// CHECK: ![[LOOP_NODE]] = distinct !{![[LOOP_NODE]], !{{[0-9]+}}}
219// CHECK-DAG: ![[VEC_NODE0:[0-9]+]] = !{!"llvm.loop.peeled.count", i32 3}
220
221// -----
222
223// CHECK-LABEL: @unswitchOptions
224llvm.func @unswitchOptions() {
225  // CHECK: br {{.*}} !llvm.loop ![[LOOP_NODE:[0-9]+]]
226  llvm.br ^bb1 {loop_annotation = #llvm.loop_annotation<unswitch = <partialDisable = true>>}
227^bb1:
228  llvm.return
229}
230
231// CHECK: ![[LOOP_NODE]] = distinct !{![[LOOP_NODE]], !{{[0-9]+}}}
232// CHECK-DAG: ![[VEC_NODE0:[0-9]+]] = !{!"llvm.loop.unswitch.partial.disable"}
233
234// -----
235
236llvm.func @foo(%arg0: i32)
237
238#group1 = #llvm.access_group<id = distinct[0]<>>
239#group2 = #llvm.access_group<id = distinct[1]<>>
240
241// CHECK-LABEL: @loopOptions
242llvm.func @loopOptions(%arg1 : i32, %arg2 : i32) {
243    %0 = llvm.mlir.constant(0 : i32) : i32
244    %4 = llvm.alloca %arg1 x i32 : (i32) -> (!llvm.ptr)
245    llvm.br ^bb3(%0 : i32)
246  ^bb3(%1: i32):
247    %2 = llvm.icmp "slt" %1, %arg1 : i32
248    // CHECK: br i1 {{.*}} !llvm.loop ![[LOOP_NODE:[0-9]+]]
249    llvm.cond_br %2, ^bb4, ^bb5 {loop_annotation = #llvm.loop_annotation<
250          licm = <disable = true>,
251          interleave = <count = 1>,
252          unroll = <disable = true>, pipeline = <disable = true, initiationinterval = 2>,
253          parallelAccesses = #group1, #group2>}
254  ^bb4:
255    %3 = llvm.add %1, %arg2  : i32
256    // CHECK: = load i32, ptr %{{.*}} !llvm.access.group ![[ACCESS_GROUPS_NODE:[0-9]+]]
257    %5 = llvm.load %4 {access_groups = [#group1, #group2]} : !llvm.ptr -> i32
258    // CHECK: store i32 %{{.*}}, ptr %{{.*}} !llvm.access.group ![[ACCESS_GROUPS_NODE]]
259    llvm.store %5, %4 {access_groups = [#group1, #group2]} : i32, !llvm.ptr
260    // CHECK: = atomicrmw add ptr %{{.*}}, i32 %{{.*}} !llvm.access.group ![[ACCESS_GROUPS_NODE]]
261    %6 = llvm.atomicrmw add %4, %5 monotonic {access_groups = [#group1, #group2]} : !llvm.ptr, i32
262    // CHECK: = cmpxchg ptr %{{.*}}, i32 %{{.*}}, i32 %{{.*}} !llvm.access.group ![[ACCESS_GROUPS_NODE]]
263    %7 = llvm.cmpxchg %4, %5, %6 acq_rel monotonic {access_groups = [#group1, #group2]} : !llvm.ptr, i32
264    %9 = llvm.mlir.constant(42 : i8) : i8
265    // CHECK: llvm.memcpy{{.*}} !llvm.access.group ![[ACCESS_GROUPS_NODE]]
266    "llvm.intr.memcpy"(%4, %4, %0) <{isVolatile = false}> {access_groups = [#group1, #group2]} : (!llvm.ptr, !llvm.ptr, i32) -> ()
267    // CHECK: llvm.memset{{.*}} !llvm.access.group ![[ACCESS_GROUPS_NODE]]
268    "llvm.intr.memset"(%4, %9, %0) <{isVolatile = false}> {access_groups = [#group1, #group2]} : (!llvm.ptr, i8, i32) -> ()
269    // CHECK: call void @foo({{.*}} !llvm.access.group ![[ACCESS_GROUPS_NODE]]
270    llvm.call @foo(%arg1) {access_groups = [#group1, #group2]} : (i32) -> ()
271    // CHECK: br label {{.*}} !llvm.loop ![[LOOP_NODE]]
272    llvm.br ^bb3(%3 : i32) {loop_annotation = #llvm.loop_annotation<
273          licm = <disable = true>,
274          interleave = <count = 1>,
275          unroll = <disable = true>, pipeline = <disable = true, initiationinterval = 2>,
276          parallelAccesses = #group1, #group2>}
277
278  ^bb5:
279    llvm.return
280}
281
282// CHECK: ![[LOOP_NODE]] = distinct !{![[LOOP_NODE]], !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}}
283// CHECK-DAG: ![[PA_NODE:[0-9]+]] = !{!"llvm.loop.parallel_accesses", ![[GROUP_NODE1:[0-9]+]], ![[GROUP_NODE2:[0-9]+]]}
284// CHECK-DAG: ![[GROUP_NODE1:[0-9]+]] = distinct !{}
285// CHECK-DAG: ![[GROUP_NODE2:[0-9]+]] = distinct !{}
286// CHECK-DAG: ![[UNROLL_DISABLE_NODE:[0-9]+]] = !{!"llvm.loop.unroll.disable"}
287// CHECK-DAG: ![[LICM_DISABLE_NODE:[0-9]+]] = !{!"llvm.licm.disable"}
288// CHECK-DAG: ![[INTERLEAVE_NODE:[0-9]+]] = !{!"llvm.loop.interleave.count", i32 1}
289// CHECK-DAG: ![[PIPELINE_DISABLE_NODE:[0-9]+]] = !{!"llvm.loop.pipeline.disable", i1 true}
290// CHECK-DAG: ![[II_NODE:[0-9]+]] = !{!"llvm.loop.pipeline.initiationinterval", i32 2}
291// CHECK-DAG: ![[ACCESS_GROUPS_NODE:[0-9]+]] = !{![[GROUP_NODE1]], ![[GROUP_NODE2]]}
292
293// -----
294
295#di_file = #llvm.di_file<"metadata-loop.ll" in "/">
296
297#loc1 = loc("loop-metadata.mlir":42:4)
298#loc2 = loc("loop-metadata.mlir":52:4)
299
300#di_compile_unit = #llvm.di_compile_unit<id = distinct[0]<>, sourceLanguage = DW_LANG_C, file = #di_file, isOptimized = false, emissionKind = None>
301#di_subprogram = #llvm.di_subprogram<compileUnit = #di_compile_unit, scope = #di_file, name = "loop_locs", file = #di_file, subprogramFlags = Definition>
302
303#start_loc_fused = loc(fused<#di_subprogram>[#loc1])
304#end_loc_fused= loc(fused<#di_subprogram>[#loc2])
305
306#loopMD = #llvm.loop_annotation<disableNonforced = false,
307        startLoc = #start_loc_fused,
308        endLoc = #end_loc_fused>
309
310// CHECK-LABEL: @loop_annotation_with_locs
311llvm.func @loop_annotation_with_locs() {
312// CHECK: br {{.*}} !llvm.loop ![[LOOP_NODE:[0-9]+]]
313  llvm.br ^bb1 {loop_annotation = #loopMD}
314^bb1:
315  llvm.return
316}
317
318// CHECK: ![[LOOP_NODE]] = distinct !{![[LOOP_NODE]], ![[START_LOC:.*]], ![[END_LOC:.*]]}
319// CHECK: ![[START_LOC]] = !DILocation(line: 42, column: 4, scope:
320// CHECK: ![[END_LOC]] = !DILocation(line: 52, column: 4, scope:
321