brintos

brintos / llvm-project-archived public Read only

0
0
Text · 23.6 KiB · 230ba12 Raw
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