Index: llvm/lib/CodeGen/MachineSink.cpp =================================================================== --- llvm/lib/CodeGen/MachineSink.cpp +++ llvm/lib/CodeGen/MachineSink.cpp @@ -128,10 +128,14 @@ /// current block. DenseSet SeenDbgVars; + // A single DBG_VALUE that is to be sunk, and its original subregister. + using SinkingVar = std::pair; + /// A set of DBG_VALUEs, indexed by their DebugVariable. Refers to the /// original / non-sunk DBG_VALUE, which should be cloned to the final - /// sunk location. - using SinkingVarSet = DenseMap; + /// sunk location. The subregister the DBG_VALUE originally held is + /// stored too, as other salvage operations may change it. + using SinkingVarSet = DenseMap; /// Record of variable locations to re-create after the sinking of a /// vreg definition completes. @@ -370,15 +374,17 @@ ++DestLoc; // Collect the DBG_VALUEs being sunk and put them in a deterministic order. - using VarInstPair = std::pair; + using VarInstPair = std::pair; SmallVector InstsToSink; for (auto &SunkLoc : Def.InstsToSink) InstsToSink.push_back(SunkLoc); llvm::sort(InstsToSink); for (auto &SunkLoc : InstsToSink) { - MachineInstr *NewDbgMI = MF.CloneMachineInstr(SunkLoc.second); + SinkingVar ToSink = SunkLoc.second; + MachineInstr *NewDbgMI = MF.CloneMachineInstr(ToSink.first); NewDbgMI->getOperand(0).setReg(VReg); + NewDbgMI->getOperand(0).setSubReg(ToSink.second); MBB->insert(DestLoc, NewDbgMI); } } @@ -1096,7 +1102,8 @@ // Debug users that don't pass any other DBG_VALUEs for this variable // can be sunk. if (!User.getInt()) - SunkDef.InstsToSink.insert({Var, DbgMI}); + SunkDef.InstsToSink.insert( + {Var, {DbgMI, DbgMI->getOperand(0).getSubReg()}}); } } Index: llvm/test/DebugInfo/MIR/X86/machinesink.mir =================================================================== --- llvm/test/DebugInfo/MIR/X86/machinesink.mir +++ llvm/test/DebugInfo/MIR/X86/machinesink.mir @@ -87,7 +87,17 @@ exit: ret void } - + + define void @test7(i32* nocapture readonly %p) local_unnamed_addr !dbg !601 { + ; Stripped + entry: + br label %nou + nou: + br label %exit + exit: + ret void + } + declare void @llvm.dbg.value(metadata, i64, metadata, metadata) !llvm.dbg.cu = !{!1} @@ -134,6 +144,11 @@ !502 = !{!503} !503 = !DILocalVariable(name: "u", arg: 1, scope: !501, file: !2, line: 2, type: !12) !504 = !DILocation(line: 1, column: 1, scope: !501) + !601 = distinct !DISubprogram(name: "test5", scope: !2, file: !2, line: 2, type: !10, isLocal: false, isDefinition: true, scopeLine: 3, flags: DIFlagPrototyped, isOptimized: true, unit: !1, retainedNodes: !602) + !602 = !{!603} + !603 = !DILocalVariable(name: "v", arg: 1, scope: !601, file: !2, line: 2, type: !12) + !604 = !DILocation(line: 1, column: 1, scope: !601) + ; CHECK: [[VARNUM:![0-9]+]] = !DILocalVariable(name: "p", ; CHECK: [[VAR2NUM:![0-9]+]] = !DILocalVariable(name: "q", @@ -141,6 +156,7 @@ ; CHECK: [[VAR4NUM:![0-9]+]] = !DILocalVariable(name: "s", ; CHECK: [[VAR5NUM:![0-9]+]] = !DILocalVariable(name: "t", ; CHECK: [[VAR6NUM:![0-9]+]] = !DILocalVariable(name: "u", + ; CHECK: [[VAR7NUM:![0-9]+]] = !DILocalVariable(name: "v", ... --- @@ -467,3 +483,67 @@ $rax = MOV64ri 1 RET 0 ... +--- +name: test7 +# CHECK-LABEL: name: test7 +tracksRegLiveness: true +liveins: + - { reg: '$rdi', virtual-reg: '%2' } + - { reg: '$rsi', virtual-reg: '%2' } +body: | + bb.0.entry: + ; CHECK-LABEL: bb.0.entry: + ; CHECK-NOT: DBG_VALUE + successors: %bb.3 + liveins: $rdi, $esi + JMP_1 %bb.3 + + bb.1: + successors: %bb.2, %bb.4 + liveins: $rdi, $esi + + ; Register %5 sinks through this block; the DBG_VALUE should become $noreg + ; CHECK-LABEL: bb.1: + ; CHECK: DBG_VALUE $noreg, $noreg, [[VAR7NUM]], !DIExpression() + + CMP32ri $esi, 1, implicit-def $eflags + DBG_VALUE %5, $noreg, !603, !17, debug-location !604 + JCC_1 %bb.2, 4, implicit $eflags + JMP_1 %bb.4 + + bb.2: + successors: %bb.4 + + ; Both copies should sink into this block, and we should sink the DBG_VALUE + ; from %bb.1 into this one too. The DBG_VALUE should not pick up a + ; subregister along the way. + ; CHECK-LABEL: bb.2: + ; CHECK: %[[COPYDEST1:[0-9]+]]:gr32 = COPY %[[COPYSRC1:[0-9]+]].sub_32bit + ; CHECK-NEXT: %[[COPYDEST2:[0-9]+]]:gr32 = COPY %[[COPYDEST1]] + ; CHECK-NEXT: DBG_VALUE %[[COPYDEST2]], $noreg, [[VAR7NUM]], !DIExpression() + ; CHECK-NEXT: ADD32ri + + %1:gr32 = ADD32ri8 %5, 4, implicit-def dead $eflags + JMP_1 %bb.4 + + bb.3: + successors: %bb.1, %bb.4 + liveins: $rdi, $esi + + ; CHECK-LABEL: bb.3: + ; CHECK: %[[COPYSRC1]]:gr64 = COPY $rdi + ; CHECK: DBG_VALUE $noreg, $noreg, [[VAR7NUM]], !DIExpression() + + %2:gr64 = COPY $rdi + %12:gr32 = COPY %2.sub_32bit + %5:gr32 = COPY %12 + CMP32ri $esi, 0, implicit-def $eflags + DBG_VALUE %5, $noreg, !603, !17, debug-location !604 + JCC_1 %bb.1, 4, implicit $eflags + JMP_1 %bb.4 + + bb.4: + liveins: $rdi, $esi + $eax = COPY killed $rdi + RET 0 +...