diff --git a/llvm/lib/CodeGen/GlobalISel/RegBankSelect.cpp b/llvm/lib/CodeGen/GlobalISel/RegBankSelect.cpp --- a/llvm/lib/CodeGen/GlobalISel/RegBankSelect.cpp +++ b/llvm/lib/CodeGen/GlobalISel/RegBankSelect.cpp @@ -603,6 +603,9 @@ MRI->setRegBank(Reg, *ValMapping.BreakDown[0].RegBank); break; case RepairingPlacement::Insert: + // Don't insert additional instruction for debug instruction. + if (MI.isDebugInstr()) + break; OpdMapper.createVRegs(OpIdx); if (!repairReg(MO, ValMapping, RepairPt, OpdMapper.getVRegs(OpIdx))) return false; @@ -716,9 +719,25 @@ if (MI.isInlineAsm()) continue; - // Ignore debug info. - if (MI.isDebugInstr()) - continue; + if (MI.isDebugInstr()) { + bool Ignore = false; + for (MachineOperand &MO : MI.operands()) { + if (!MO.isReg()) + continue; + Register Reg = MO.getReg(); + if (!Reg) + continue; + // If there is physical register or virtual register that has been + // assigned to a register class, ignore debug info. + LLT Ty = MRI->getType(Reg); + if (!Ty.isValid()) { + Ignore = true; + break; + } + } + if (Ignore) + continue; + } // Ignore IMPLICIT_DEF which must have a regclass. if (MI.isImplicitDef()) diff --git a/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp b/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp --- a/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp +++ b/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp @@ -907,6 +907,51 @@ getMinClassForRegBank(DstRegBank, DstSize, true)}; } +static bool selectDebugInstr(MachineInstr &I, MachineRegisterInfo &MRI, + const RegisterBankInfo &RBI) { + bool Ignore = false; + for (MachineOperand &MO : I.operands()) { + if (!MO.isReg()) + continue; + Register Reg = MO.getReg(); + if (!Reg) + continue; + LLT Ty = MRI.getType(Reg); + // If there is physical register or virutal register that has been + // assigned to a register class, just bail out. This logic is aligned + // to RegBankSelect when setting register bank for debug instructions. + if (!Ty.isValid()) { + Ignore = true; + break; + } + } + if (Ignore) + return true; + for (MachineOperand &MO : I.operands()) { + if (!MO.isReg()) + continue; + Register Reg = MO.getReg(); + if (!Reg) + continue; + LLT Ty = MRI.getType(Reg); + const RegClassOrRegBank &RegClassOrBank = MRI.getRegClassOrRegBank(Reg); + const TargetRegisterClass *RC = + RegClassOrBank.dyn_cast(); + if (!RC) { + const RegisterBank &RB = *RegClassOrBank.get(); + RC = getRegClassForTypeOnBank(Ty, RB); + if (!RC) { + LLVM_DEBUG( + dbgs() << "Warning: DBG_VALUE operand has unexpected size/bank\n"); + break; + } + } + RBI.constrainGenericRegister(Reg, *RC, MRI); + } + + return true; +} + static bool selectCopy(MachineInstr &I, const TargetInstrInfo &TII, MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI, const RegisterBankInfo &RBI) { @@ -2382,6 +2427,9 @@ if (I.isCopy()) return selectCopy(I, TII, MRI, TRI, RBI); + if (I.isDebugInstr()) + return selectDebugInstr(I, MRI, RBI); + return true; } diff --git a/llvm/lib/Target/X86/X86InstructionSelector.cpp b/llvm/lib/Target/X86/X86InstructionSelector.cpp --- a/llvm/lib/Target/X86/X86InstructionSelector.cpp +++ b/llvm/lib/Target/X86/X86InstructionSelector.cpp @@ -94,6 +94,7 @@ MachineFunction &MF) const; bool selectUadde(MachineInstr &I, MachineRegisterInfo &MRI, MachineFunction &MF) const; + bool selectDebugInstr(MachineInstr &I, MachineRegisterInfo &MRI) const; bool selectCopy(MachineInstr &I, MachineRegisterInfo &MRI) const; bool selectUnmergeValues(MachineInstr &I, MachineRegisterInfo &MRI, MachineFunction &MF); @@ -230,6 +231,51 @@ llvm_unreachable("Unknown RegClass for PhysReg!"); } +bool X86InstructionSelector::selectDebugInstr(MachineInstr &I, + MachineRegisterInfo &MRI) const { + bool Ignore = false; + for (MachineOperand &MO : I.operands()) { + if (!MO.isReg()) + continue; + Register Reg = MO.getReg(); + if (!Reg) + continue; + LLT Ty = MRI.getType(Reg); + // If there is physical register or virutal register that has been + // assigned to a register class, just bail out. This logic is aligned + // to RegBankSelect when setting register bank for debug instructions. + if (!Ty.isValid()) { + Ignore = true; + break; + } + } + if (Ignore) + return true; + for (MachineOperand &MO : I.operands()) { + if (!MO.isReg()) + continue; + Register Reg = MO.getReg(); + if (!Reg) + continue; + LLT Ty = MRI.getType(Reg); + const RegClassOrRegBank &RegClassOrBank = MRI.getRegClassOrRegBank(Reg); + const TargetRegisterClass *RC = + RegClassOrBank.dyn_cast(); + if (!RC) { + const RegisterBank &RB = *RegClassOrBank.get(); + RC = getRegClass(Ty, RB); + if (!RC) { + LLVM_DEBUG( + dbgs() << "Warning: DBG_VALUE operand has unexpected size/bank\n"); + break; + } + } + RBI.constrainGenericRegister(Reg, *RC, MRI); + } + + return true; +} + // Set X86 Opcode and constrain DestReg. bool X86InstructionSelector::selectCopy(MachineInstr &I, MachineRegisterInfo &MRI) const { @@ -326,6 +372,9 @@ if (I.isCopy()) return selectCopy(I, MRI); + if (I.isDebugInstr()) + return selectDebugInstr(I, MRI); + return true; } diff --git a/llvm/lib/Target/X86/X86RegisterBankInfo.cpp b/llvm/lib/Target/X86/X86RegisterBankInfo.cpp --- a/llvm/lib/Target/X86/X86RegisterBankInfo.cpp +++ b/llvm/lib/Target/X86/X86RegisterBankInfo.cpp @@ -114,7 +114,7 @@ unsigned NumOperands = MI.getNumOperands(); for (unsigned Idx = 0; Idx < NumOperands; ++Idx) { auto &MO = MI.getOperand(Idx); - if (!MO.isReg()) + if (!MO.isReg() || !MO.getReg()) OpRegBankIdx[Idx] = PMI_None; else OpRegBankIdx[Idx] = getPartialMappingIdx(MRI.getType(MO.getReg()), isFP); @@ -130,6 +130,8 @@ for (unsigned Idx = 0; Idx < NumOperands; ++Idx) { if (!MI.getOperand(Idx).isReg()) continue; + if (!MI.getOperand(Idx).getReg()) + continue; auto Mapping = getValueMapping(OpRegBankIdx[Idx], 1); if (!Mapping->isValid()) diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-dbg-value.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-dbg-value.mir --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-dbg-value.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-dbg-value.mir @@ -43,10 +43,12 @@ bb.0: liveins: $w0 ; CHECK-LABEL: name: test_dbg_value - ; CHECK: [[COPY:%[0-9]+]]:gpr32 = COPY $w0 - ; CHECK: [[ADDWrr:%[0-9]+]]:gpr32 = ADDWrr [[COPY]], [[COPY]] - ; CHECK: $w0 = COPY [[ADDWrr]] - ; CHECK: DBG_VALUE [[ADDWrr]], $noreg, !7, !DIExpression(), debug-location !9 + ; CHECK: liveins: $w0 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr32 = COPY $w0 + ; CHECK-NEXT: [[ADDWrr:%[0-9]+]]:gpr32 = ADDWrr [[COPY]], [[COPY]] + ; CHECK-NEXT: $w0 = COPY [[ADDWrr]] + ; CHECK-NEXT: DBG_VALUE [[ADDWrr]], $noreg, !7, !DIExpression(), debug-location !9 %0:gpr(s32) = COPY $w0 %1:gpr(s32) = G_ADD %0, %0 $w0 = COPY %1(s32) @@ -61,8 +63,9 @@ bb.0: liveins: $w0 ; CHECK-LABEL: name: test_dbg_value_dead - ; CHECK-NOT: COPY - ; CHECK: DBG_VALUE %0:gpr, $noreg, !7, !DIExpression(), debug-location !9 + ; CHECK: liveins: $w0 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: DBG_VALUE %0:gpr32, $noreg, !7, !DIExpression(), debug-location !9 %0:gpr(s32) = COPY $w0 DBG_VALUE %0(s32), $noreg, !7, !DIExpression(), debug-location !9 ... diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-hint.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-hint.mir --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-hint.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-hint.mir @@ -16,7 +16,7 @@ ; CHECK-LABEL: name: assert_zext_gpr ; CHECK: liveins: $w0, $w1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %copy:gpr32all = COPY $w0 + ; CHECK-NEXT: %copy:gpr32 = COPY $w0 ; CHECK-NEXT: $w1 = COPY %copy ; CHECK-NEXT: RET_ReallyLR implicit $w1 %copy:gpr(s32) = COPY $w0 @@ -104,7 +104,7 @@ ; CHECK-LABEL: name: assert_sext_gpr ; CHECK: liveins: $w0, $w1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %copy:gpr32all = COPY $w0 + ; CHECK-NEXT: %copy:gpr32 = COPY $w0 ; CHECK-NEXT: $w1 = COPY %copy ; CHECK-NEXT: RET_ReallyLR implicit $w1 %copy:gpr(s32) = COPY $w0 diff --git a/llvm/test/DebugInfo/AArch64/debug-reg-bank.ll b/llvm/test/DebugInfo/AArch64/debug-reg-bank.ll --- a/llvm/test/DebugInfo/AArch64/debug-reg-bank.ll +++ b/llvm/test/DebugInfo/AArch64/debug-reg-bank.ll @@ -6,7 +6,7 @@ ; CHECK: bb.1.entry: ; CHECK-NEXT: liveins: $w0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: DBG_VALUE %0:_, $noreg, !12, !DIExpression(), debug-location !19 + ; CHECK-NEXT: DBG_VALUE %0:gpr32, $noreg, !12, !DIExpression(), debug-location !19 ; CHECK-NEXT: RET_ReallyLR debug-location !20 entry: call void @llvm.dbg.value(metadata i32 %n, i64 0, metadata !12, metadata !19), !dbg !20 diff --git a/llvm/test/DebugInfo/X86/debug-reg-bank.ll b/llvm/test/DebugInfo/X86/debug-reg-bank.ll --- a/llvm/test/DebugInfo/X86/debug-reg-bank.ll +++ b/llvm/test/DebugInfo/X86/debug-reg-bank.ll @@ -6,7 +6,7 @@ ; CHECK: bb.1.entry: ; CHECK-NEXT: liveins: $edi ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: DBG_VALUE %0:gpr, $noreg, !12, !DIExpression(), debug-location !19 + ; CHECK-NEXT: DBG_VALUE %0:gr32, $noreg, !12, !DIExpression(), debug-location !19 ; CHECK-NEXT: RET 0, debug-location !20 entry: call void @llvm.dbg.value(metadata i32 %n, i64 0, metadata !12, metadata !19), !dbg !20