[clang] StmtPrinter: Handle DeclRefExpr to a Decomposition (#125001)
[llvm-project.git] / llvm / test / DebugInfo / WebAssembly / dbg-value-reg-stackify.mir
blob230ba1228e1b08b4e2d57a392ab5e004d895f8be
1 # RUN: llc -run-pass wasm-reg-stackify %s -o - | FileCheck %s
3 # Tests for DBG_VALUE hanlding in RegStackify + DebugValueManager
5 --- |
6   target triple = "wasm32-unknown-unknown"
8   declare void @use(i32)
9   declare void @use_2(i32, i32)
11   define void @sink_simple() !dbg !6 {
12     call void @llvm.dbg.value(metadata i32 0, metadata !5, metadata !DIExpression()), !dbg !10
13     call void @llvm.dbg.value(metadata i32 0, metadata !11, metadata !DIExpression()), !dbg !10
14     call void @llvm.dbg.value(metadata i32 0, metadata !12, metadata !DIExpression()), !dbg !10
15     call void @llvm.dbg.value(metadata i32 0, metadata !13, metadata !DIExpression()), !dbg !10
16     ret void
17   }
18   define void @sink_non_consecutive() !dbg !14 {
19     unreachable
20   }
21   define void @dont_sink_above_def() !dbg !15 {
22     unreachable
23   }
24   define void @sink_to_same_place() !dbg !16 {
25     unreachable
26   }
27   define void @cannot_sink_across_same_variable() !dbg !17 {
28     unreachable
29   }
30   define void @cannot_sink_across_same_variable2() !dbg !18 {
31     unreachable
32   }
33   define void @can_sink_across_same_variable_with_same_const() !dbg !19 {
34     unreachable
35   }
36   define void @sink_multiple_defs() !dbg !20 {
37     unreachable
38   }
39   define void @clone_same_bb() !dbg !21 {
40     unreachable
41   }
42   define void @clone_different_bb() !dbg !22 {
43     unreachable
44   }
45   define void @tee_with_two_use_insts() !dbg !23 {
46     unreachable
47   }
48   define void @tee_with_one_inst_with_two_uses() !dbg !24 {
49     unreachable
50   }
51   declare void @llvm.dbg.value(metadata, metadata, metadata)
53   !llvm.dbg.cu = !{!0}
54   !llvm.module.flags = !{!2, !3, !4}
56   ; Note the current mapping variable metadata and their names, which we will
57   ; use in all functions in ths file:
58   ; - "var_a" / VAR_A: !5
59   ; - "var_b" / VAR_B: !11
60   ; - "var_c" / VAR_C: !12
61   ; - "var_d" / VAR_D: !13
62   ; We will use VAR_? in the CHECK lines for robustness in case of metadata
63   ; renumbering, but currently in mir tests we cannot use variable names like
64   ; "var_a" directly in the input, which can be confusing to read.
66   !0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, emissionKind: FullDebug)
67   !1 = !DIFile(filename: "test.c", directory: "")
68   !2 = !{i32 7, !"Dwarf Version", i32 5}
69   !3 = !{i32 2, !"Debug Info Version", i32 3}
70   !4 = !{i32 1, !"wchar_size", i32 4}
71   !5 = !DILocalVariable(name: "var_a", scope: !6, file: !1, line: 2, type: !9)
72   ; CHECK: ![[VAR_A:[0-9]+]] = !DILocalVariable(name: "var_a"
73   !6 = distinct !DISubprogram(name: "sink_simple", scope: !1, file: !1, line: 1, type: !7, scopeLine: 1, unit: !0)
74   !7 = !DISubroutineType(types: !8)
75   !8 = !{null}
76   !9 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
77   !10 = !DILocation(line: 0, scope: !6)
78   !11 = !DILocalVariable(name: "var_b", scope: !6, file: !1, line: 2, type: !9)
79   ; CHECK: ![[VAR_B:[0-9]+]] = !DILocalVariable(name: "var_b"
80   !12 = !DILocalVariable(name: "var_c", scope: !6, file: !1, line: 2, type: !9)
81   ; CHECK: ![[VAR_C:[0-9]+]] = !DILocalVariable(name: "var_c"
82   !13 = !DILocalVariable(name: "var_d", scope: !6, file: !1, line: 2, type: !9)
83   ; CHECK: ![[VAR_D:[0-9]+]] = !DILocalVariable(name: "var_d"
84   !14 = distinct !DISubprogram(name: "sink_non_consecutive", scope: !1, file: !1, line: 1, type: !7, scopeLine: 1, unit: !0)
85   !15 = distinct !DISubprogram(name: "dont_sink_above_def", scope: !1, file: !1, line: 1, type: !7, scopeLine: 1, unit: !0)
86   !16 = distinct !DISubprogram(name: "sink_to_same_place", scope: !1, file: !1, line: 1, type: !7, scopeLine: 1, unit: !0)
87   !17 = distinct !DISubprogram(name: "cannot_sink_across_same_variable", scope: !1, file: !1, line: 1, type: !7, scopeLine: 1, unit: !0)
88   !18 = distinct !DISubprogram(name: "cannot_sink_across_same_variable2", scope: !1, file: !1, line: 1, type: !7, scopeLine: 1, unit: !0)
89   !19 = distinct !DISubprogram(name: "can_sink_across_same_variable_with_same_const", scope: !1, file: !1, line: 1, type: !7, scopeLine: 1, unit: !0)
90   !20 = distinct !DISubprogram(name: "sink_multiple_defs", scope: !1, file: !1, line: 1, type: !7, scopeLine: 1, unit: !0)
91   !21 = distinct !DISubprogram(name: "clone_same_bb", scope: !1, file: !1, line: 1, type: !7, scopeLine: 1, unit: !0)
92   !22 = distinct !DISubprogram(name: "clone_different_bb", scope: !1, file: !1, line: 1, type: !7, scopeLine: 1, unit: !0)
93   !23 = distinct !DISubprogram(name: "tee_with_two_use_insts", scope: !1, file: !1, line: 1, type: !7, scopeLine: 1, unit: !0)
94   !24 = distinct !DISubprogram(name: "tee_with_one_inst_with_two_uses", scope: !1, file: !1, line: 1, type: !7, scopeLine: 1, unit: !0)
95 ...
97 ---
98 # A simple sinking example.
99 # '%0 = CONST_I32 1' will sink to the place before 'CALL %use', and the two
100 # DBG_VALUEs will sink with it, leaving the original DBG_VALUEs to be set to
101 # undef (= DBG_VALUE $noreg).
102 # CHECK-LABEL: name: sink_simple
103 name: sink_simple
104 liveins:
105   - { reg: '$arguments' }
106 tracksRegLiveness: true
107 body: |
108   bb.0:
109     liveins: $arguments
110     %0:i32 = CONST_I32 1, implicit-def $arguments
111     DBG_VALUE %0:i32, $noreg, !5, !DIExpression(), debug-location !10
112     DBG_VALUE %0:i32, $noreg, !11, !DIExpression(), debug-location !10
113     NOP implicit-def $arguments
114     CALL @use, %0:i32, implicit-def $arguments
115     RETURN implicit-def $arguments
117   ; CHECK:      DBG_VALUE $noreg, $noreg, ![[VAR_A]], !DIExpression()
118   ; CHECK-NEXT: DBG_VALUE $noreg, $noreg, ![[VAR_B]], !DIExpression()
119   ; CHECK-NEXT: NOP implicit-def $arguments
120   ; CHECK-NEXT: %0:i32 = CONST_I32 1, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack
121   ; CHECK-NEXT: DBG_VALUE %0, $noreg, ![[VAR_A]], !DIExpression()
122   ; CHECK-NEXT: DBG_VALUE %0, $noreg, ![[VAR_B]], !DIExpression()
123   ; CHECK-NEXT: CALL @use, %0, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack
124   ; CHECK-NEXT: RETURN implicit-def $arguments
128 # Sinking when DBG_VALUEs are non-consecutive.
129 # '%0 = CONST_I32 1' will sink to the place before 'CALL %use', and the two
130 # DBG_VALUEs will sink with it, even though they are not consecutive. The
131 # original DBG_VALUEs will be set to undef.
132 # CHECK-LABEL: name: sink_non_consecutive
133 name: sink_non_consecutive
134 liveins:
135   - { reg: '$arguments' }
136 tracksRegLiveness: true
137 body: |
138   bb.0:
139     liveins: $arguments
140     %0:i32 = CONST_I32 1, implicit-def $arguments
141     DBG_VALUE %0:i32, $noreg, !5, !DIExpression(), debug-location !10
142     NOP implicit-def $arguments
143     DBG_VALUE %0:i32, $noreg, !11, !DIExpression(), debug-location !10
144     NOP implicit-def $arguments
145     CALL @use, %0:i32, implicit-def $arguments
146     RETURN implicit-def $arguments
148   ; CHECK:      DBG_VALUE $noreg, $noreg, ![[VAR_A]], !DIExpression()
149   ; CHECK-NEXT: NOP implicit-def $arguments
150   ; CHECK-NEXT: DBG_VALUE $noreg, $noreg, ![[VAR_B]], !DIExpression()
151   ; CHECK-NEXT: NOP implicit-def $arguments
152   ; CHECK-NEXT: %0:i32 = CONST_I32 1, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack
153   ; CHECK-NEXT: DBG_VALUE %0, $noreg, ![[VAR_A]], !DIExpression()
154   ; CHECK-NEXT: DBG_VALUE %0, $noreg, ![[VAR_B]], !DIExpression()
155   ; CHECK-NEXT: CALL @use, %0, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack
156   ; CHECK-NEXT: RETURN implicit-def $arguments
160 # Only DBG_VALUEs following a def should be sunk together.
161 # '%0 = CONST_I32 1' will sink to the place before 'CALL %use', but the
162 # DBG_VALUE above it should be untouched.
163 # CHECK-LABEL: name: dont_sink_above_def
164 name: dont_sink_above_def
165 liveins:
166   - { reg: '$arguments' }
167 tracksRegLiveness: true
168 body: |
169   bb.0:
170     liveins: $arguments
171     DBG_VALUE %0:i32, $noreg, !5, !DIExpression(), debug-location !10
172     %0:i32 = CONST_I32 1, implicit-def $arguments
173     NOP implicit-def $arguments
174     CALL @use, %0:i32, implicit-def $arguments
175     RETURN implicit-def $arguments
177   ; CHECK:      DBG_VALUE %0, $noreg, ![[VAR_A]], !DIExpression()
178   ; CHECK-NEXT: NOP implicit-def $arguments
179   ; CHECK-NEXT: %0:i32 = CONST_I32 1, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack
180   ; CHECK-NEXT: CALL @use, %0, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack
181   ; CHECK-NEXT: RETURN implicit-def $arguments
185 # A sink no-op case.
186 # '%0 = CONST_I32 1' will sink to the place before 'CALL %use', but it's already
187 # right before the CALL so it should be effectively a no-op. But currently
188 # sinking happens anyway so this will create unnecessary two undef DBG_VALUEs.
189 # This increases the number of DBG_VALUEs but doesn't hurt the coverage or
190 # generate incorrect debug info. TODO Improve this?
191 # CHECK-LABEL: name: sink_to_same_place
192 name: sink_to_same_place
193 liveins:
194   - { reg: '$arguments' }
195 tracksRegLiveness: true
196 body: |
197   bb.0:
198     liveins: $arguments
199     %0:i32 = CONST_I32 1, implicit-def $arguments
200     DBG_VALUE %0:i32, $noreg, !5, !DIExpression(), debug-location !10
201     DBG_VALUE %0:i32, $noreg, !11, !DIExpression(), debug-location !10
202     CALL @use, %0:i32, implicit-def $arguments
203     RETURN implicit-def $arguments
205   ; CHECK:      %0:i32 = CONST_I32 1, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack
206   ; CHECK-NEXT: DBG_VALUE %0, $noreg, ![[VAR_A]], !DIExpression()
207   ; CHECK-NEXT: DBG_VALUE %0, $noreg, ![[VAR_B]], !DIExpression()
208   ; CHECK-NEXT: CALL @use, %0, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack
209   ; CHECK-NEXT: RETURN implicit-def $arguments
213 # A DBG_VALUE cannot be sunk across another DBG_VALUE that has the same
214 # DebugVariable, because it will reorder assignments.
215 # '%0 = CONST_I32 1' will sink to the place before 'CALL %use'. But from the two
216 # DBG_VALUEs following it, only the DBG_VALUE for "var_b" can sink with it,
217 # because there is another 'DBG_VALUE 10' for "var_a" in the middle.
218 # CHECK-LABEL: name: cannot_sink_across_same_variable
219 name: cannot_sink_across_same_variable
220 liveins:
221   - { reg: '$arguments' }
222 tracksRegLiveness: true
223 body: |
224   bb.0:
225     liveins: $arguments
226     %0:i32 = CONST_I32 1, implicit-def $arguments
227     DBG_VALUE %0:i32, $noreg, !5, !DIExpression(), debug-location !10
228     DBG_VALUE %0:i32, $noreg, !11, !DIExpression(), debug-location !10
229     DBG_VALUE 10, $noreg, !5, !DIExpression(), debug-location !10
230     NOP implicit-def $arguments
231     CALL @use, %0:i32, implicit-def $arguments
232     RETURN implicit-def $arguments
234   ; CHECK:      DBG_VALUE $noreg, $noreg, ![[VAR_A]], !DIExpression()
235   ; CHECK-NEXT: DBG_VALUE $noreg, $noreg, ![[VAR_B]], !DIExpression()
236   ; CHECK-NEXT: DBG_VALUE 10, $noreg, ![[VAR_A]], !DIExpression()
237   ; CHECK-NEXT: NOP implicit-def $arguments
238   ; CHECK-NEXT: %0:i32 = CONST_I32 1, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack
239   ; CHECK-NEXT: DBG_VALUE %0, $noreg, ![[VAR_B]], !DIExpression()
240   ; CHECK-NEXT: CALL @use, %0, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack
241   ; CHECK-NEXT: RETURN implicit-def $arguments
245 # Another case in which a DBG_VALUE cannot be sunk across another DBG_VALUE with
246 # the same DebugVariable, because it will reorder assignments.
247 # '%0 = CONST_I32 1' will sink to the place before 'CALL %use'. But from the two
248 # DBG_VALUEs following it, only the DBG_VALUE for "var_b" can sink with it,
249 # because there is another 'DBG_VALUE %1, "var_a"' in the middle.
250 # CHECK-LABEL: name: cannot_sink_across_same_variable2
251 name: cannot_sink_across_same_variable2
252 liveins:
253   - { reg: '$arguments' }
254 tracksRegLiveness: true
255 body: |
256   bb.0:
257     liveins: $arguments
258     %0:i32 = CONST_I32 1, implicit-def $arguments
259     %1:i32 = CONST_I32 2, implicit-def $arguments
260     DBG_VALUE %0:i32, $noreg, !5, !DIExpression(), debug-location !10
261     DBG_VALUE %0:i32, $noreg, !11, !DIExpression(), debug-location !10
262     DBG_VALUE %1:i32, $noreg, !5, !DIExpression(), debug-location !10
263     NOP implicit-def $arguments
264     CALL @use, %0:i32, implicit-def $arguments
265     RETURN implicit-def $arguments
267   ; CHECK:      %1:i32 = CONST_I32 2, implicit-def $arguments
268   ; CHECK-NEXT: DBG_VALUE $noreg, $noreg, ![[VAR_A]], !DIExpression()
269   ; CHECK-NEXT: DBG_VALUE $noreg, $noreg, ![[VAR_B]], !DIExpression()
270   ; CHECK-NEXT: DBG_VALUE %1, $noreg, ![[VAR_A]], !DIExpression()
271   ; CHECK-NEXT: NOP implicit-def $arguments
272   ; CHECK-NEXT: %0:i32 = CONST_I32 1, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack
273   ; CHECK-NEXT: DBG_VALUE %0, $noreg, ![[VAR_B]], !DIExpression()
274   ; CHECK-NEXT: CALL @use, %0, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack
275   ; CHECK-NEXT: RETURN implicit-def $arguments
279 # There is a exception in which a DBG_VALUE can be sunk across another DBG_VALUE
280 # with the same DebugVariable: when the interfering DBG_VALUE refers to the same
281 # CONST_[I32/I64/F32/F64] instruction, in which case we don't reorder
282 # assignments.
284 # This is the same test with the previous one with one difference: %1 has the
285 # same CONST instruction with %0 'CONST_I32 1'. We can sink the DBG_VALUE for
286 # "var_a" here as well.
287 # CHECK-LABEL: name: can_sink_across_same_variable_with_same_const
288 name: can_sink_across_same_variable_with_same_const
289 liveins:
290   - { reg: '$arguments' }
291 tracksRegLiveness: true
292 body: |
293   bb.0:
294     liveins: $arguments
295     %0:i32 = CONST_I32 1, implicit-def $arguments
296     %1:i32 = CONST_I32 1, implicit-def $arguments ; Same CONST_I32
297     DBG_VALUE %0:i32, $noreg, !5, !DIExpression(), debug-location !10
298     DBG_VALUE %0:i32, $noreg, !11, !DIExpression(), debug-location !10
299     DBG_VALUE %1:i32, $noreg, !5, !DIExpression(), debug-location !10
300     NOP implicit-def $arguments
301     CALL @use, %0:i32, implicit-def $arguments
302     RETURN implicit-def $arguments
304   ; CHECK:      %1:i32 = CONST_I32 1, implicit-def $arguments
305   ; CHECK-NEXT: DBG_VALUE $noreg, $noreg, ![[VAR_A]], !DIExpression()
306   ; CHECK-NEXT: DBG_VALUE $noreg, $noreg, ![[VAR_B]], !DIExpression()
307   ; CHECK-NEXT: DBG_VALUE %1, $noreg, ![[VAR_A]], !DIExpression()
308   ; CHECK-NEXT: NOP implicit-def $arguments
309   ; CHECK-NEXT: %0:i32 = CONST_I32 1, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack
310   ; CHECK-NEXT: DBG_VALUE %0, $noreg, ![[VAR_A]], !DIExpression()
311   ; CHECK-NEXT: DBG_VALUE %0, $noreg, ![[VAR_B]], !DIExpression()
312   ; CHECK-NEXT: CALL @use, %0, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack
313   ; CHECK-NEXT: RETURN implicit-def $arguments
317 # Both %0 and %1 will be sunk to the place before ADD_I32. DBG_VALUEs associated
318 # with those two defs will be sunk as well, leaving the original DBG_VALUEs set
319 # to undef.
320 # CHECK-LABEL: name: sink_multiple_defs
321 name: sink_multiple_defs
322 liveins:
323   - { reg: '$arguments' }
324 tracksRegLiveness: true
325 body: |
326   bb.0:
327     liveins: $arguments
328     %0:i32 = CONST_I32 1, implicit-def $arguments
329     DBG_VALUE %0:i32, $noreg, !5, !DIExpression(), debug-location !10
330     DBG_VALUE %0:i32, $noreg, !11, !DIExpression(), debug-location !10
331     NOP implicit-def $arguments
332     %1:i32 = CONST_I32 2, implicit-def $arguments
333     DBG_VALUE %1:i32, $noreg, !12, !DIExpression(), debug-location !10
334     DBG_VALUE %1:i32, $noreg, !13, !DIExpression(), debug-location !10
335     NOP implicit-def $arguments
336     %2:i32 = ADD_I32 %0:i32, %1:i32, implicit-def $arguments
337     RETURN implicit-def $arguments
339   ; CHECK:      DBG_VALUE $noreg, $noreg, ![[VAR_A]], !DIExpression()
340   ; CHECK-NEXT: DBG_VALUE $noreg, $noreg, ![[VAR_B]], !DIExpression()
341   ; CHECK-NEXT: NOP implicit-def $arguments
342   ; CHECK-NEXT: DBG_VALUE $noreg, $noreg, ![[VAR_C]], !DIExpression()
343   ; CHECK-NEXT: DBG_VALUE $noreg, $noreg, ![[VAR_D]], !DIExpression()
344   ; CHECK-NEXT: NOP implicit-def $arguments
345   ; CHECK-NEXT: %0:i32 = CONST_I32 1, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack
346   ; CHECK-NEXT: DBG_VALUE %0, $noreg, ![[VAR_A]], !DIExpression()
347   ; CHECK-NEXT: DBG_VALUE %0, $noreg, ![[VAR_B]], !DIExpression()
348   ; CHECK-NEXT: %1:i32 = CONST_I32 2, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack
349   ; CHECK-NEXT: DBG_VALUE %1, $noreg, ![[VAR_C]], !DIExpression()
350   ; CHECK-NEXT: DBG_VALUE %1, $noreg, ![[VAR_D]], !DIExpression()
351   ; CHECK-NEXT: dead %2:i32 = ADD_I32 %0, %1, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack
352   ; CHECK-NEXT: RETURN implicit-def $arguments
356 # A simple cloning example.
357 # When processing the second 'CALL @use', because %0 has multiple uses, the def
358 # '%0 = CONST_I32 1' is cloned before the CALL, along with its DBG_VALUEs. And
359 # then when processing the first 'CALL @use', by that time %0 has only one use
360 # remaining, so it is just sink with the DBG_VALUEs, leaving the original
361 # DBG_VALUEs undef.
362 # CHECK-LABEL: name: clone_same_bb
363 name: clone_same_bb
364 liveins:
365   - { reg: '$arguments' }
366 tracksRegLiveness: true
367 body: |
368   bb.0:
369     liveins: $arguments
370     %0:i32 = CONST_I32 1, implicit-def $arguments
371     DBG_VALUE %0:i32, $noreg, !5, !DIExpression(), debug-location !10
372     DBG_VALUE %0:i32, $noreg, !11, !DIExpression(), debug-location !10
373     NOP implicit-def $arguments
374     CALL @use, %0:i32, implicit-def $arguments
375     CALL @use, %0:i32, implicit-def $arguments
376     RETURN implicit-def $arguments
378   ; CHECK:      DBG_VALUE $noreg, $noreg, ![[VAR_A]], !DIExpression()
379   ; CHECK-NEXT: DBG_VALUE $noreg, $noreg, ![[VAR_B]], !DIExpression()
380   ; CHECK-NEXT: NOP implicit-def $arguments
381   ; CHECK-NEXT: %0:i32 = CONST_I32 1, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack
382   ; CHECK-NEXT: DBG_VALUE %0, $noreg, ![[VAR_A]], !DIExpression()
383   ; CHECK-NEXT: DBG_VALUE %0, $noreg, ![[VAR_B]], !DIExpression()
384   ; CHECK-NEXT: CALL @use, %0, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack
385   ; CHECK-NEXT: %1:i32 = CONST_I32 1, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack
386   ; CHECK-NEXT: DBG_VALUE %1, $noreg, ![[VAR_A]], !DIExpression()
387   ; CHECK-NEXT: DBG_VALUE %1, $noreg, ![[VAR_B]], !DIExpression()
388   ; CHECK-NEXT: CALL @use, %1, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack
389   ; CHECK-NEXT: RETURN implicit-def $arguments
393 # Cloning across different BBs.
394 # First, when bb.0's 'CALL @use' is procssed, '%0 = CONST_I32 1' and its
395 # DBG_VALUEs are cloned before the CALL. And when bb.1's 'CALL @use' is
396 # processed, '%0 = CONST_I32 1' and its DBG_VALUEs are cloned to bb.1 this time.
397 # Even though there are (previously cloned) DBG_VALUEs for "var_a" and "var_b"
398 # in the middle, it's fine because they point to the same 'CONST_I32 1'
399 # instruction.
400 # After the second cloning, the original '%0 = CONST_I32 1' is removed because
401 # it doesn't have any users anymore, leaving its original DBG_VALUEs as undef.
402 # CHECK-LABEL: name: clone_different_bb
403 name: clone_different_bb
404 liveins:
405   - { reg: '$arguments' }
406 tracksRegLiveness: true
407 body: |
408   bb.0:
409     successors: %bb.1
410     liveins: $arguments
411     %0:i32 = CONST_I32 1, implicit-def $arguments
412     DBG_VALUE %0:i32, $noreg, !5, !DIExpression(), debug-location !10
413     DBG_VALUE %0:i32, $noreg, !11, !DIExpression(), debug-location !10
414     NOP implicit-def $arguments
415     CALL @use, %0:i32, implicit-def $arguments
416     BR %bb.1, implicit-def $arguments
418   ; CHECK:    bb.0:
419   ; CHECK:      DBG_VALUE $noreg, $noreg, ![[VAR_A]], !DIExpression()
420   ; CHECK-NEXT: DBG_VALUE $noreg, $noreg, ![[VAR_B]], !DIExpression()
421   ; CHECK-NEXT: NOP implicit-def $arguments
422   ; CHECK-NEXT: %1:i32 = CONST_I32 1, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack
423   ; CHECK-NEXT: DBG_VALUE %1, $noreg, ![[VAR_A]], !DIExpression()
424   ; CHECK-NEXT: DBG_VALUE %1, $noreg, ![[VAR_B]], !DIExpression()
425   ; CHECK-NEXT: CALL @use, %1, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack
426   ; CHECK-NEXT: BR %bb.1, implicit-def $arguments
428   bb.1:
429   ; predecessors: %bb.0
430     CALL @use, %0:i32, implicit-def $arguments
431     RETURN implicit-def $arguments
433   ; CHECK:    bb.1:
434   ; CHECK:      %2:i32 = CONST_I32 1, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack
435   ; CHECK-NEXT: DBG_VALUE %2, $noreg, ![[VAR_A]], !DIExpression()
436   ; CHECK-NEXT: DBG_VALUE %2, $noreg, ![[VAR_B]], !DIExpression()
437   ; CHECK-NEXT: CALL @use, %2, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack
438   ; CHECK-NEXT: RETURN implicit-def $arguments
442 # TEE conversion example.
443 # Convert this form:
444 #   Reg = INST ...        // Def
445 #   DBG_VALUE Reg, ...
446 #   INST ..., Reg, ...    // Insert
447 #   INST ..., Reg, ...
448 # to
449 #   DefReg = INST ...     // Def (to become the new Insert)
450 #   DBG_VALUE DefReg, ...
451 #   TeeReg, Reg = TEE_... DefReg
452 #   DBG_VALUE TeeReg, ...
453 #   INST ..., TeeReg, ... // Insert
454 #   INST ..., Reg, ...
455 # CHECK-LABEL: name: tee_with_two_use_insts
456 name: tee_with_two_use_insts
457 liveins:
458   - { reg: '$arguments' }
459 tracksRegLiveness: true
460 body: |
461   bb.0:
462     liveins: $arguments
463     %0:i32 = ARGUMENT_i32 0, implicit $arguments
464     %1:i32 = ARGUMENT_i32 1, implicit $arguments
465     %2:i32 = MUL_I32 %1:i32, %0:i32, implicit-def $arguments
466     DBG_VALUE %2:i32, $noreg, !5, !DIExpression(), debug-location !10
467     DBG_VALUE %2:i32, $noreg, !11, !DIExpression(), debug-location !10
468     NOP implicit-def $arguments
469     CALL @use, %2:i32, implicit-def $arguments
470     CALL @use, %2:i32, implicit-def $arguments
471     RETURN implicit-def $arguments
473   ; CHECK:      %0:i32 = ARGUMENT_i32 0, implicit $arguments
474   ; CHECK-NEXT: %1:i32 = ARGUMENT_i32 1, implicit $arguments
475   ; CHECK-NEXT: DBG_VALUE $noreg, $noreg, ![[VAR_A]], !DIExpression()
476   ; CHECK-NEXT: DBG_VALUE $noreg, $noreg, ![[VAR_B]], !DIExpression()
477   ; CHECK-NEXT: NOP implicit-def $arguments
478   ; CHECK-NEXT: %4:i32 = MUL_I32 %1, %0, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack
479   ; CHECK-NEXT: DBG_VALUE %4, $noreg, ![[VAR_A]], !DIExpression()
480   ; CHECK-NEXT: DBG_VALUE %4, $noreg, ![[VAR_B]], !DIExpression()
481   ; CHECK-NEXT: %3:i32, %2:i32 = TEE_I32 %4, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack
482   ; CHECK-NEXT: DBG_VALUE %3, $noreg, ![[VAR_A]], !DIExpression()
483   ; CHECK-NEXT: DBG_VALUE %3, $noreg, ![[VAR_B]], !DIExpression()
484   ; CHECK-NEXT: CALL @use, %3, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack
485   ; CHECK-NEXT: CALL @use, %2, implicit-def $arguments
486   ; CHECK-NEXT: RETURN implicit-def $arguments
490 # Another TEE conversion example. The previous example had two instructions
491 # that use a single register, whereas this has one instructions that has two
492 # same use operands. The resulting transformation is the same.
493 # CHECK-LABEL: name: tee_with_one_inst_with_two_uses
494 name: tee_with_one_inst_with_two_uses
495 liveins:
496   - { reg: '$arguments' }
497 tracksRegLiveness: true
498 body: |
499   bb.0:
500     liveins: $arguments
501     %0:i32 = ARGUMENT_i32 0, implicit $arguments
502     %1:i32 = ARGUMENT_i32 1, implicit $arguments
503     %2:i32 = MUL_I32 %1:i32, %0:i32, implicit-def $arguments
504     DBG_VALUE %2:i32, $noreg, !5, !DIExpression(), debug-location !10
505     DBG_VALUE %2:i32, $noreg, !11, !DIExpression(), debug-location !10
506     NOP implicit-def $arguments
507     CALL @use_2, %2:i32, %2:i32, implicit-def $arguments
508     RETURN implicit-def $arguments
510   ; CHECK:      %0:i32 = ARGUMENT_i32 0, implicit $arguments
511   ; CHECK-NEXT: %1:i32 = ARGUMENT_i32 1, implicit $arguments
512   ; CHECK-NEXT: DBG_VALUE $noreg, $noreg, ![[VAR_A]], !DIExpression()
513   ; CHECK-NEXT: DBG_VALUE $noreg, $noreg, ![[VAR_B]], !DIExpression()
514   ; CHECK-NEXT: NOP implicit-def $arguments
515   ; CHECK-NEXT: %4:i32 = MUL_I32 %1, %0, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack
516   ; CHECK-NEXT: DBG_VALUE %4, $noreg, ![[VAR_A]], !DIExpression()
517   ; CHECK-NEXT: DBG_VALUE %4, $noreg, ![[VAR_B]], !DIExpression()
518   ; CHECK-NEXT: %3:i32, %2:i32 = TEE_I32 %4, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack
519   ; CHECK-NEXT: DBG_VALUE %3, $noreg, ![[VAR_A]], !DIExpression()
520   ; CHECK-NEXT: DBG_VALUE %3, $noreg, ![[VAR_B]], !DIExpression()
521   ; CHECK-NEXT: CALL @use_2, %3, %2, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack
522   ; CHECK-NEXT: RETURN implicit-def $arguments