Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / llvm / test / DebugInfo / WebAssembly / dbg-value-reg-stackify.mir
blobbfb3f740c49307ebe2ab0c614e09d71d2ae1bcf1
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() {
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() {
19     unreachable
20   }
21   define void @dont_sink_above_def() {
22     unreachable
23   }
24   define void @sink_to_same_place() {
25     unreachable
26   }
27   define void @cannot_sink_across_same_variable() {
28     unreachable
29   }
30   define void @cannot_sink_across_same_variable2() {
31     unreachable
32   }
33   define void @can_sink_across_same_variable_with_same_const() {
34     unreachable
35   }
36   define void @sink_multiple_defs() {
37     unreachable
38   }
39   define void @clone_same_bb() {
40     unreachable
41   }
42   define void @clone_different_bb() {
43     unreachable
44   }
45   define void @tee_with_two_use_insts() {
46     unreachable
47   }
48   define void @tee_with_one_inst_with_two_uses() {
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 ...
86 ---
87 # A simple sinking example.
88 # '%0 = CONST_I32 1' will sink to the place before 'CALL %use', and the two
89 # DBG_VALUEs will sink with it, leaving the original DBG_VALUEs to be set to
90 # undef (= DBG_VALUE $noreg).
91 # CHECK-LABEL: name: sink_simple
92 name: sink_simple
93 liveins:
94   - { reg: '$arguments' }
95 tracksRegLiveness: true
96 body: |
97   bb.0:
98     liveins: $arguments
99     %0:i32 = CONST_I32 1, implicit-def $arguments
100     DBG_VALUE %0:i32, $noreg, !5, !DIExpression(), debug-location !10
101     DBG_VALUE %0:i32, $noreg, !11, !DIExpression(), debug-location !10
102     NOP implicit-def $arguments
103     CALL @use, %0:i32, implicit-def $arguments
104     RETURN implicit-def $arguments
106   ; CHECK:      DBG_VALUE $noreg, $noreg, ![[VAR_A]], !DIExpression()
107   ; CHECK-NEXT: DBG_VALUE $noreg, $noreg, ![[VAR_B]], !DIExpression()
108   ; CHECK-NEXT: NOP implicit-def $arguments
109   ; CHECK-NEXT: %0:i32 = CONST_I32 1, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack
110   ; CHECK-NEXT: DBG_VALUE %0, $noreg, ![[VAR_A]], !DIExpression()
111   ; CHECK-NEXT: DBG_VALUE %0, $noreg, ![[VAR_B]], !DIExpression()
112   ; CHECK-NEXT: CALL @use, %0, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack
113   ; CHECK-NEXT: RETURN implicit-def $arguments
117 # Sinking when DBG_VALUEs are non-consecutive.
118 # '%0 = CONST_I32 1' will sink to the place before 'CALL %use', and the two
119 # DBG_VALUEs will sink with it, even though they are not consecutive. The
120 # original DBG_VALUEs will be set to undef.
121 # CHECK-LABEL: name: sink_non_consecutive
122 name: sink_non_consecutive
123 liveins:
124   - { reg: '$arguments' }
125 tracksRegLiveness: true
126 body: |
127   bb.0:
128     liveins: $arguments
129     %0:i32 = CONST_I32 1, implicit-def $arguments
130     DBG_VALUE %0:i32, $noreg, !5, !DIExpression(), debug-location !10
131     NOP implicit-def $arguments
132     DBG_VALUE %0:i32, $noreg, !11, !DIExpression(), debug-location !10
133     NOP implicit-def $arguments
134     CALL @use, %0:i32, implicit-def $arguments
135     RETURN implicit-def $arguments
137   ; CHECK:      DBG_VALUE $noreg, $noreg, ![[VAR_A]], !DIExpression()
138   ; CHECK-NEXT: NOP implicit-def $arguments
139   ; CHECK-NEXT: DBG_VALUE $noreg, $noreg, ![[VAR_B]], !DIExpression()
140   ; CHECK-NEXT: NOP implicit-def $arguments
141   ; CHECK-NEXT: %0:i32 = CONST_I32 1, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack
142   ; CHECK-NEXT: DBG_VALUE %0, $noreg, ![[VAR_A]], !DIExpression()
143   ; CHECK-NEXT: DBG_VALUE %0, $noreg, ![[VAR_B]], !DIExpression()
144   ; CHECK-NEXT: CALL @use, %0, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack
145   ; CHECK-NEXT: RETURN implicit-def $arguments
149 # Only DBG_VALUEs following a def should be sunk together.
150 # '%0 = CONST_I32 1' will sink to the place before 'CALL %use', but the
151 # DBG_VALUE above it should be untouched.
152 # CHECK-LABEL: name: dont_sink_above_def
153 name: dont_sink_above_def
154 liveins:
155   - { reg: '$arguments' }
156 tracksRegLiveness: true
157 body: |
158   bb.0:
159     liveins: $arguments
160     DBG_VALUE %0:i32, $noreg, !5, !DIExpression(), debug-location !10
161     %0:i32 = CONST_I32 1, implicit-def $arguments
162     NOP implicit-def $arguments
163     CALL @use, %0:i32, implicit-def $arguments
164     RETURN implicit-def $arguments
166   ; CHECK:      DBG_VALUE %0, $noreg, ![[VAR_A]], !DIExpression()
167   ; CHECK-NEXT: NOP implicit-def $arguments
168   ; CHECK-NEXT: %0:i32 = CONST_I32 1, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack
169   ; CHECK-NEXT: CALL @use, %0, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack
170   ; CHECK-NEXT: RETURN implicit-def $arguments
174 # A sink no-op case.
175 # '%0 = CONST_I32 1' will sink to the place before 'CALL %use', but it's already
176 # right before the CALL so it should be effectively a no-op. But currently
177 # sinking happens anyway so this will create unnecessary two undef DBG_VALUEs.
178 # This increases the number of DBG_VALUEs but doesn't hurt the coverage or
179 # generate incorrect debug info. TODO Improve this?
180 # CHECK-LABEL: name: sink_to_same_place
181 name: sink_to_same_place
182 liveins:
183   - { reg: '$arguments' }
184 tracksRegLiveness: true
185 body: |
186   bb.0:
187     liveins: $arguments
188     %0:i32 = CONST_I32 1, implicit-def $arguments
189     DBG_VALUE %0:i32, $noreg, !5, !DIExpression(), debug-location !10
190     DBG_VALUE %0:i32, $noreg, !11, !DIExpression(), debug-location !10
191     CALL @use, %0:i32, implicit-def $arguments
192     RETURN implicit-def $arguments
194   ; CHECK:      %0:i32 = CONST_I32 1, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack
195   ; CHECK-NEXT: DBG_VALUE %0, $noreg, ![[VAR_A]], !DIExpression()
196   ; CHECK-NEXT: DBG_VALUE %0, $noreg, ![[VAR_B]], !DIExpression()
197   ; CHECK-NEXT: CALL @use, %0, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack
198   ; CHECK-NEXT: RETURN implicit-def $arguments
202 # A DBG_VALUE cannot be sunk across another DBG_VALUE that has the same
203 # DebugVariable, because it will reorder assignments.
204 # '%0 = CONST_I32 1' will sink to the place before 'CALL %use'. But from the two
205 # DBG_VALUEs following it, only the DBG_VALUE for "var_b" can sink with it,
206 # because there is another 'DBG_VALUE 10' for "var_a" in the middle.
207 # CHECK-LABEL: name: cannot_sink_across_same_variable
208 name: cannot_sink_across_same_variable
209 liveins:
210   - { reg: '$arguments' }
211 tracksRegLiveness: true
212 body: |
213   bb.0:
214     liveins: $arguments
215     %0:i32 = CONST_I32 1, implicit-def $arguments
216     DBG_VALUE %0:i32, $noreg, !5, !DIExpression(), debug-location !10
217     DBG_VALUE %0:i32, $noreg, !11, !DIExpression(), debug-location !10
218     DBG_VALUE 10, $noreg, !5, !DIExpression(), debug-location !10
219     NOP implicit-def $arguments
220     CALL @use, %0:i32, implicit-def $arguments
221     RETURN implicit-def $arguments
223   ; CHECK:      DBG_VALUE $noreg, $noreg, ![[VAR_A]], !DIExpression()
224   ; CHECK-NEXT: DBG_VALUE $noreg, $noreg, ![[VAR_B]], !DIExpression()
225   ; CHECK-NEXT: DBG_VALUE 10, $noreg, ![[VAR_A]], !DIExpression()
226   ; CHECK-NEXT: NOP implicit-def $arguments
227   ; CHECK-NEXT: %0:i32 = CONST_I32 1, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack
228   ; CHECK-NEXT: DBG_VALUE %0, $noreg, ![[VAR_B]], !DIExpression()
229   ; CHECK-NEXT: CALL @use, %0, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack
230   ; CHECK-NEXT: RETURN implicit-def $arguments
234 # Another case in which a DBG_VALUE cannot be sunk across another DBG_VALUE with
235 # the same DebugVariable, because it will reorder assignments.
236 # '%0 = CONST_I32 1' will sink to the place before 'CALL %use'. But from the two
237 # DBG_VALUEs following it, only the DBG_VALUE for "var_b" can sink with it,
238 # because there is another 'DBG_VALUE %1, "var_a"' in the middle.
239 # CHECK-LABEL: name: cannot_sink_across_same_variable2
240 name: cannot_sink_across_same_variable2
241 liveins:
242   - { reg: '$arguments' }
243 tracksRegLiveness: true
244 body: |
245   bb.0:
246     liveins: $arguments
247     %0:i32 = CONST_I32 1, implicit-def $arguments
248     %1:i32 = CONST_I32 2, implicit-def $arguments
249     DBG_VALUE %0:i32, $noreg, !5, !DIExpression(), debug-location !10
250     DBG_VALUE %0:i32, $noreg, !11, !DIExpression(), debug-location !10
251     DBG_VALUE %1:i32, $noreg, !5, !DIExpression(), debug-location !10
252     NOP implicit-def $arguments
253     CALL @use, %0:i32, implicit-def $arguments
254     RETURN implicit-def $arguments
256   ; CHECK:      %1:i32 = CONST_I32 2, implicit-def $arguments
257   ; CHECK-NEXT: DBG_VALUE $noreg, $noreg, ![[VAR_A]], !DIExpression()
258   ; CHECK-NEXT: DBG_VALUE $noreg, $noreg, ![[VAR_B]], !DIExpression()
259   ; CHECK-NEXT: DBG_VALUE %1, $noreg, ![[VAR_A]], !DIExpression()
260   ; CHECK-NEXT: NOP implicit-def $arguments
261   ; CHECK-NEXT: %0:i32 = CONST_I32 1, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack
262   ; CHECK-NEXT: DBG_VALUE %0, $noreg, ![[VAR_B]], !DIExpression()
263   ; CHECK-NEXT: CALL @use, %0, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack
264   ; CHECK-NEXT: RETURN implicit-def $arguments
268 # There is a exception in which a DBG_VALUE can be sunk across another DBG_VALUE
269 # with the same DebugVariable: when the interfering DBG_VALUE refers to the same
270 # CONST_[I32/I64/F32/F64] instruction, in which case we don't reorder
271 # assignments.
273 # This is the same test with the previous one with one difference: %1 has the
274 # same CONST instruction with %0 'CONST_I32 1'. We can sink the DBG_VALUE for
275 # "var_a" here as well.
276 # CHECK-LABEL: name: can_sink_across_same_variable_with_same_const
277 name: can_sink_across_same_variable_with_same_const
278 liveins:
279   - { reg: '$arguments' }
280 tracksRegLiveness: true
281 body: |
282   bb.0:
283     liveins: $arguments
284     %0:i32 = CONST_I32 1, implicit-def $arguments
285     %1:i32 = CONST_I32 1, implicit-def $arguments ; Same CONST_I32
286     DBG_VALUE %0:i32, $noreg, !5, !DIExpression(), debug-location !10
287     DBG_VALUE %0:i32, $noreg, !11, !DIExpression(), debug-location !10
288     DBG_VALUE %1:i32, $noreg, !5, !DIExpression(), debug-location !10
289     NOP implicit-def $arguments
290     CALL @use, %0:i32, implicit-def $arguments
291     RETURN implicit-def $arguments
293   ; CHECK:      %1:i32 = CONST_I32 1, implicit-def $arguments
294   ; CHECK-NEXT: DBG_VALUE $noreg, $noreg, ![[VAR_A]], !DIExpression()
295   ; CHECK-NEXT: DBG_VALUE $noreg, $noreg, ![[VAR_B]], !DIExpression()
296   ; CHECK-NEXT: DBG_VALUE %1, $noreg, ![[VAR_A]], !DIExpression()
297   ; CHECK-NEXT: NOP implicit-def $arguments
298   ; CHECK-NEXT: %0:i32 = CONST_I32 1, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack
299   ; CHECK-NEXT: DBG_VALUE %0, $noreg, ![[VAR_A]], !DIExpression()
300   ; CHECK-NEXT: DBG_VALUE %0, $noreg, ![[VAR_B]], !DIExpression()
301   ; CHECK-NEXT: CALL @use, %0, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack
302   ; CHECK-NEXT: RETURN implicit-def $arguments
306 # Both %0 and %1 will be sunk to the place before ADD_I32. DBG_VALUEs associated
307 # with those two defs will be sunk as well, leaving the original DBG_VALUEs set
308 # to undef.
309 # CHECK-LABEL: name: sink_multiple_defs
310 name: sink_multiple_defs
311 liveins:
312   - { reg: '$arguments' }
313 tracksRegLiveness: true
314 body: |
315   bb.0:
316     liveins: $arguments
317     %0:i32 = CONST_I32 1, implicit-def $arguments
318     DBG_VALUE %0:i32, $noreg, !5, !DIExpression(), debug-location !10
319     DBG_VALUE %0:i32, $noreg, !11, !DIExpression(), debug-location !10
320     NOP implicit-def $arguments
321     %1:i32 = CONST_I32 2, implicit-def $arguments
322     DBG_VALUE %1:i32, $noreg, !12, !DIExpression(), debug-location !10
323     DBG_VALUE %1:i32, $noreg, !13, !DIExpression(), debug-location !10
324     NOP implicit-def $arguments
325     %2:i32 = ADD_I32 %0:i32, %1:i32, implicit-def $arguments
326     RETURN implicit-def $arguments
328   ; CHECK:      DBG_VALUE $noreg, $noreg, ![[VAR_A]], !DIExpression()
329   ; CHECK-NEXT: DBG_VALUE $noreg, $noreg, ![[VAR_B]], !DIExpression()
330   ; CHECK-NEXT: NOP implicit-def $arguments
331   ; CHECK-NEXT: DBG_VALUE $noreg, $noreg, ![[VAR_C]], !DIExpression()
332   ; CHECK-NEXT: DBG_VALUE $noreg, $noreg, ![[VAR_D]], !DIExpression()
333   ; CHECK-NEXT: NOP implicit-def $arguments
334   ; CHECK-NEXT: %0:i32 = CONST_I32 1, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack
335   ; CHECK-NEXT: DBG_VALUE %0, $noreg, ![[VAR_A]], !DIExpression()
336   ; CHECK-NEXT: DBG_VALUE %0, $noreg, ![[VAR_B]], !DIExpression()
337   ; CHECK-NEXT: %1:i32 = CONST_I32 2, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack
338   ; CHECK-NEXT: DBG_VALUE %1, $noreg, ![[VAR_C]], !DIExpression()
339   ; CHECK-NEXT: DBG_VALUE %1, $noreg, ![[VAR_D]], !DIExpression()
340   ; CHECK-NEXT: dead %2:i32 = ADD_I32 %0, %1, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack
341   ; CHECK-NEXT: RETURN implicit-def $arguments
345 # A simple cloning example.
346 # When processing the second 'CALL @use', because %0 has multiple uses, the def
347 # '%0 = CONST_I32 1' is cloned before the CALL, along with its DBG_VALUEs. And
348 # then when processing the first 'CALL @use', by that time %0 has only one use
349 # remaining, so it is just sink with the DBG_VALUEs, leaving the original
350 # DBG_VALUEs undef.
351 # CHECK-LABEL: name: clone_same_bb
352 name: clone_same_bb
353 liveins:
354   - { reg: '$arguments' }
355 tracksRegLiveness: true
356 body: |
357   bb.0:
358     liveins: $arguments
359     %0:i32 = CONST_I32 1, implicit-def $arguments
360     DBG_VALUE %0:i32, $noreg, !5, !DIExpression(), debug-location !10
361     DBG_VALUE %0:i32, $noreg, !11, !DIExpression(), debug-location !10
362     NOP implicit-def $arguments
363     CALL @use, %0:i32, implicit-def $arguments
364     CALL @use, %0:i32, implicit-def $arguments
365     RETURN implicit-def $arguments
367   ; CHECK:      DBG_VALUE $noreg, $noreg, ![[VAR_A]], !DIExpression()
368   ; CHECK-NEXT: DBG_VALUE $noreg, $noreg, ![[VAR_B]], !DIExpression()
369   ; CHECK-NEXT: NOP implicit-def $arguments
370   ; CHECK-NEXT: %0:i32 = CONST_I32 1, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack
371   ; CHECK-NEXT: DBG_VALUE %0, $noreg, ![[VAR_A]], !DIExpression()
372   ; CHECK-NEXT: DBG_VALUE %0, $noreg, ![[VAR_B]], !DIExpression()
373   ; CHECK-NEXT: CALL @use, %0, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack
374   ; CHECK-NEXT: %1:i32 = CONST_I32 1, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack
375   ; CHECK-NEXT: DBG_VALUE %1, $noreg, ![[VAR_A]], !DIExpression()
376   ; CHECK-NEXT: DBG_VALUE %1, $noreg, ![[VAR_B]], !DIExpression()
377   ; CHECK-NEXT: CALL @use, %1, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack
378   ; CHECK-NEXT: RETURN implicit-def $arguments
382 # Cloning across different BBs.
383 # First, when bb.0's 'CALL @use' is procssed, '%0 = CONST_I32 1' and its
384 # DBG_VALUEs are cloned before the CALL. And when bb.1's 'CALL @use' is
385 # processed, '%0 = CONST_I32 1' and its DBG_VALUEs are cloned to bb.1 this time.
386 # Even though there are (previously cloned) DBG_VALUEs for "var_a" and "var_b"
387 # in the middle, it's fine because they point to the same 'CONST_I32 1'
388 # instruction.
389 # After the second cloning, the original '%0 = CONST_I32 1' is removed because
390 # it doesn't have any users anymore, leaving its original DBG_VALUEs as undef.
391 # CHECK-LABEL: name: clone_different_bb
392 name: clone_different_bb
393 liveins:
394   - { reg: '$arguments' }
395 tracksRegLiveness: true
396 body: |
397   bb.0:
398     successors: %bb.1
399     liveins: $arguments
400     %0:i32 = CONST_I32 1, implicit-def $arguments
401     DBG_VALUE %0:i32, $noreg, !5, !DIExpression(), debug-location !10
402     DBG_VALUE %0:i32, $noreg, !11, !DIExpression(), debug-location !10
403     NOP implicit-def $arguments
404     CALL @use, %0:i32, implicit-def $arguments
405     BR %bb.1, implicit-def $arguments
407   ; CHECK:    bb.0:
408   ; CHECK:      DBG_VALUE $noreg, $noreg, ![[VAR_A]], !DIExpression()
409   ; CHECK-NEXT: DBG_VALUE $noreg, $noreg, ![[VAR_B]], !DIExpression()
410   ; CHECK-NEXT: NOP implicit-def $arguments
411   ; CHECK-NEXT: %1:i32 = CONST_I32 1, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack
412   ; CHECK-NEXT: DBG_VALUE %1, $noreg, ![[VAR_A]], !DIExpression()
413   ; CHECK-NEXT: DBG_VALUE %1, $noreg, ![[VAR_B]], !DIExpression()
414   ; CHECK-NEXT: CALL @use, %1, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack
415   ; CHECK-NEXT: BR %bb.1, implicit-def $arguments
417   bb.1:
418   ; predecessors: %bb.0
419     CALL @use, %0:i32, implicit-def $arguments
420     RETURN implicit-def $arguments
422   ; CHECK:    bb.1:
423   ; CHECK:      %2:i32 = CONST_I32 1, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack
424   ; CHECK-NEXT: DBG_VALUE %2, $noreg, ![[VAR_A]], !DIExpression()
425   ; CHECK-NEXT: DBG_VALUE %2, $noreg, ![[VAR_B]], !DIExpression()
426   ; CHECK-NEXT: CALL @use, %2, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack
427   ; CHECK-NEXT: RETURN implicit-def $arguments
431 # TEE conversion example.
432 # Convert this form:
433 #   Reg = INST ...        // Def
434 #   DBG_VALUE Reg, ...
435 #   INST ..., Reg, ...    // Insert
436 #   INST ..., Reg, ...
437 # to
438 #   DefReg = INST ...     // Def (to become the new Insert)
439 #   DBG_VALUE DefReg, ...
440 #   TeeReg, Reg = TEE_... DefReg
441 #   DBG_VALUE TeeReg, ...
442 #   INST ..., TeeReg, ... // Insert
443 #   INST ..., Reg, ...
444 # CHECK-LABEL: name: tee_with_two_use_insts
445 name: tee_with_two_use_insts
446 liveins:
447   - { reg: '$arguments' }
448 tracksRegLiveness: true
449 body: |
450   bb.0:
451     liveins: $arguments
452     %0:i32 = ARGUMENT_i32 0, implicit $arguments
453     %1:i32 = ARGUMENT_i32 1, implicit $arguments
454     %2:i32 = MUL_I32 %1:i32, %0:i32, implicit-def $arguments
455     DBG_VALUE %2:i32, $noreg, !5, !DIExpression(), debug-location !10
456     DBG_VALUE %2:i32, $noreg, !11, !DIExpression(), debug-location !10
457     NOP implicit-def $arguments
458     CALL @use, %2:i32, implicit-def $arguments
459     CALL @use, %2:i32, implicit-def $arguments
460     RETURN implicit-def $arguments
462   ; CHECK:      %0:i32 = ARGUMENT_i32 0, implicit $arguments
463   ; CHECK-NEXT: %1:i32 = ARGUMENT_i32 1, implicit $arguments
464   ; CHECK-NEXT: DBG_VALUE $noreg, $noreg, ![[VAR_A]], !DIExpression()
465   ; CHECK-NEXT: DBG_VALUE $noreg, $noreg, ![[VAR_B]], !DIExpression()
466   ; CHECK-NEXT: NOP implicit-def $arguments
467   ; CHECK-NEXT: %4:i32 = MUL_I32 %1, %0, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack
468   ; CHECK-NEXT: DBG_VALUE %4, $noreg, ![[VAR_A]], !DIExpression()
469   ; CHECK-NEXT: DBG_VALUE %4, $noreg, ![[VAR_B]], !DIExpression()
470   ; CHECK-NEXT: %3:i32, %2:i32 = TEE_I32 %4, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack
471   ; CHECK-NEXT: DBG_VALUE %3, $noreg, ![[VAR_A]], !DIExpression()
472   ; CHECK-NEXT: DBG_VALUE %3, $noreg, ![[VAR_B]], !DIExpression()
473   ; CHECK-NEXT: CALL @use, %3, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack
474   ; CHECK-NEXT: CALL @use, %2, implicit-def $arguments
475   ; CHECK-NEXT: RETURN implicit-def $arguments
479 # Another TEE conversion example. The previous example had two instructions
480 # that use a single register, whereas this has one instructions that has two
481 # same use operands. The resulting transformation is the same.
482 # CHECK-LABEL: name: tee_with_one_inst_with_two_uses
483 name: tee_with_one_inst_with_two_uses
484 liveins:
485   - { reg: '$arguments' }
486 tracksRegLiveness: true
487 body: |
488   bb.0:
489     liveins: $arguments
490     %0:i32 = ARGUMENT_i32 0, implicit $arguments
491     %1:i32 = ARGUMENT_i32 1, implicit $arguments
492     %2:i32 = MUL_I32 %1:i32, %0:i32, implicit-def $arguments
493     DBG_VALUE %2:i32, $noreg, !5, !DIExpression(), debug-location !10
494     DBG_VALUE %2:i32, $noreg, !11, !DIExpression(), debug-location !10
495     NOP implicit-def $arguments
496     CALL @use_2, %2:i32, %2:i32, implicit-def $arguments
497     RETURN implicit-def $arguments
499   ; CHECK:      %0:i32 = ARGUMENT_i32 0, implicit $arguments
500   ; CHECK-NEXT: %1:i32 = ARGUMENT_i32 1, implicit $arguments
501   ; CHECK-NEXT: DBG_VALUE $noreg, $noreg, ![[VAR_A]], !DIExpression()
502   ; CHECK-NEXT: DBG_VALUE $noreg, $noreg, ![[VAR_B]], !DIExpression()
503   ; CHECK-NEXT: NOP implicit-def $arguments
504   ; CHECK-NEXT: %4:i32 = MUL_I32 %1, %0, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack
505   ; CHECK-NEXT: DBG_VALUE %4, $noreg, ![[VAR_A]], !DIExpression()
506   ; CHECK-NEXT: DBG_VALUE %4, $noreg, ![[VAR_B]], !DIExpression()
507   ; CHECK-NEXT: %3:i32, %2:i32 = TEE_I32 %4, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack
508   ; CHECK-NEXT: DBG_VALUE %3, $noreg, ![[VAR_A]], !DIExpression()
509   ; CHECK-NEXT: DBG_VALUE %3, $noreg, ![[VAR_B]], !DIExpression()
510   ; CHECK-NEXT: CALL @use_2, %3, %2, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack
511   ; CHECK-NEXT: RETURN implicit-def $arguments