524 lines · plain
1# RUN: llc -run-pass wasm-reg-stackify %s -o - | FileCheck %s2 3# Tests for DBG_VALUE hanlding in RegStackify + DebugValueManager4 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 !1013 call void @llvm.dbg.value(metadata i32 0, metadata !11, metadata !DIExpression()), !dbg !1014 call void @llvm.dbg.value(metadata i32 0, metadata !12, metadata !DIExpression()), !dbg !1015 call void @llvm.dbg.value(metadata i32 0, metadata !13, metadata !DIExpression()), !dbg !1016 ret void17 }18 define void @sink_non_consecutive() !dbg !14 {19 unreachable20 }21 define void @dont_sink_above_def() !dbg !15 {22 unreachable23 }24 define void @sink_to_same_place() !dbg !16 {25 unreachable26 }27 define void @cannot_sink_across_same_variable() !dbg !17 {28 unreachable29 }30 define void @cannot_sink_across_same_variable2() !dbg !18 {31 unreachable32 }33 define void @can_sink_across_same_variable_with_same_const() !dbg !19 {34 unreachable35 }36 define void @sink_multiple_defs() !dbg !20 {37 unreachable38 }39 define void @clone_same_bb() !dbg !21 {40 unreachable41 }42 define void @clone_different_bb() !dbg !22 {43 unreachable44 }45 define void @tee_with_two_use_insts() !dbg !23 {46 unreachable47 }48 define void @tee_with_one_inst_with_two_uses() !dbg !24 {49 unreachable50 }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 will57 ; use in all functions in ths file:58 ; - "var_a" / VAR_A: !559 ; - "var_b" / VAR_B: !1160 ; - "var_c" / VAR_C: !1261 ; - "var_d" / VAR_D: !1362 ; We will use VAR_? in the CHECK lines for robustness in case of metadata63 ; renumbering, but currently in mir tests we cannot use variable names like64 ; "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 two100# DBG_VALUEs will sink with it, leaving the original DBG_VALUEs to be set to101# undef (= DBG_VALUE $noreg).102# CHECK-LABEL: name: sink_simple103name: sink_simple104liveins:105 - { reg: '$arguments' }106tracksRegLiveness: true107body: |108 bb.0:109 liveins: $arguments110 %0:i32 = CONST_I32 1, implicit-def $arguments111 DBG_VALUE %0:i32, $noreg, !5, !DIExpression(), debug-location !10112 DBG_VALUE %0:i32, $noreg, !11, !DIExpression(), debug-location !10113 NOP implicit-def $arguments114 CALL @use, %0:i32, implicit-def $arguments115 RETURN implicit-def $arguments116 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 $arguments120 ; CHECK-NEXT: %0:i32 = CONST_I32 1, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack121 ; 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_stack124 ; CHECK-NEXT: RETURN implicit-def $arguments125...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 two130# DBG_VALUEs will sink with it, even though they are not consecutive. The131# original DBG_VALUEs will be set to undef.132# CHECK-LABEL: name: sink_non_consecutive133name: sink_non_consecutive134liveins:135 - { reg: '$arguments' }136tracksRegLiveness: true137body: |138 bb.0:139 liveins: $arguments140 %0:i32 = CONST_I32 1, implicit-def $arguments141 DBG_VALUE %0:i32, $noreg, !5, !DIExpression(), debug-location !10142 NOP implicit-def $arguments143 DBG_VALUE %0:i32, $noreg, !11, !DIExpression(), debug-location !10144 NOP implicit-def $arguments145 CALL @use, %0:i32, implicit-def $arguments146 RETURN implicit-def $arguments147 148 ; CHECK: DBG_VALUE $noreg, $noreg, ![[VAR_A]], !DIExpression()149 ; CHECK-NEXT: NOP implicit-def $arguments150 ; CHECK-NEXT: DBG_VALUE $noreg, $noreg, ![[VAR_B]], !DIExpression()151 ; CHECK-NEXT: NOP implicit-def $arguments152 ; CHECK-NEXT: %0:i32 = CONST_I32 1, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack153 ; 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_stack156 ; CHECK-NEXT: RETURN implicit-def $arguments157...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 the162# DBG_VALUE above it should be untouched.163# CHECK-LABEL: name: dont_sink_above_def164name: dont_sink_above_def165liveins:166 - { reg: '$arguments' }167tracksRegLiveness: true168body: |169 bb.0:170 liveins: $arguments171 DBG_VALUE %0:i32, $noreg, !5, !DIExpression(), debug-location !10172 %0:i32 = CONST_I32 1, implicit-def $arguments173 NOP implicit-def $arguments174 CALL @use, %0:i32, implicit-def $arguments175 RETURN implicit-def $arguments176 177 ; CHECK: DBG_VALUE %0, $noreg, ![[VAR_A]], !DIExpression()178 ; CHECK-NEXT: NOP implicit-def $arguments179 ; CHECK-NEXT: %0:i32 = CONST_I32 1, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack180 ; CHECK-NEXT: CALL @use, %0, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack181 ; CHECK-NEXT: RETURN implicit-def $arguments182...183 184---185# A sink no-op case.186# '%0 = CONST_I32 1' will sink to the place before 'CALL %use', but it's already187# right before the CALL so it should be effectively a no-op. But currently188# 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 or190# generate incorrect debug info. TODO Improve this?191# CHECK-LABEL: name: sink_to_same_place192name: sink_to_same_place193liveins:194 - { reg: '$arguments' }195tracksRegLiveness: true196body: |197 bb.0:198 liveins: $arguments199 %0:i32 = CONST_I32 1, implicit-def $arguments200 DBG_VALUE %0:i32, $noreg, !5, !DIExpression(), debug-location !10201 DBG_VALUE %0:i32, $noreg, !11, !DIExpression(), debug-location !10202 CALL @use, %0:i32, implicit-def $arguments203 RETURN implicit-def $arguments204 205 ; CHECK: %0:i32 = CONST_I32 1, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack206 ; 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_stack209 ; CHECK-NEXT: RETURN implicit-def $arguments210...211 212---213# A DBG_VALUE cannot be sunk across another DBG_VALUE that has the same214# DebugVariable, because it will reorder assignments.215# '%0 = CONST_I32 1' will sink to the place before 'CALL %use'. But from the two216# 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_variable219name: cannot_sink_across_same_variable220liveins:221 - { reg: '$arguments' }222tracksRegLiveness: true223body: |224 bb.0:225 liveins: $arguments226 %0:i32 = CONST_I32 1, implicit-def $arguments227 DBG_VALUE %0:i32, $noreg, !5, !DIExpression(), debug-location !10228 DBG_VALUE %0:i32, $noreg, !11, !DIExpression(), debug-location !10229 DBG_VALUE 10, $noreg, !5, !DIExpression(), debug-location !10230 NOP implicit-def $arguments231 CALL @use, %0:i32, implicit-def $arguments232 RETURN implicit-def $arguments233 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 $arguments238 ; CHECK-NEXT: %0:i32 = CONST_I32 1, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack239 ; CHECK-NEXT: DBG_VALUE %0, $noreg, ![[VAR_B]], !DIExpression()240 ; CHECK-NEXT: CALL @use, %0, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack241 ; CHECK-NEXT: RETURN implicit-def $arguments242...243 244---245# Another case in which a DBG_VALUE cannot be sunk across another DBG_VALUE with246# the same DebugVariable, because it will reorder assignments.247# '%0 = CONST_I32 1' will sink to the place before 'CALL %use'. But from the two248# 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_variable2251name: cannot_sink_across_same_variable2252liveins:253 - { reg: '$arguments' }254tracksRegLiveness: true255body: |256 bb.0:257 liveins: $arguments258 %0:i32 = CONST_I32 1, implicit-def $arguments259 %1:i32 = CONST_I32 2, implicit-def $arguments260 DBG_VALUE %0:i32, $noreg, !5, !DIExpression(), debug-location !10261 DBG_VALUE %0:i32, $noreg, !11, !DIExpression(), debug-location !10262 DBG_VALUE %1:i32, $noreg, !5, !DIExpression(), debug-location !10263 NOP implicit-def $arguments264 CALL @use, %0:i32, implicit-def $arguments265 RETURN implicit-def $arguments266 267 ; CHECK: %1:i32 = CONST_I32 2, implicit-def $arguments268 ; 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 $arguments272 ; CHECK-NEXT: %0:i32 = CONST_I32 1, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack273 ; CHECK-NEXT: DBG_VALUE %0, $noreg, ![[VAR_B]], !DIExpression()274 ; CHECK-NEXT: CALL @use, %0, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack275 ; CHECK-NEXT: RETURN implicit-def $arguments276...277 278---279# There is a exception in which a DBG_VALUE can be sunk across another DBG_VALUE280# with the same DebugVariable: when the interfering DBG_VALUE refers to the same281# CONST_[I32/I64/F32/F64] instruction, in which case we don't reorder282# assignments.283#284# This is the same test with the previous one with one difference: %1 has the285# same CONST instruction with %0 'CONST_I32 1'. We can sink the DBG_VALUE for286# "var_a" here as well.287# CHECK-LABEL: name: can_sink_across_same_variable_with_same_const288name: can_sink_across_same_variable_with_same_const289liveins:290 - { reg: '$arguments' }291tracksRegLiveness: true292body: |293 bb.0:294 liveins: $arguments295 %0:i32 = CONST_I32 1, implicit-def $arguments296 %1:i32 = CONST_I32 1, implicit-def $arguments ; Same CONST_I32297 DBG_VALUE %0:i32, $noreg, !5, !DIExpression(), debug-location !10298 DBG_VALUE %0:i32, $noreg, !11, !DIExpression(), debug-location !10299 DBG_VALUE %1:i32, $noreg, !5, !DIExpression(), debug-location !10300 NOP implicit-def $arguments301 CALL @use, %0:i32, implicit-def $arguments302 RETURN implicit-def $arguments303 304 ; CHECK: %1:i32 = CONST_I32 1, implicit-def $arguments305 ; 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 $arguments309 ; CHECK-NEXT: %0:i32 = CONST_I32 1, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack310 ; 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_stack313 ; CHECK-NEXT: RETURN implicit-def $arguments314...315 316---317# Both %0 and %1 will be sunk to the place before ADD_I32. DBG_VALUEs associated318# with those two defs will be sunk as well, leaving the original DBG_VALUEs set319# to undef.320# CHECK-LABEL: name: sink_multiple_defs321name: sink_multiple_defs322liveins:323 - { reg: '$arguments' }324tracksRegLiveness: true325body: |326 bb.0:327 liveins: $arguments328 %0:i32 = CONST_I32 1, implicit-def $arguments329 DBG_VALUE %0:i32, $noreg, !5, !DIExpression(), debug-location !10330 DBG_VALUE %0:i32, $noreg, !11, !DIExpression(), debug-location !10331 NOP implicit-def $arguments332 %1:i32 = CONST_I32 2, implicit-def $arguments333 DBG_VALUE %1:i32, $noreg, !12, !DIExpression(), debug-location !10334 DBG_VALUE %1:i32, $noreg, !13, !DIExpression(), debug-location !10335 NOP implicit-def $arguments336 %2:i32 = ADD_I32 %0:i32, %1:i32, implicit-def $arguments337 RETURN implicit-def $arguments338 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 $arguments342 ; 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 $arguments345 ; CHECK-NEXT: %0:i32 = CONST_I32 1, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack346 ; 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_stack349 ; 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_stack352 ; CHECK-NEXT: RETURN implicit-def $arguments353...354 355---356# A simple cloning example.357# When processing the second 'CALL @use', because %0 has multiple uses, the def358# '%0 = CONST_I32 1' is cloned before the CALL, along with its DBG_VALUEs. And359# then when processing the first 'CALL @use', by that time %0 has only one use360# remaining, so it is just sink with the DBG_VALUEs, leaving the original361# DBG_VALUEs undef.362# CHECK-LABEL: name: clone_same_bb363name: clone_same_bb364liveins:365 - { reg: '$arguments' }366tracksRegLiveness: true367body: |368 bb.0:369 liveins: $arguments370 %0:i32 = CONST_I32 1, implicit-def $arguments371 DBG_VALUE %0:i32, $noreg, !5, !DIExpression(), debug-location !10372 DBG_VALUE %0:i32, $noreg, !11, !DIExpression(), debug-location !10373 NOP implicit-def $arguments374 CALL @use, %0:i32, implicit-def $arguments375 CALL @use, %0:i32, implicit-def $arguments376 RETURN implicit-def $arguments377 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 $arguments381 ; CHECK-NEXT: %0:i32 = CONST_I32 1, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack382 ; 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_stack385 ; CHECK-NEXT: %1:i32 = CONST_I32 1, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack386 ; 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_stack389 ; CHECK-NEXT: RETURN implicit-def $arguments390...391 392---393# Cloning across different BBs.394# First, when bb.0's 'CALL @use' is procssed, '%0 = CONST_I32 1' and its395# DBG_VALUEs are cloned before the CALL. And when bb.1's 'CALL @use' is396# 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 because401# it doesn't have any users anymore, leaving its original DBG_VALUEs as undef.402# CHECK-LABEL: name: clone_different_bb403name: clone_different_bb404liveins:405 - { reg: '$arguments' }406tracksRegLiveness: true407body: |408 bb.0:409 successors: %bb.1410 liveins: $arguments411 %0:i32 = CONST_I32 1, implicit-def $arguments412 DBG_VALUE %0:i32, $noreg, !5, !DIExpression(), debug-location !10413 DBG_VALUE %0:i32, $noreg, !11, !DIExpression(), debug-location !10414 NOP implicit-def $arguments415 CALL @use, %0:i32, implicit-def $arguments416 BR %bb.1, implicit-def $arguments417 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 $arguments422 ; CHECK-NEXT: %1:i32 = CONST_I32 1, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack423 ; 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_stack426 ; CHECK-NEXT: BR %bb.1, implicit-def $arguments427 428 bb.1:429 ; predecessors: %bb.0430 CALL @use, %0:i32, implicit-def $arguments431 RETURN implicit-def $arguments432 433 ; CHECK: bb.1:434 ; CHECK: %2:i32 = CONST_I32 1, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack435 ; 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_stack438 ; CHECK-NEXT: RETURN implicit-def $arguments439...440 441---442# TEE conversion example.443# Convert this form:444# Reg = INST ... // Def445# DBG_VALUE Reg, ...446# INST ..., Reg, ... // Insert447# INST ..., Reg, ...448# to449# DefReg = INST ... // Def (to become the new Insert)450# DBG_VALUE DefReg, ...451# TeeReg, Reg = TEE_... DefReg452# DBG_VALUE TeeReg, ...453# INST ..., TeeReg, ... // Insert454# INST ..., Reg, ...455# CHECK-LABEL: name: tee_with_two_use_insts456name: tee_with_two_use_insts457liveins:458 - { reg: '$arguments' }459tracksRegLiveness: true460body: |461 bb.0:462 liveins: $arguments463 %0:i32 = ARGUMENT_i32 0, implicit $arguments464 %1:i32 = ARGUMENT_i32 1, implicit $arguments465 %2:i32 = MUL_I32 %1:i32, %0:i32, implicit-def $arguments466 DBG_VALUE %2:i32, $noreg, !5, !DIExpression(), debug-location !10467 DBG_VALUE %2:i32, $noreg, !11, !DIExpression(), debug-location !10468 NOP implicit-def $arguments469 CALL @use, %2:i32, implicit-def $arguments470 CALL @use, %2:i32, implicit-def $arguments471 RETURN implicit-def $arguments472 473 ; CHECK: %0:i32 = ARGUMENT_i32 0, implicit $arguments474 ; CHECK-NEXT: %1:i32 = ARGUMENT_i32 1, implicit $arguments475 ; 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 $arguments478 ; CHECK-NEXT: %4:i32 = MUL_I32 %1, %0, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack479 ; 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_stack482 ; 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_stack485 ; CHECK-NEXT: CALL @use, %2, implicit-def $arguments486 ; CHECK-NEXT: RETURN implicit-def $arguments487...488 489---490# Another TEE conversion example. The previous example had two instructions491# that use a single register, whereas this has one instructions that has two492# same use operands. The resulting transformation is the same.493# CHECK-LABEL: name: tee_with_one_inst_with_two_uses494name: tee_with_one_inst_with_two_uses495liveins:496 - { reg: '$arguments' }497tracksRegLiveness: true498body: |499 bb.0:500 liveins: $arguments501 %0:i32 = ARGUMENT_i32 0, implicit $arguments502 %1:i32 = ARGUMENT_i32 1, implicit $arguments503 %2:i32 = MUL_I32 %1:i32, %0:i32, implicit-def $arguments504 DBG_VALUE %2:i32, $noreg, !5, !DIExpression(), debug-location !10505 DBG_VALUE %2:i32, $noreg, !11, !DIExpression(), debug-location !10506 NOP implicit-def $arguments507 CALL @use_2, %2:i32, %2:i32, implicit-def $arguments508 RETURN implicit-def $arguments509 510 ; CHECK: %0:i32 = ARGUMENT_i32 0, implicit $arguments511 ; CHECK-NEXT: %1:i32 = ARGUMENT_i32 1, implicit $arguments512 ; 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 $arguments515 ; CHECK-NEXT: %4:i32 = MUL_I32 %1, %0, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack516 ; 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_stack519 ; 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_stack522 ; CHECK-NEXT: RETURN implicit-def $arguments523...524