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 there is physical register or non register operand, ignore debug + // info. + if (MI.isDebugInstr()) { + bool Ignore = false; + for (MachineOperand &MO : MI.operands()) { + if (!MO.isReg()) + continue; + Register Reg = MO.getReg(); + if (!Reg) + continue; + 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,53 @@ getMinClassForRegBank(DstRegBank, DstSize, true)}; } +static bool selectDebugInstr(MachineInstr &I, MachineRegisterInfo &MRI, + const RegisterBankInfo &RBI) { + if (I.isDebugInstr()) { + bool Ignore = false; + for (MachineOperand &MO : I.operands()) { + if (!MO.isReg()) + continue; + Register Reg = MO.getReg(); + if (!Reg) + continue; + LLT Ty = MRI.getType(Reg); + // It may be physical register or non register. For those cases, just + // bail out. + 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 +2429,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,53 @@ llvm_unreachable("Unknown RegClass for PhysReg!"); } +bool X86InstructionSelector::selectDebugInstr(MachineInstr &I, + MachineRegisterInfo &MRI) const { + if (I.isDebugInstr()) { + bool Ignore = false; + for (MachineOperand &MO : I.operands()) { + if (!MO.isReg()) + continue; + Register Reg = MO.getReg(); + if (!Reg) + continue; + LLT Ty = MRI.getType(Reg); + // It may be physical register or non register. For those cases, just + // bail out. + 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 +374,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 @@ -15,9 +15,10 @@ ; CHECK-LABEL: name: assert_zext_gpr ; CHECK: liveins: $w0, $w1 - ; CHECK: %copy:gpr32all = COPY $w0 - ; CHECK: $w1 = COPY %copy - ; CHECK: RET_ReallyLR implicit $w1 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: %copy:gpr32 = COPY $w0 + ; CHECK-NEXT: $w1 = COPY %copy + ; CHECK-NEXT: RET_ReallyLR implicit $w1 %copy:gpr(s32) = COPY $w0 %copy_assert_zext:gpr(s32) = G_ASSERT_ZEXT %copy, 16 $w1 = COPY %copy_assert_zext(s32) @@ -35,9 +36,10 @@ ; CHECK-LABEL: name: assert_zext_fpr ; CHECK: liveins: $s0, $s1 - ; CHECK: %copy:fpr32 = COPY $s0 - ; CHECK: $s1 = COPY %copy - ; CHECK: RET_ReallyLR implicit $s1 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: %copy:fpr32 = COPY $s0 + ; CHECK-NEXT: $s1 = COPY %copy + ; CHECK-NEXT: RET_ReallyLR implicit $s1 %copy:fpr(s32) = COPY $s0 %copy_assert_zext:fpr(s32) = G_ASSERT_ZEXT %copy, 16 $s1 = COPY %copy_assert_zext(s32) @@ -55,9 +57,10 @@ ; CHECK-LABEL: name: assert_zext_in_between_cross_bank ; CHECK: liveins: $s0, $w1 - ; CHECK: %copy:fpr32 = COPY $s0 - ; CHECK: $w1 = COPY %copy - ; CHECK: RET_ReallyLR implicit $w1 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: %copy:fpr32 = COPY $s0 + ; CHECK-NEXT: $w1 = COPY %copy + ; CHECK-NEXT: RET_ReallyLR implicit $w1 %copy:fpr(s32) = COPY $s0 %copy_assert_zext:fpr(s32) = G_ASSERT_ZEXT %copy, 16 $w1 = COPY %copy_assert_zext(s32) @@ -78,9 +81,10 @@ ; CHECK-LABEL: name: assert_zext_decided_dst_class ; CHECK: liveins: $w0, $w1, $w2 - ; CHECK: %copy_with_rc:gpr32sp = COPY $w2 - ; CHECK: $w1 = COPY %copy_with_rc - ; CHECK: RET_ReallyLR implicit $w1 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: %copy_with_rc:gpr32sp = COPY $w2 + ; CHECK-NEXT: $w1 = COPY %copy_with_rc + ; CHECK-NEXT: RET_ReallyLR implicit $w1 %copy:gpr(s32) = COPY $w0 %copy_assert_zext:gpr(s32) = G_ASSERT_ZEXT %copy, 16 %copy_with_rc:gpr32sp(s32) = COPY $w2 @@ -99,9 +103,10 @@ ; CHECK-LABEL: name: assert_sext_gpr ; CHECK: liveins: $w0, $w1 - ; CHECK: %copy:gpr32all = COPY $w0 - ; CHECK: $w1 = COPY %copy - ; CHECK: RET_ReallyLR implicit $w1 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: %copy:gpr32 = COPY $w0 + ; CHECK-NEXT: $w1 = COPY %copy + ; CHECK-NEXT: RET_ReallyLR implicit $w1 %copy:gpr(s32) = COPY $w0 %copy_assert_sext:gpr(s32) = G_ASSERT_SEXT %copy, 16 $w1 = COPY %copy_assert_sext(s32) @@ -119,9 +124,10 @@ ; CHECK-LABEL: name: assert_sext_fpr ; CHECK: liveins: $s0, $s1 - ; CHECK: %copy:fpr32 = COPY $s0 - ; CHECK: $s1 = COPY %copy - ; CHECK: RET_ReallyLR implicit $s1 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: %copy:fpr32 = COPY $s0 + ; CHECK-NEXT: $s1 = COPY %copy + ; CHECK-NEXT: RET_ReallyLR implicit $s1 %copy:fpr(s32) = COPY $s0 %copy_assert_sext:fpr(s32) = G_ASSERT_SEXT %copy, 16 $s1 = COPY %copy_assert_sext(s32) @@ -139,9 +145,10 @@ ; CHECK-LABEL: name: assert_sext_in_between_cross_bank ; CHECK: liveins: $s0, $w1 - ; CHECK: %copy:fpr32 = COPY $s0 - ; CHECK: $w1 = COPY %copy - ; CHECK: RET_ReallyLR implicit $w1 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: %copy:fpr32 = COPY $s0 + ; CHECK-NEXT: $w1 = COPY %copy + ; CHECK-NEXT: RET_ReallyLR implicit $w1 %copy:fpr(s32) = COPY $s0 %copy_assert_sext:fpr(s32) = G_ASSERT_SEXT %copy, 16 $w1 = COPY %copy_assert_sext(s32) @@ -162,9 +169,10 @@ ; CHECK-LABEL: name: assert_sext_decided_dst_class ; CHECK: liveins: $w0, $w1, $w2 - ; CHECK: %copy_with_rc:gpr32sp = COPY $w2 - ; CHECK: $w1 = COPY %copy_with_rc - ; CHECK: RET_ReallyLR implicit $w1 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: %copy_with_rc:gpr32sp = COPY $w2 + ; CHECK-NEXT: $w1 = COPY %copy_with_rc + ; CHECK-NEXT: RET_ReallyLR implicit $w1 %copy:gpr(s32) = COPY $w0 %copy_assert_sext:gpr(s32) = G_ASSERT_SEXT %copy, 16 %copy_with_rc:gpr32sp(s32) = COPY $w2 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