1# RUN: llc -run-pass wasm-reg-stackify %s -o - | FileCheck %s 2 3# Tests for DBG_VALUE hanlding in RegStackify + DebugValueManager 4 5--- | 6 target triple = "wasm32-unknown-unknown" 7 8 declare void @use(i32) 9 declare void @use_2(i32, i32) 10 11 define void @sink_simple() !dbg !6 { 12 call void @llvm.dbg.value(metadata i32 0, metadata !5, metadata !DIExpression()), !dbg !10 13 call void @llvm.dbg.value(metadata i32 0, metadata !11, metadata !DIExpression()), !dbg !10 14 call void @llvm.dbg.value(metadata i32 0, metadata !12, metadata !DIExpression()), !dbg !10 15 call void @llvm.dbg.value(metadata i32 0, metadata !13, metadata !DIExpression()), !dbg !10 16 ret void 17 } 18 define void @sink_non_consecutive() !dbg !14 { 19 unreachable 20 } 21 define void @dont_sink_above_def() !dbg !15 { 22 unreachable 23 } 24 define void @sink_to_same_place() !dbg !16 { 25 unreachable 26 } 27 define void @cannot_sink_across_same_variable() !dbg !17 { 28 unreachable 29 } 30 define void @cannot_sink_across_same_variable2() !dbg !18 { 31 unreachable 32 } 33 define void @can_sink_across_same_variable_with_same_const() !dbg !19 { 34 unreachable 35 } 36 define void @sink_multiple_defs() !dbg !20 { 37 unreachable 38 } 39 define void @clone_same_bb() !dbg !21 { 40 unreachable 41 } 42 define void @clone_different_bb() !dbg !22 { 43 unreachable 44 } 45 define void @tee_with_two_use_insts() !dbg !23 { 46 unreachable 47 } 48 define void @tee_with_one_inst_with_two_uses() !dbg !24 { 49 unreachable 50 } 51 declare void @llvm.dbg.value(metadata, metadata, metadata) 52 53 !llvm.dbg.cu = !{!0} 54 !llvm.module.flags = !{!2, !3, !4} 55 56 ; Note the current mapping variable metadata and their names, which we will 57 ; use in all functions in ths file: 58 ; - "var_a" / VAR_A: !5 59 ; - "var_b" / VAR_B: !11 60 ; - "var_c" / VAR_C: !12 61 ; - "var_d" / VAR_D: !13 62 ; We will use VAR_? in the CHECK lines for robustness in case of metadata 63 ; renumbering, but currently in mir tests we cannot use variable names like 64 ; "var_a" directly in the input, which can be confusing to read. 65 66 !0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, emissionKind: FullDebug) 67 !1 = !DIFile(filename: "test.c", directory: "") 68 !2 = !{i32 7, !"Dwarf Version", i32 5} 69 !3 = !{i32 2, !"Debug Info Version", i32 3} 70 !4 = !{i32 1, !"wchar_size", i32 4} 71 !5 = !DILocalVariable(name: "var_a", scope: !6, file: !1, line: 2, type: !9) 72 ; CHECK: ![[VAR_A:[0-9]+]] = !DILocalVariable(name: "var_a" 73 !6 = distinct !DISubprogram(name: "sink_simple", scope: !1, file: !1, line: 1, type: !7, scopeLine: 1, unit: !0) 74 !7 = !DISubroutineType(types: !8) 75 !8 = !{null} 76 !9 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) 77 !10 = !DILocation(line: 0, scope: !6) 78 !11 = !DILocalVariable(name: "var_b", scope: !6, file: !1, line: 2, type: !9) 79 ; CHECK: ![[VAR_B:[0-9]+]] = !DILocalVariable(name: "var_b" 80 !12 = !DILocalVariable(name: "var_c", scope: !6, file: !1, line: 2, type: !9) 81 ; CHECK: ![[VAR_C:[0-9]+]] = !DILocalVariable(name: "var_c" 82 !13 = !DILocalVariable(name: "var_d", scope: !6, file: !1, line: 2, type: !9) 83 ; CHECK: ![[VAR_D:[0-9]+]] = !DILocalVariable(name: "var_d" 84 !14 = distinct !DISubprogram(name: "sink_non_consecutive", scope: !1, file: !1, line: 1, type: !7, scopeLine: 1, unit: !0) 85 !15 = distinct !DISubprogram(name: "dont_sink_above_def", scope: !1, file: !1, line: 1, type: !7, scopeLine: 1, unit: !0) 86 !16 = distinct !DISubprogram(name: "sink_to_same_place", scope: !1, file: !1, line: 1, type: !7, scopeLine: 1, unit: !0) 87 !17 = distinct !DISubprogram(name: "cannot_sink_across_same_variable", scope: !1, file: !1, line: 1, type: !7, scopeLine: 1, unit: !0) 88 !18 = distinct !DISubprogram(name: "cannot_sink_across_same_variable2", scope: !1, file: !1, line: 1, type: !7, scopeLine: 1, unit: !0) 89 !19 = distinct !DISubprogram(name: "can_sink_across_same_variable_with_same_const", scope: !1, file: !1, line: 1, type: !7, scopeLine: 1, unit: !0) 90 !20 = distinct !DISubprogram(name: "sink_multiple_defs", scope: !1, file: !1, line: 1, type: !7, scopeLine: 1, unit: !0) 91 !21 = distinct !DISubprogram(name: "clone_same_bb", scope: !1, file: !1, line: 1, type: !7, scopeLine: 1, unit: !0) 92 !22 = distinct !DISubprogram(name: "clone_different_bb", scope: !1, file: !1, line: 1, type: !7, scopeLine: 1, unit: !0) 93 !23 = distinct !DISubprogram(name: "tee_with_two_use_insts", scope: !1, file: !1, line: 1, type: !7, scopeLine: 1, unit: !0) 94 !24 = distinct !DISubprogram(name: "tee_with_one_inst_with_two_uses", scope: !1, file: !1, line: 1, type: !7, scopeLine: 1, unit: !0) 95... 96 97--- 98# A simple sinking example. 99# '%0 = CONST_I32 1' will sink to the place before 'CALL %use', and the two 100# DBG_VALUEs will sink with it, leaving the original DBG_VALUEs to be set to 101# undef (= DBG_VALUE $noreg). 102# CHECK-LABEL: name: sink_simple 103name: sink_simple 104liveins: 105 - { reg: '$arguments' } 106tracksRegLiveness: true 107body: | 108 bb.0: 109 liveins: $arguments 110 %0:i32 = CONST_I32 1, implicit-def $arguments 111 DBG_VALUE %0:i32, $noreg, !5, !DIExpression(), debug-location !10 112 DBG_VALUE %0:i32, $noreg, !11, !DIExpression(), debug-location !10 113 NOP implicit-def $arguments 114 CALL @use, %0:i32, implicit-def $arguments 115 RETURN implicit-def $arguments 116 117 ; CHECK: DBG_VALUE $noreg, $noreg, ![[VAR_A]], !DIExpression() 118 ; CHECK-NEXT: DBG_VALUE $noreg, $noreg, ![[VAR_B]], !DIExpression() 119 ; CHECK-NEXT: NOP implicit-def $arguments 120 ; CHECK-NEXT: %0:i32 = CONST_I32 1, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack 121 ; CHECK-NEXT: DBG_VALUE %0, $noreg, ![[VAR_A]], !DIExpression() 122 ; CHECK-NEXT: DBG_VALUE %0, $noreg, ![[VAR_B]], !DIExpression() 123 ; CHECK-NEXT: CALL @use, %0, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack 124 ; CHECK-NEXT: RETURN implicit-def $arguments 125... 126 127--- 128# Sinking when DBG_VALUEs are non-consecutive. 129# '%0 = CONST_I32 1' will sink to the place before 'CALL %use', and the two 130# DBG_VALUEs will sink with it, even though they are not consecutive. The 131# original DBG_VALUEs will be set to undef. 132# CHECK-LABEL: name: sink_non_consecutive 133name: sink_non_consecutive 134liveins: 135 - { reg: '$arguments' } 136tracksRegLiveness: true 137body: | 138 bb.0: 139 liveins: $arguments 140 %0:i32 = CONST_I32 1, implicit-def $arguments 141 DBG_VALUE %0:i32, $noreg, !5, !DIExpression(), debug-location !10 142 NOP implicit-def $arguments 143 DBG_VALUE %0:i32, $noreg, !11, !DIExpression(), debug-location !10 144 NOP implicit-def $arguments 145 CALL @use, %0:i32, implicit-def $arguments 146 RETURN implicit-def $arguments 147 148 ; CHECK: DBG_VALUE $noreg, $noreg, ![[VAR_A]], !DIExpression() 149 ; CHECK-NEXT: NOP implicit-def $arguments 150 ; CHECK-NEXT: DBG_VALUE $noreg, $noreg, ![[VAR_B]], !DIExpression() 151 ; CHECK-NEXT: NOP implicit-def $arguments 152 ; CHECK-NEXT: %0:i32 = CONST_I32 1, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack 153 ; CHECK-NEXT: DBG_VALUE %0, $noreg, ![[VAR_A]], !DIExpression() 154 ; CHECK-NEXT: DBG_VALUE %0, $noreg, ![[VAR_B]], !DIExpression() 155 ; CHECK-NEXT: CALL @use, %0, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack 156 ; CHECK-NEXT: RETURN implicit-def $arguments 157... 158 159--- 160# Only DBG_VALUEs following a def should be sunk together. 161# '%0 = CONST_I32 1' will sink to the place before 'CALL %use', but the 162# DBG_VALUE above it should be untouched. 163# CHECK-LABEL: name: dont_sink_above_def 164name: dont_sink_above_def 165liveins: 166 - { reg: '$arguments' } 167tracksRegLiveness: true 168body: | 169 bb.0: 170 liveins: $arguments 171 DBG_VALUE %0:i32, $noreg, !5, !DIExpression(), debug-location !10 172 %0:i32 = CONST_I32 1, implicit-def $arguments 173 NOP implicit-def $arguments 174 CALL @use, %0:i32, implicit-def $arguments 175 RETURN implicit-def $arguments 176 177 ; CHECK: DBG_VALUE %0, $noreg, ![[VAR_A]], !DIExpression() 178 ; CHECK-NEXT: NOP implicit-def $arguments 179 ; CHECK-NEXT: %0:i32 = CONST_I32 1, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack 180 ; CHECK-NEXT: CALL @use, %0, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack 181 ; CHECK-NEXT: RETURN implicit-def $arguments 182... 183 184--- 185# A sink no-op case. 186# '%0 = CONST_I32 1' will sink to the place before 'CALL %use', but it's already 187# right before the CALL so it should be effectively a no-op. But currently 188# sinking happens anyway so this will create unnecessary two undef DBG_VALUEs. 189# This increases the number of DBG_VALUEs but doesn't hurt the coverage or 190# generate incorrect debug info. TODO Improve this? 191# CHECK-LABEL: name: sink_to_same_place 192name: sink_to_same_place 193liveins: 194 - { reg: '$arguments' } 195tracksRegLiveness: true 196body: | 197 bb.0: 198 liveins: $arguments 199 %0:i32 = CONST_I32 1, implicit-def $arguments 200 DBG_VALUE %0:i32, $noreg, !5, !DIExpression(), debug-location !10 201 DBG_VALUE %0:i32, $noreg, !11, !DIExpression(), debug-location !10 202 CALL @use, %0:i32, implicit-def $arguments 203 RETURN implicit-def $arguments 204 205 ; CHECK: %0:i32 = CONST_I32 1, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack 206 ; CHECK-NEXT: DBG_VALUE %0, $noreg, ![[VAR_A]], !DIExpression() 207 ; CHECK-NEXT: DBG_VALUE %0, $noreg, ![[VAR_B]], !DIExpression() 208 ; CHECK-NEXT: CALL @use, %0, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack 209 ; CHECK-NEXT: RETURN implicit-def $arguments 210... 211 212--- 213# A DBG_VALUE cannot be sunk across another DBG_VALUE that has the same 214# DebugVariable, because it will reorder assignments. 215# '%0 = CONST_I32 1' will sink to the place before 'CALL %use'. But from the two 216# DBG_VALUEs following it, only the DBG_VALUE for "var_b" can sink with it, 217# because there is another 'DBG_VALUE 10' for "var_a" in the middle. 218# CHECK-LABEL: name: cannot_sink_across_same_variable 219name: cannot_sink_across_same_variable 220liveins: 221 - { reg: '$arguments' } 222tracksRegLiveness: true 223body: | 224 bb.0: 225 liveins: $arguments 226 %0:i32 = CONST_I32 1, implicit-def $arguments 227 DBG_VALUE %0:i32, $noreg, !5, !DIExpression(), debug-location !10 228 DBG_VALUE %0:i32, $noreg, !11, !DIExpression(), debug-location !10 229 DBG_VALUE 10, $noreg, !5, !DIExpression(), debug-location !10 230 NOP implicit-def $arguments 231 CALL @use, %0:i32, implicit-def $arguments 232 RETURN implicit-def $arguments 233 234 ; CHECK: DBG_VALUE $noreg, $noreg, ![[VAR_A]], !DIExpression() 235 ; CHECK-NEXT: DBG_VALUE $noreg, $noreg, ![[VAR_B]], !DIExpression() 236 ; CHECK-NEXT: DBG_VALUE 10, $noreg, ![[VAR_A]], !DIExpression() 237 ; CHECK-NEXT: NOP implicit-def $arguments 238 ; CHECK-NEXT: %0:i32 = CONST_I32 1, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack 239 ; CHECK-NEXT: DBG_VALUE %0, $noreg, ![[VAR_B]], !DIExpression() 240 ; CHECK-NEXT: CALL @use, %0, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack 241 ; CHECK-NEXT: RETURN implicit-def $arguments 242... 243 244--- 245# Another case in which a DBG_VALUE cannot be sunk across another DBG_VALUE with 246# the same DebugVariable, because it will reorder assignments. 247# '%0 = CONST_I32 1' will sink to the place before 'CALL %use'. But from the two 248# DBG_VALUEs following it, only the DBG_VALUE for "var_b" can sink with it, 249# because there is another 'DBG_VALUE %1, "var_a"' in the middle. 250# CHECK-LABEL: name: cannot_sink_across_same_variable2 251name: cannot_sink_across_same_variable2 252liveins: 253 - { reg: '$arguments' } 254tracksRegLiveness: true 255body: | 256 bb.0: 257 liveins: $arguments 258 %0:i32 = CONST_I32 1, implicit-def $arguments 259 %1:i32 = CONST_I32 2, implicit-def $arguments 260 DBG_VALUE %0:i32, $noreg, !5, !DIExpression(), debug-location !10 261 DBG_VALUE %0:i32, $noreg, !11, !DIExpression(), debug-location !10 262 DBG_VALUE %1:i32, $noreg, !5, !DIExpression(), debug-location !10 263 NOP implicit-def $arguments 264 CALL @use, %0:i32, implicit-def $arguments 265 RETURN implicit-def $arguments 266 267 ; CHECK: %1:i32 = CONST_I32 2, implicit-def $arguments 268 ; CHECK-NEXT: DBG_VALUE $noreg, $noreg, ![[VAR_A]], !DIExpression() 269 ; CHECK-NEXT: DBG_VALUE $noreg, $noreg, ![[VAR_B]], !DIExpression() 270 ; CHECK-NEXT: DBG_VALUE %1, $noreg, ![[VAR_A]], !DIExpression() 271 ; CHECK-NEXT: NOP implicit-def $arguments 272 ; CHECK-NEXT: %0:i32 = CONST_I32 1, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack 273 ; CHECK-NEXT: DBG_VALUE %0, $noreg, ![[VAR_B]], !DIExpression() 274 ; CHECK-NEXT: CALL @use, %0, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack 275 ; CHECK-NEXT: RETURN implicit-def $arguments 276... 277 278--- 279# There is a exception in which a DBG_VALUE can be sunk across another DBG_VALUE 280# with the same DebugVariable: when the interfering DBG_VALUE refers to the same 281# CONST_[I32/I64/F32/F64] instruction, in which case we don't reorder 282# assignments. 283# 284# This is the same test with the previous one with one difference: %1 has the 285# same CONST instruction with %0 'CONST_I32 1'. We can sink the DBG_VALUE for 286# "var_a" here as well. 287# CHECK-LABEL: name: can_sink_across_same_variable_with_same_const 288name: can_sink_across_same_variable_with_same_const 289liveins: 290 - { reg: '$arguments' } 291tracksRegLiveness: true 292body: | 293 bb.0: 294 liveins: $arguments 295 %0:i32 = CONST_I32 1, implicit-def $arguments 296 %1:i32 = CONST_I32 1, implicit-def $arguments ; Same CONST_I32 297 DBG_VALUE %0:i32, $noreg, !5, !DIExpression(), debug-location !10 298 DBG_VALUE %0:i32, $noreg, !11, !DIExpression(), debug-location !10 299 DBG_VALUE %1:i32, $noreg, !5, !DIExpression(), debug-location !10 300 NOP implicit-def $arguments 301 CALL @use, %0:i32, implicit-def $arguments 302 RETURN implicit-def $arguments 303 304 ; CHECK: %1:i32 = CONST_I32 1, implicit-def $arguments 305 ; CHECK-NEXT: DBG_VALUE $noreg, $noreg, ![[VAR_A]], !DIExpression() 306 ; CHECK-NEXT: DBG_VALUE $noreg, $noreg, ![[VAR_B]], !DIExpression() 307 ; CHECK-NEXT: DBG_VALUE %1, $noreg, ![[VAR_A]], !DIExpression() 308 ; CHECK-NEXT: NOP implicit-def $arguments 309 ; CHECK-NEXT: %0:i32 = CONST_I32 1, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack 310 ; CHECK-NEXT: DBG_VALUE %0, $noreg, ![[VAR_A]], !DIExpression() 311 ; CHECK-NEXT: DBG_VALUE %0, $noreg, ![[VAR_B]], !DIExpression() 312 ; CHECK-NEXT: CALL @use, %0, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack 313 ; CHECK-NEXT: RETURN implicit-def $arguments 314... 315 316--- 317# Both %0 and %1 will be sunk to the place before ADD_I32. DBG_VALUEs associated 318# with those two defs will be sunk as well, leaving the original DBG_VALUEs set 319# to undef. 320# CHECK-LABEL: name: sink_multiple_defs 321name: sink_multiple_defs 322liveins: 323 - { reg: '$arguments' } 324tracksRegLiveness: true 325body: | 326 bb.0: 327 liveins: $arguments 328 %0:i32 = CONST_I32 1, implicit-def $arguments 329 DBG_VALUE %0:i32, $noreg, !5, !DIExpression(), debug-location !10 330 DBG_VALUE %0:i32, $noreg, !11, !DIExpression(), debug-location !10 331 NOP implicit-def $arguments 332 %1:i32 = CONST_I32 2, implicit-def $arguments 333 DBG_VALUE %1:i32, $noreg, !12, !DIExpression(), debug-location !10 334 DBG_VALUE %1:i32, $noreg, !13, !DIExpression(), debug-location !10 335 NOP implicit-def $arguments 336 %2:i32 = ADD_I32 %0:i32, %1:i32, implicit-def $arguments 337 RETURN implicit-def $arguments 338 339 ; CHECK: DBG_VALUE $noreg, $noreg, ![[VAR_A]], !DIExpression() 340 ; CHECK-NEXT: DBG_VALUE $noreg, $noreg, ![[VAR_B]], !DIExpression() 341 ; CHECK-NEXT: NOP implicit-def $arguments 342 ; CHECK-NEXT: DBG_VALUE $noreg, $noreg, ![[VAR_C]], !DIExpression() 343 ; CHECK-NEXT: DBG_VALUE $noreg, $noreg, ![[VAR_D]], !DIExpression() 344 ; CHECK-NEXT: NOP implicit-def $arguments 345 ; CHECK-NEXT: %0:i32 = CONST_I32 1, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack 346 ; CHECK-NEXT: DBG_VALUE %0, $noreg, ![[VAR_A]], !DIExpression() 347 ; CHECK-NEXT: DBG_VALUE %0, $noreg, ![[VAR_B]], !DIExpression() 348 ; CHECK-NEXT: %1:i32 = CONST_I32 2, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack 349 ; CHECK-NEXT: DBG_VALUE %1, $noreg, ![[VAR_C]], !DIExpression() 350 ; CHECK-NEXT: DBG_VALUE %1, $noreg, ![[VAR_D]], !DIExpression() 351 ; CHECK-NEXT: dead %2:i32 = ADD_I32 %0, %1, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack 352 ; CHECK-NEXT: RETURN implicit-def $arguments 353... 354 355--- 356# A simple cloning example. 357# When processing the second 'CALL @use', because %0 has multiple uses, the def 358# '%0 = CONST_I32 1' is cloned before the CALL, along with its DBG_VALUEs. And 359# then when processing the first 'CALL @use', by that time %0 has only one use 360# remaining, so it is just sink with the DBG_VALUEs, leaving the original 361# DBG_VALUEs undef. 362# CHECK-LABEL: name: clone_same_bb 363name: clone_same_bb 364liveins: 365 - { reg: '$arguments' } 366tracksRegLiveness: true 367body: | 368 bb.0: 369 liveins: $arguments 370 %0:i32 = CONST_I32 1, implicit-def $arguments 371 DBG_VALUE %0:i32, $noreg, !5, !DIExpression(), debug-location !10 372 DBG_VALUE %0:i32, $noreg, !11, !DIExpression(), debug-location !10 373 NOP implicit-def $arguments 374 CALL @use, %0:i32, implicit-def $arguments 375 CALL @use, %0:i32, implicit-def $arguments 376 RETURN implicit-def $arguments 377 378 ; CHECK: DBG_VALUE $noreg, $noreg, ![[VAR_A]], !DIExpression() 379 ; CHECK-NEXT: DBG_VALUE $noreg, $noreg, ![[VAR_B]], !DIExpression() 380 ; CHECK-NEXT: NOP implicit-def $arguments 381 ; CHECK-NEXT: %0:i32 = CONST_I32 1, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack 382 ; CHECK-NEXT: DBG_VALUE %0, $noreg, ![[VAR_A]], !DIExpression() 383 ; CHECK-NEXT: DBG_VALUE %0, $noreg, ![[VAR_B]], !DIExpression() 384 ; CHECK-NEXT: CALL @use, %0, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack 385 ; CHECK-NEXT: %1:i32 = CONST_I32 1, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack 386 ; CHECK-NEXT: DBG_VALUE %1, $noreg, ![[VAR_A]], !DIExpression() 387 ; CHECK-NEXT: DBG_VALUE %1, $noreg, ![[VAR_B]], !DIExpression() 388 ; CHECK-NEXT: CALL @use, %1, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack 389 ; CHECK-NEXT: RETURN implicit-def $arguments 390... 391 392--- 393# Cloning across different BBs. 394# First, when bb.0's 'CALL @use' is procssed, '%0 = CONST_I32 1' and its 395# DBG_VALUEs are cloned before the CALL. And when bb.1's 'CALL @use' is 396# processed, '%0 = CONST_I32 1' and its DBG_VALUEs are cloned to bb.1 this time. 397# Even though there are (previously cloned) DBG_VALUEs for "var_a" and "var_b" 398# in the middle, it's fine because they point to the same 'CONST_I32 1' 399# instruction. 400# After the second cloning, the original '%0 = CONST_I32 1' is removed because 401# it doesn't have any users anymore, leaving its original DBG_VALUEs as undef. 402# CHECK-LABEL: name: clone_different_bb 403name: clone_different_bb 404liveins: 405 - { reg: '$arguments' } 406tracksRegLiveness: true 407body: | 408 bb.0: 409 successors: %bb.1 410 liveins: $arguments 411 %0:i32 = CONST_I32 1, implicit-def $arguments 412 DBG_VALUE %0:i32, $noreg, !5, !DIExpression(), debug-location !10 413 DBG_VALUE %0:i32, $noreg, !11, !DIExpression(), debug-location !10 414 NOP implicit-def $arguments 415 CALL @use, %0:i32, implicit-def $arguments 416 BR %bb.1, implicit-def $arguments 417 418 ; CHECK: bb.0: 419 ; CHECK: DBG_VALUE $noreg, $noreg, ![[VAR_A]], !DIExpression() 420 ; CHECK-NEXT: DBG_VALUE $noreg, $noreg, ![[VAR_B]], !DIExpression() 421 ; CHECK-NEXT: NOP implicit-def $arguments 422 ; CHECK-NEXT: %1:i32 = CONST_I32 1, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack 423 ; CHECK-NEXT: DBG_VALUE %1, $noreg, ![[VAR_A]], !DIExpression() 424 ; CHECK-NEXT: DBG_VALUE %1, $noreg, ![[VAR_B]], !DIExpression() 425 ; CHECK-NEXT: CALL @use, %1, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack 426 ; CHECK-NEXT: BR %bb.1, implicit-def $arguments 427 428 bb.1: 429 ; predecessors: %bb.0 430 CALL @use, %0:i32, implicit-def $arguments 431 RETURN implicit-def $arguments 432 433 ; CHECK: bb.1: 434 ; CHECK: %2:i32 = CONST_I32 1, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack 435 ; CHECK-NEXT: DBG_VALUE %2, $noreg, ![[VAR_A]], !DIExpression() 436 ; CHECK-NEXT: DBG_VALUE %2, $noreg, ![[VAR_B]], !DIExpression() 437 ; CHECK-NEXT: CALL @use, %2, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack 438 ; CHECK-NEXT: RETURN implicit-def $arguments 439... 440 441--- 442# TEE conversion example. 443# Convert this form: 444# Reg = INST ... // Def 445# DBG_VALUE Reg, ... 446# INST ..., Reg, ... // Insert 447# INST ..., Reg, ... 448# to 449# DefReg = INST ... // Def (to become the new Insert) 450# DBG_VALUE DefReg, ... 451# TeeReg, Reg = TEE_... DefReg 452# DBG_VALUE TeeReg, ... 453# INST ..., TeeReg, ... // Insert 454# INST ..., Reg, ... 455# CHECK-LABEL: name: tee_with_two_use_insts 456name: tee_with_two_use_insts 457liveins: 458 - { reg: '$arguments' } 459tracksRegLiveness: true 460body: | 461 bb.0: 462 liveins: $arguments 463 %0:i32 = ARGUMENT_i32 0, implicit $arguments 464 %1:i32 = ARGUMENT_i32 1, implicit $arguments 465 %2:i32 = MUL_I32 %1:i32, %0:i32, implicit-def $arguments 466 DBG_VALUE %2:i32, $noreg, !5, !DIExpression(), debug-location !10 467 DBG_VALUE %2:i32, $noreg, !11, !DIExpression(), debug-location !10 468 NOP implicit-def $arguments 469 CALL @use, %2:i32, implicit-def $arguments 470 CALL @use, %2:i32, implicit-def $arguments 471 RETURN implicit-def $arguments 472 473 ; CHECK: %0:i32 = ARGUMENT_i32 0, implicit $arguments 474 ; CHECK-NEXT: %1:i32 = ARGUMENT_i32 1, implicit $arguments 475 ; CHECK-NEXT: DBG_VALUE $noreg, $noreg, ![[VAR_A]], !DIExpression() 476 ; CHECK-NEXT: DBG_VALUE $noreg, $noreg, ![[VAR_B]], !DIExpression() 477 ; CHECK-NEXT: NOP implicit-def $arguments 478 ; CHECK-NEXT: %4:i32 = MUL_I32 %1, %0, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack 479 ; CHECK-NEXT: DBG_VALUE %4, $noreg, ![[VAR_A]], !DIExpression() 480 ; CHECK-NEXT: DBG_VALUE %4, $noreg, ![[VAR_B]], !DIExpression() 481 ; CHECK-NEXT: %3:i32, %2:i32 = TEE_I32 %4, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack 482 ; CHECK-NEXT: DBG_VALUE %3, $noreg, ![[VAR_A]], !DIExpression() 483 ; CHECK-NEXT: DBG_VALUE %3, $noreg, ![[VAR_B]], !DIExpression() 484 ; CHECK-NEXT: CALL @use, %3, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack 485 ; CHECK-NEXT: CALL @use, %2, implicit-def $arguments 486 ; CHECK-NEXT: RETURN implicit-def $arguments 487... 488 489--- 490# Another TEE conversion example. The previous example had two instructions 491# that use a single register, whereas this has one instructions that has two 492# same use operands. The resulting transformation is the same. 493# CHECK-LABEL: name: tee_with_one_inst_with_two_uses 494name: tee_with_one_inst_with_two_uses 495liveins: 496 - { reg: '$arguments' } 497tracksRegLiveness: true 498body: | 499 bb.0: 500 liveins: $arguments 501 %0:i32 = ARGUMENT_i32 0, implicit $arguments 502 %1:i32 = ARGUMENT_i32 1, implicit $arguments 503 %2:i32 = MUL_I32 %1:i32, %0:i32, implicit-def $arguments 504 DBG_VALUE %2:i32, $noreg, !5, !DIExpression(), debug-location !10 505 DBG_VALUE %2:i32, $noreg, !11, !DIExpression(), debug-location !10 506 NOP implicit-def $arguments 507 CALL @use_2, %2:i32, %2:i32, implicit-def $arguments 508 RETURN implicit-def $arguments 509 510 ; CHECK: %0:i32 = ARGUMENT_i32 0, implicit $arguments 511 ; CHECK-NEXT: %1:i32 = ARGUMENT_i32 1, implicit $arguments 512 ; CHECK-NEXT: DBG_VALUE $noreg, $noreg, ![[VAR_A]], !DIExpression() 513 ; CHECK-NEXT: DBG_VALUE $noreg, $noreg, ![[VAR_B]], !DIExpression() 514 ; CHECK-NEXT: NOP implicit-def $arguments 515 ; CHECK-NEXT: %4:i32 = MUL_I32 %1, %0, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack 516 ; CHECK-NEXT: DBG_VALUE %4, $noreg, ![[VAR_A]], !DIExpression() 517 ; CHECK-NEXT: DBG_VALUE %4, $noreg, ![[VAR_B]], !DIExpression() 518 ; CHECK-NEXT: %3:i32, %2:i32 = TEE_I32 %4, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack 519 ; CHECK-NEXT: DBG_VALUE %3, $noreg, ![[VAR_A]], !DIExpression() 520 ; CHECK-NEXT: DBG_VALUE %3, $noreg, ![[VAR_B]], !DIExpression() 521 ; CHECK-NEXT: CALL @use_2, %3, %2, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack 522 ; CHECK-NEXT: RETURN implicit-def $arguments 523... 524