xref: /llvm-project/llvm/test/DebugInfo/WebAssembly/dbg-value-reg-stackify.mir (revision d871f40deb7a7e6286b6d6b4476f6d30e444075e)
1# RUN: llc -run-pass wasm-reg-stackify %s -o - | FileCheck %s
2
3# Tests for DBG_VALUE hanlding in RegStackify + DebugValueManager
4
5--- |
6  target triple = "wasm32-unknown-unknown"
7
8  declare void @use(i32)
9  declare void @use_2(i32, i32)
10
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)
52
53  !llvm.dbg.cu = !{!0}
54  !llvm.module.flags = !{!2, !3, !4}
55
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.
65
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...
96
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
103name: sink_simple
104liveins:
105  - { reg: '$arguments' }
106tracksRegLiveness: true
107body: |
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
116
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
125...
126
127---
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
133name: sink_non_consecutive
134liveins:
135  - { reg: '$arguments' }
136tracksRegLiveness: true
137body: |
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
147
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
157...
158
159---
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
164name: dont_sink_above_def
165liveins:
166  - { reg: '$arguments' }
167tracksRegLiveness: true
168body: |
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
176
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
182...
183
184---
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
192name: sink_to_same_place
193liveins:
194  - { reg: '$arguments' }
195tracksRegLiveness: true
196body: |
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
204
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
210...
211
212---
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
219name: cannot_sink_across_same_variable
220liveins:
221  - { reg: '$arguments' }
222tracksRegLiveness: true
223body: |
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
233
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
242...
243
244---
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
251name: cannot_sink_across_same_variable2
252liveins:
253  - { reg: '$arguments' }
254tracksRegLiveness: true
255body: |
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
266
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
276...
277
278---
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.
283#
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
288name: can_sink_across_same_variable_with_same_const
289liveins:
290  - { reg: '$arguments' }
291tracksRegLiveness: true
292body: |
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
303
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
314...
315
316---
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
321name: sink_multiple_defs
322liveins:
323  - { reg: '$arguments' }
324tracksRegLiveness: true
325body: |
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
338
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
353...
354
355---
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
363name: clone_same_bb
364liveins:
365  - { reg: '$arguments' }
366tracksRegLiveness: true
367body: |
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
377
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
390...
391
392---
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
403name: clone_different_bb
404liveins:
405  - { reg: '$arguments' }
406tracksRegLiveness: true
407body: |
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
417
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
427
428  bb.1:
429  ; predecessors: %bb.0
430    CALL @use, %0:i32, implicit-def $arguments
431    RETURN implicit-def $arguments
432
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
439...
440
441---
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
456name: tee_with_two_use_insts
457liveins:
458  - { reg: '$arguments' }
459tracksRegLiveness: true
460body: |
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
472
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
487...
488
489---
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
494name: tee_with_one_inst_with_two_uses
495liveins:
496  - { reg: '$arguments' }
497tracksRegLiveness: true
498body: |
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
509
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
523...
524