diff --git a/llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.cpp b/llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.cpp --- a/llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.cpp +++ b/llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.cpp @@ -764,8 +764,8 @@ const DIExpression *Expr = Properties.DIExpr; if (!MLoc) { // No location -> DBG_VALUE $noreg - MIB.addReg(0, RegState::Debug); - MIB.addReg(0, RegState::Debug); + MIB.addReg(0); + MIB.addReg(0); } else if (LocIdxToLocID[*MLoc] >= NumRegs) { unsigned LocID = LocIdxToLocID[*MLoc]; const SpillLoc &Spill = SpillLocs[LocID - NumRegs + 1]; @@ -774,15 +774,15 @@ Expr = TRI->prependOffsetExpression(Expr, DIExpression::ApplyOffset, Spill.SpillOffset); unsigned Base = Spill.SpillBase; - MIB.addReg(Base, RegState::Debug); + MIB.addReg(Base); MIB.addImm(0); } else { unsigned LocID = LocIdxToLocID[*MLoc]; - MIB.addReg(LocID, RegState::Debug); + MIB.addReg(LocID); if (Properties.Indirect) MIB.addImm(0); else - MIB.addReg(0, RegState::Debug); + MIB.addReg(0); } MIB.addMetadata(Var.getVariable()); @@ -1220,7 +1220,6 @@ DIExpression::prepend(Prop.DIExpr, DIExpression::EntryValue); Register Reg = MTracker->LocIdxToLocID[Num.getLoc()]; MachineOperand MO = MachineOperand::CreateReg(Reg, false); - MO.setIsDebug(true); PendingDbgValues.push_back(emitMOLoc(MO, Var, {NewExpr, Prop.Indirect})); return true; diff --git a/llvm/lib/CodeGen/LiveDebugValues/VarLocBasedImpl.cpp b/llvm/lib/CodeGen/LiveDebugValues/VarLocBasedImpl.cpp --- a/llvm/lib/CodeGen/LiveDebugValues/VarLocBasedImpl.cpp +++ b/llvm/lib/CodeGen/LiveDebugValues/VarLocBasedImpl.cpp @@ -546,7 +546,6 @@ EVKind == EntryValueLocKind::EntryValueKind ? Orig.getReg() : Register(Loc.RegNo), false)); - MOs.back().setIsDebug(); break; case MachineLocKind::SpillLocKind: { // Spills are indirect DBG_VALUEs, with a base register and offset. @@ -568,7 +567,6 @@ DIExpr = DIExpression::appendOpsToArg(DIExpr, Ops, I); } MOs.push_back(MachineOperand::CreateReg(Base, false)); - MOs.back().setIsDebug(); break; } case MachineLocKind::ImmediateKind: { diff --git a/llvm/lib/CodeGen/MIRParser/MIParser.cpp b/llvm/lib/CodeGen/MIRParser/MIParser.cpp --- a/llvm/lib/CodeGen/MIRParser/MIParser.cpp +++ b/llvm/lib/CodeGen/MIRParser/MIParser.cpp @@ -1011,10 +1011,6 @@ Optional TiedDefIdx; if (parseMachineOperandAndTargetFlags(OpCode, Operands.size(), MO, TiedDefIdx)) return true; - if ((OpCode == TargetOpcode::DBG_VALUE || - OpCode == TargetOpcode::DBG_VALUE_LIST) && - MO.isReg()) - MO.setIsDebug(); Operands.push_back( ParsedMachineOperand(MO, Loc, Token.location(), TiedDefIdx)); if (Token.isNewlineOrEOF() || Token.is(MIToken::coloncolon) || diff --git a/llvm/lib/CodeGen/MachineFunction.cpp b/llvm/lib/CodeGen/MachineFunction.cpp --- a/llvm/lib/CodeGen/MachineFunction.cpp +++ b/llvm/lib/CodeGen/MachineFunction.cpp @@ -1158,7 +1158,7 @@ // Create DBG_PHI for specified physreg. auto Builder = BuildMI(InsertBB, InsertBB.getFirstNonPHI(), DebugLoc(), TII.get(TargetOpcode::DBG_PHI)); - Builder.addReg(State.first, RegState::Debug); + Builder.addReg(State.first); unsigned NewNum = getNewDebugInstrNum(); Builder.addImm(NewNum); return ApplySubregisters({NewNum, 0u}); @@ -1171,7 +1171,6 @@ const MCInstrDesc &RefII = TII->get(TargetOpcode::DBG_VALUE); MI.setDesc(RefII); MI.getOperand(1).ChangeToRegister(0, false); - MI.getOperand(0).setIsDebug(); }; if (!useDebugInstrRef()) diff --git a/llvm/lib/CodeGen/MachineInstr.cpp b/llvm/lib/CodeGen/MachineInstr.cpp --- a/llvm/lib/CodeGen/MachineInstr.cpp +++ b/llvm/lib/CodeGen/MachineInstr.cpp @@ -294,6 +294,9 @@ if (MCID->getOperandConstraint(OpNo, MCOI::EARLY_CLOBBER) != -1) NewMO->setIsEarlyClobber(true); } + // Ensure debug instructions set RegState::Debug on register uses. + if (NewMO->isUse() && isDebugInstr()) + NewMO->setIsDebug(); } } @@ -2111,11 +2114,11 @@ assert(cast(Expr)->isValid() && "not an expression"); assert(cast(Variable)->isValidLocationForIntrinsic(DL) && "Expected inlined-at fields to agree"); - auto MIB = BuildMI(MF, DL, MCID).addReg(Reg, RegState::Debug); + auto MIB = BuildMI(MF, DL, MCID).addReg(Reg); if (IsIndirect) MIB.addImm(0U); else - MIB.addReg(0U, RegState::Debug); + MIB.addReg(0U); return MIB.addMetadata(Variable).addMetadata(Expr); } @@ -2134,7 +2137,7 @@ if (IsIndirect) MIB.addImm(0U); else - MIB.addReg(0U, RegState::Debug); + MIB.addReg(0U); return MIB.addMetadata(Variable).addMetadata(Expr); } @@ -2153,7 +2156,7 @@ MIB.addMetadata(Variable).addMetadata(Expr); for (const MachineOperand &MO : MOs) if (MO.isReg()) - MIB.addReg(MO.getReg(), RegState::Debug); + MIB.addReg(MO.getReg()); else MIB.add(MO); return MIB; diff --git a/llvm/lib/CodeGen/MachineOperand.cpp b/llvm/lib/CodeGen/MachineOperand.cpp --- a/llvm/lib/CodeGen/MachineOperand.cpp +++ b/llvm/lib/CodeGen/MachineOperand.cpp @@ -250,6 +250,11 @@ if (RegInfo && WasReg) RegInfo->removeRegOperandFromUseList(this); + // Ensure debug instructions set RegState::Debug on register uses. + const MachineInstr *MI = getParent(); + if (!isDef && MI && MI->isDebugInstr()) + isDebug = true; + // Change this to a register and set the reg#. assert(!(isDead && !isDef) && "Dead flag on non-def"); assert(!(isKill && isDef) && "Kill flag on def"); diff --git a/llvm/lib/CodeGen/MachineVerifier.cpp b/llvm/lib/CodeGen/MachineVerifier.cpp --- a/llvm/lib/CodeGen/MachineVerifier.cpp +++ b/llvm/lib/CodeGen/MachineVerifier.cpp @@ -1889,6 +1889,11 @@ switch (MO->getType()) { case MachineOperand::MO_Register: { + // Verify debug state on DBG_VALUE* instructions. Check this first because + // reg0 indicates an undefined debug value. + if (MI->isDebugValue() && !MO->isDebug()) + report("DBG_VALUE register operands must be debug", MO, MONum); + const Register Reg = MO->getReg(); if (!Reg) return; diff --git a/llvm/lib/CodeGen/PrologEpilogInserter.cpp b/llvm/lib/CodeGen/PrologEpilogInserter.cpp --- a/llvm/lib/CodeGen/PrologEpilogInserter.cpp +++ b/llvm/lib/CodeGen/PrologEpilogInserter.cpp @@ -1253,7 +1253,6 @@ StackOffset Offset = TFI->getFrameIndexReference(MF, FrameIdx, Reg); Op.ChangeToRegister(Reg, false /*isDef*/); - Op.setIsDebug(); const DIExpression *DIExpr = MI.getDebugExpression(); diff --git a/llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp b/llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp --- a/llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp @@ -722,7 +722,7 @@ MIB.addFrameIndex(Op.getFrameIx()); break; case SDDbgOperand::VREG: - MIB.addReg(Op.getVReg(), RegState::Debug); + MIB.addReg(Op.getVReg()); break; case SDDbgOperand::SDNODE: { SDValue V = SDValue(Op.getSDNode(), Op.getResNo()); @@ -862,7 +862,7 @@ DebugLoc DL = SD->getDebugLoc(); auto MIB = BuildMI(*MF, DL, TII->get(TargetOpcode::DBG_VALUE)); MIB.addReg(0U); - MIB.addReg(0U, RegState::Debug); + MIB.addReg(0U); MIB.addMetadata(Var); MIB.addMetadata(Expr); return &*MIB; @@ -898,7 +898,7 @@ if (SD->isIndirect()) MIB.addImm(0U); else - MIB.addReg(0U, RegState::Debug); + MIB.addReg(0U); return MIB.addMetadata(Var).addMetadata(Expr); } diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -5518,7 +5518,7 @@ // pointing at the VReg, which will be patched up later. auto &Inst = TII->get(TargetOpcode::DBG_INSTR_REF); auto MIB = BuildMI(MF, DL, Inst); - MIB.addReg(Reg, RegState::Debug); + MIB.addReg(Reg); MIB.addImm(0); MIB.addMetadata(Variable); auto *NewDIExpr = FragExpr; diff --git a/llvm/lib/Target/AMDGPU/SIFrameLowering.cpp b/llvm/lib/Target/AMDGPU/SIFrameLowering.cpp --- a/llvm/lib/Target/AMDGPU/SIFrameLowering.cpp +++ b/llvm/lib/Target/AMDGPU/SIFrameLowering.cpp @@ -1202,7 +1202,6 @@ if (MI.isDebugValue() && MI.getOperand(0).isFI() && SpillFIs[MI.getOperand(0).getIndex()]) { MI.getOperand(0).ChangeToRegister(Register(), false /*isDef*/); - MI.getOperand(0).setIsDebug(); } } } diff --git a/llvm/lib/Target/AMDGPU/SILowerSGPRSpills.cpp b/llvm/lib/Target/AMDGPU/SILowerSGPRSpills.cpp --- a/llvm/lib/Target/AMDGPU/SILowerSGPRSpills.cpp +++ b/llvm/lib/Target/AMDGPU/SILowerSGPRSpills.cpp @@ -369,7 +369,6 @@ if (MI.isDebugValue() && MI.getOperand(0).isFI() && SpillFIs[MI.getOperand(0).getIndex()]) { MI.getOperand(0).ChangeToRegister(Register(), false /*isDef*/); - MI.getOperand(0).setIsDebug(); } } } diff --git a/llvm/lib/Target/NVPTX/NVPTXPrologEpilogPass.cpp b/llvm/lib/Target/NVPTX/NVPTXPrologEpilogPass.cpp --- a/llvm/lib/Target/NVPTX/NVPTXPrologEpilogPass.cpp +++ b/llvm/lib/Target/NVPTX/NVPTXPrologEpilogPass.cpp @@ -74,7 +74,6 @@ auto Offset = TFI.getFrameIndexReference(MF, Op.getIndex(), Reg); Op.ChangeToRegister(Reg, /*isDef=*/false); - Op.setIsDebug(); const DIExpression *DIExpr = MI.getDebugExpression(); if (MI.isNonListDebugValue()) { DIExpr = TRI.prependOffsetExpression(MI.getDebugExpression(), DIExpression::ApplyOffset, Offset); diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyReplacePhysRegs.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyReplacePhysRegs.cpp --- a/llvm/lib/Target/WebAssembly/WebAssemblyReplacePhysRegs.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyReplacePhysRegs.cpp @@ -101,8 +101,6 @@ } } MO.setReg(VReg); - if (MO.getParent()->isDebugValue()) - MO.setIsDebug(); Changed = true; } } diff --git a/llvm/lib/Target/X86/X86FastISel.cpp b/llvm/lib/Target/X86/X86FastISel.cpp --- a/llvm/lib/Target/X86/X86FastISel.cpp +++ b/llvm/lib/Target/X86/X86FastISel.cpp @@ -2784,8 +2784,6 @@ if (!X86SelectAddress(DI->getAddress(), AM)) return false; const MCInstrDesc &II = TII.get(TargetOpcode::DBG_VALUE); - // FIXME may need to add RegState::Debug to any registers produced, - // although ESP/EBP should be the only ones at the moment. assert(DI->getVariable()->isValidLocationForIntrinsic(DbgLoc) && "Expected inlined-at fields to agree"); addFullAddress(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, II), AM) diff --git a/llvm/unittests/CodeGen/GlobalISel/PatternMatchTest.cpp b/llvm/unittests/CodeGen/GlobalISel/PatternMatchTest.cpp --- a/llvm/unittests/CodeGen/GlobalISel/PatternMatchTest.cpp +++ b/llvm/unittests/CodeGen/GlobalISel/PatternMatchTest.cpp @@ -499,8 +499,8 @@ EXPECT_TRUE(mi_match(Reg, *MRI, m_OneNonDBGUse(m_GAdd(m_Reg(), m_Reg())))); // Add multiple debug uses of Reg. - B.buildInstr(TargetOpcode::DBG_VALUE, {}, {Reg})->getOperand(0).setIsDebug(); - B.buildInstr(TargetOpcode::DBG_VALUE, {}, {Reg})->getOperand(0).setIsDebug(); + B.buildInstr(TargetOpcode::DBG_VALUE, {}, {Reg}); + B.buildInstr(TargetOpcode::DBG_VALUE, {}, {Reg}); EXPECT_FALSE(mi_match(Reg, *MRI, m_OneUse(m_GAdd(m_Reg(), m_Reg())))); EXPECT_TRUE(mi_match(Reg, *MRI, m_OneNonDBGUse(m_GAdd(m_Reg(), m_Reg())))); diff --git a/llvm/unittests/CodeGen/MachineInstrTest.cpp b/llvm/unittests/CodeGen/MachineInstrTest.cpp --- a/llvm/unittests/CodeGen/MachineInstrTest.cpp +++ b/llvm/unittests/CodeGen/MachineInstrTest.cpp @@ -386,6 +386,32 @@ ASSERT_FALSE(MI->getHeapAllocMarker()); } +TEST(MachineInstrDebugValue, AddDebugValueOperand) { + LLVMContext Ctx; + Module Mod("Module", Ctx); + auto MF = createMachineFunction(Ctx, Mod); + + for (const unsigned short Opcode : + {TargetOpcode::DBG_VALUE, TargetOpcode::DBG_VALUE_LIST, + TargetOpcode::DBG_INSTR_REF, TargetOpcode::DBG_PHI, + TargetOpcode::DBG_LABEL}) { + const MCInstrDesc MCID = { + Opcode, 0, 0, + 0, 0, (1ULL << MCID::Pseudo) | (1ULL << MCID::Variadic), + 0, nullptr, nullptr, + nullptr}; + + auto *MI = MF->CreateMachineInstr(MCID, DebugLoc()); + MI->addOperand(*MF, MachineOperand::CreateReg(0, /*isDef*/ false)); + + MI->addOperand(*MF, MachineOperand::CreateImm(0)); + MI->getOperand(1).ChangeToRegister(0, false); + + ASSERT_TRUE(MI->getOperand(0).isDebug()); + ASSERT_TRUE(MI->getOperand(1).isDebug()); + } +} + static_assert(std::is_trivially_copyable::value, "trivially copyable");