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 @@ -458,6 +458,7 @@ LLVM_DEBUG(dbgs() << "Mapping is too expensive from the start\n"); return Cost; } + const MachineRegisterInfo &MRI = MI.getMF()->getRegInfo(); // Moreover, to realize this mapping, the register bank of each operand must // match this mapping. In other words, we may need to locally reassign the @@ -471,6 +472,10 @@ Register Reg = MO.getReg(); if (!Reg) continue; + LLT Ty = MRI.getType(Reg); + if (!Ty.isValid()) + continue; + LLVM_DEBUG(dbgs() << "Opd" << OpIdx << '\n'); const RegisterBankInfo::ValueMapping &ValMapping = InstrMapping.getOperandMapping(OpIdx); @@ -603,6 +608,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,10 +724,6 @@ if (MI.isInlineAsm()) continue; - // Ignore debug info. - if (MI.isDebugInstr()) - continue; - // Ignore IMPLICIT_DEF which must have a regclass. if (MI.isImplicitDef()) continue; diff --git a/llvm/lib/CodeGen/RegisterBankInfo.cpp b/llvm/lib/CodeGen/RegisterBankInfo.cpp --- a/llvm/lib/CodeGen/RegisterBankInfo.cpp +++ b/llvm/lib/CodeGen/RegisterBankInfo.cpp @@ -449,6 +449,9 @@ LLVM_DEBUG(dbgs() << " is $noreg, nothing to be done\n"); continue; } + LLT Ty = MRI.getType(MO.getReg()); + if (!Ty.isValid()) + continue; assert(OpdMapper.getInstrMapping().getOperandMapping(OpIdx).NumBreakDowns != 0 && "Invalid mapping"); @@ -601,6 +604,7 @@ const MachineFunction &MF = *MI.getMF(); const RegisterBankInfo *RBI = MF.getSubtarget().getRegBankInfo(); (void)RBI; + const MachineRegisterInfo &MRI = MF.getRegInfo(); for (unsigned Idx = 0; Idx < NumOperands; ++Idx) { const MachineOperand &MO = MI.getOperand(Idx); @@ -612,6 +616,9 @@ Register Reg = MO.getReg(); if (!Reg) continue; + LLT Ty = MRI.getType(Reg); + if (!Ty.isValid()) + continue; assert(getOperandMapping(Idx).isValid() && "We must have a mapping for reg operands"); const RegisterBankInfo::ValueMapping &MOMapping = getOperandMapping(Idx); 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,38 @@ getMinClassForRegBank(DstRegBank, DstSize, true)}; } +// FIXME: We need some sort of API in RBI/TRI to allow generic code to +// constrain operands of simple instructions given a TargetRegisterClass +// and LLT +static bool selectDebugInstr(MachineInstr &I, MachineRegisterInfo &MRI, + const RegisterBankInfo &RBI) { + for (MachineOperand &MO : I.operands()) { + if (!MO.isReg()) + continue; + Register Reg = MO.getReg(); + if (!Reg) + continue; + if (Reg.isPhysical()) + 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) { @@ -2377,6 +2409,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/AArch64/GISel/AArch64RegisterBankInfo.cpp b/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp --- a/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp +++ b/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp @@ -681,6 +681,8 @@ continue; LLT Ty = MRI.getType(MO.getReg()); + if (!Ty.isValid()) + continue; OpSize[Idx] = Ty.getSizeInBits(); // As a top-level guess, vectors go in FPRs, scalars and pointers in GPRs. @@ -989,6 +991,9 @@ SmallVector OpdsMapping(NumOperands); for (unsigned Idx = 0; Idx < NumOperands; ++Idx) { if (MI.getOperand(Idx).isReg() && MI.getOperand(Idx).getReg()) { + LLT Ty = MRI.getType(MI.getOperand(Idx).getReg()); + if (!Ty.isValid()) + continue; auto Mapping = getValueMapping(OpRegBankIdx[Idx], OpSize[Idx]); if (!Mapping->isValid()) return getInvalidInstructionMapping(); 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,38 @@ llvm_unreachable("Unknown RegClass for PhysReg!"); } +// FIXME: We need some sort of API in RBI/TRI to allow generic code to +// constrain operands of simple instructions given a TargetRegisterClass +// and LLT +bool X86InstructionSelector::selectDebugInstr(MachineInstr &I, + MachineRegisterInfo &MRI) const { + for (MachineOperand &MO : I.operands()) { + if (!MO.isReg()) + continue; + Register Reg = MO.getReg(); + if (!Reg) + continue; + if (Reg.isPhysical()) + 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 +359,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 @@ -65,7 +65,7 @@ ; CHECK-LABEL: name: test_dbg_value_dead ; CHECK: liveins: $w0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: DBG_VALUE %0:gpr, $noreg, !7, !DIExpression(), debug-location !9 + ; 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-9]+}}:_, $noreg, !12, !DIExpression(), debug-location !19 + ; CHECK-NEXT: DBG_VALUE %2:gpr32, $noreg, !12, !DIExpression(), debug-location !19 ; CHECK-NEXT: RET_ReallyLR debug-location !20 entry: %m = mul i32 %n, 13 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-9]+}}:_, $noreg, !12, !DIExpression(), debug-location !19 + ; CHECK-NEXT: DBG_VALUE %2:gr32, $noreg, !12, !DIExpression(), debug-location !19 ; CHECK-NEXT: RET 0, debug-location !20 entry: %m = mul i32 %n, 13