1 # RUN: llc -run-pass wasm-reg-stackify %s -o - | FileCheck %s
3 # Tests for DBG_VALUE hanlding in RegStackify + DebugValueManager
6 target triple = "wasm32-unknown-unknown"
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
18 define void @sink_non_consecutive() !dbg !14 {
21 define void @dont_sink_above_def() !dbg !15 {
24 define void @sink_to_same_place() !dbg !16 {
27 define void @cannot_sink_across_same_variable() !dbg !17 {
30 define void @cannot_sink_across_same_variable2() !dbg !18 {
33 define void @can_sink_across_same_variable_with_same_const() !dbg !19 {
36 define void @sink_multiple_defs() !dbg !20 {
39 define void @clone_same_bb() !dbg !21 {
42 define void @clone_different_bb() !dbg !22 {
45 define void @tee_with_two_use_insts() !dbg !23 {
48 define void @tee_with_one_inst_with_two_uses() !dbg !24 {
51 declare void @llvm.dbg.value(metadata, metadata, metadata)
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)
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)
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
105 - { reg: '$arguments' }
106 tracksRegLiveness: true
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
135 - { reg: '$arguments' }
136 tracksRegLiveness: true
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
166 - { reg: '$arguments' }
167 tracksRegLiveness: true
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
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
194 - { reg: '$arguments' }
195 tracksRegLiveness: true
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
221 - { reg: '$arguments' }
222 tracksRegLiveness: true
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
253 - { reg: '$arguments' }
254 tracksRegLiveness: true
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
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
290 - { reg: '$arguments' }
291 tracksRegLiveness: true
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
320 # CHECK-LABEL: name: sink_multiple_defs
321 name: sink_multiple_defs
323 - { reg: '$arguments' }
324 tracksRegLiveness: true
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
362 # CHECK-LABEL: name: clone_same_bb
365 - { reg: '$arguments' }
366 tracksRegLiveness: true
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'
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
405 - { reg: '$arguments' }
406 tracksRegLiveness: true
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
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
429 ; predecessors: %bb.0
430 CALL @use, %0:i32, implicit-def $arguments
431 RETURN implicit-def $arguments
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.
444 # Reg = INST ... // Def
446 # INST ..., Reg, ... // Insert
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
455 # CHECK-LABEL: name: tee_with_two_use_insts
456 name: tee_with_two_use_insts
458 - { reg: '$arguments' }
459 tracksRegLiveness: true
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
496 - { reg: '$arguments' }
497 tracksRegLiveness: true
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