[llvm] f108c7f - [GlobalISel] Allow DBG_VALUE to use undefined vregs before LiveDebugValues.
Jack Andersen via llvm-commits
llvm-commits at lists.llvm.org
Sun Dec 5 12:56:37 PST 2021
Author: Jack Andersen
Date: 2021-12-05T15:55:59-05:00
New Revision: f108c7f59dfae5fafbb00fbdef7a0cd31826dcfc
URL: https://github.com/llvm/llvm-project/commit/f108c7f59dfae5fafbb00fbdef7a0cd31826dcfc
DIFF: https://github.com/llvm/llvm-project/commit/f108c7f59dfae5fafbb00fbdef7a0cd31826dcfc.diff
LOG: [GlobalISel] Allow DBG_VALUE to use undefined vregs before LiveDebugValues.
Expanding on D109750.
Since `DBG_VALUE` instructions have final register validity determined in
`LDVImpl::handleDebugValue`, there is no apparent reason to immediately prune
unused register operands as their defs are erased. Consequently, this renders
`MachineInstr::eraseFromParentAndMarkDBGValuesForRemoval` moot; gaining a
substantial performance improvement.
The only necessary changes involve making relevant passes consider invalid
DBG_VALUE vregs uses as valid.
Reviewed By: MatzeB
Differential Revision: https://reviews.llvm.org/D112852
Added:
llvm/test/CodeGen/Generic/live-debug-vars-undef-use.mir
llvm/test/CodeGen/X86/GlobalISel/x86-calllowering-dbg-trunc.ll
llvm/test/MachineVerifier/verify-regbankselected-dbg-undef-use.mir
llvm/test/MachineVerifier/verify-selected-dbg-undef-use.mir
Modified:
llvm/include/llvm/CodeGen/GlobalISel/LegalizationArtifactCombiner.h
llvm/include/llvm/CodeGen/MIRYamlMapping.h
llvm/include/llvm/CodeGen/MachineFunction.h
llvm/include/llvm/CodeGen/MachineInstr.h
llvm/lib/CodeGen/DeadMachineInstructionElim.cpp
llvm/lib/CodeGen/GlobalISel/Combiner.cpp
llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
llvm/lib/CodeGen/GlobalISel/InstructionSelect.cpp
llvm/lib/CodeGen/GlobalISel/Utils.cpp
llvm/lib/CodeGen/LiveDebugVariables.cpp
llvm/lib/CodeGen/LiveDebugVariables.h
llvm/lib/CodeGen/MIRParser/MIRParser.cpp
llvm/lib/CodeGen/MIRPrinter.cpp
llvm/lib/CodeGen/MachineCombiner.cpp
llvm/lib/CodeGen/MachineFunction.cpp
llvm/lib/CodeGen/MachineInstr.cpp
llvm/lib/CodeGen/MachineVerifier.cpp
llvm/lib/Target/AMDGPU/SIFoldOperands.cpp
llvm/lib/Target/NVPTX/NVPTXPeephole.cpp
llvm/test/CodeGen/AArch64/GlobalISel/select-dbg-value.mir
llvm/test/CodeGen/AArch64/GlobalISel/uaddo-8-16-bits.mir
llvm/test/CodeGen/AMDGPU/fold-readlane.mir
Removed:
################################################################################
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/LegalizationArtifactCombiner.h b/llvm/include/llvm/CodeGen/GlobalISel/LegalizationArtifactCombiner.h
index 8a603de2f91db..886b3af834d79 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/LegalizationArtifactCombiner.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/LegalizationArtifactCombiner.h
@@ -1248,7 +1248,7 @@ class LegalizationArtifactCombiner {
for (auto *DeadMI : DeadInsts) {
LLVM_DEBUG(dbgs() << *DeadMI << "Is dead, eagerly deleting\n");
WrapperObserver.erasingInstr(*DeadMI);
- DeadMI->eraseFromParentAndMarkDBGValuesForRemoval();
+ DeadMI->eraseFromParent();
}
DeadInsts.clear();
}
diff --git a/llvm/include/llvm/CodeGen/MIRYamlMapping.h b/llvm/include/llvm/CodeGen/MIRYamlMapping.h
index b6d7c2487126d..05a375bc251bb 100644
--- a/llvm/include/llvm/CodeGen/MIRYamlMapping.h
+++ b/llvm/include/llvm/CodeGen/MIRYamlMapping.h
@@ -695,6 +695,7 @@ struct MachineFunction {
bool TracksRegLiveness = false;
bool HasWinCFI = false;
bool FailsVerification = false;
+ bool TracksDebugUserValues = false;
std::vector<VirtualRegisterDefinition> VirtualRegisters;
std::vector<MachineFunctionLiveIn> LiveIns;
Optional<std::vector<FlowStringValue>> CalleeSavedRegisters;
@@ -724,6 +725,8 @@ template <> struct MappingTraits<MachineFunction> {
YamlIO.mapOptional("tracksRegLiveness", MF.TracksRegLiveness, false);
YamlIO.mapOptional("hasWinCFI", MF.HasWinCFI, false);
YamlIO.mapOptional("failsVerification", MF.FailsVerification, false);
+ YamlIO.mapOptional("tracksDebugUserValues", MF.TracksDebugUserValues,
+ false);
YamlIO.mapOptional("registers", MF.VirtualRegisters,
std::vector<VirtualRegisterDefinition>());
YamlIO.mapOptional("liveins", MF.LiveIns,
diff --git a/llvm/include/llvm/CodeGen/MachineFunction.h b/llvm/include/llvm/CodeGen/MachineFunction.h
index ec23dde0c6c07..d661711251d90 100644
--- a/llvm/include/llvm/CodeGen/MachineFunction.h
+++ b/llvm/include/llvm/CodeGen/MachineFunction.h
@@ -152,6 +152,12 @@ class MachineFunctionProperties {
// FailsVerification: Means that the function is not expected to pass machine
// verification. This can be set by passes that introduce known problems that
// have not been fixed yet.
+ // TracksDebugUserValues: Without this property enabled, debug instructions
+ // such as DBG_VALUE are allowed to reference virtual registers even if those
+ // registers do not have a definition. With the property enabled virtual
+ // registers must only be used if they have a definition. This property
+ // allows earlier passes in the pipeline to skip updates of `DBG_VALUE`
+ // instructions to save compile time.
enum class Property : unsigned {
IsSSA,
NoPHIs,
@@ -163,7 +169,8 @@ class MachineFunctionProperties {
Selected,
TiedOpsRewritten,
FailsVerification,
- LastProperty = FailsVerification,
+ TracksDebugUserValues,
+ LastProperty = TracksDebugUserValues,
};
bool hasProperty(Property P) const {
diff --git a/llvm/include/llvm/CodeGen/MachineInstr.h b/llvm/include/llvm/CodeGen/MachineInstr.h
index 0ac934e208b69..b7ae1cba04f4e 100644
--- a/llvm/include/llvm/CodeGen/MachineInstr.h
+++ b/llvm/include/llvm/CodeGen/MachineInstr.h
@@ -1173,12 +1173,6 @@ class MachineInstr
/// eraseFromBundle() to erase individual bundled instructions.
void eraseFromParent();
- /// Unlink 'this' from the containing basic block and delete it.
- ///
- /// For all definitions mark their uses in DBG_VALUE nodes
- /// as undefined. Otherwise like eraseFromParent().
- void eraseFromParentAndMarkDBGValuesForRemoval();
-
/// Unlink 'this' form its basic block and delete it.
///
/// If the instruction is part of a bundle, the other instructions in the
diff --git a/llvm/lib/CodeGen/DeadMachineInstructionElim.cpp b/llvm/lib/CodeGen/DeadMachineInstructionElim.cpp
index 0bb186a024166..5579152f1ce0e 100644
--- a/llvm/lib/CodeGen/DeadMachineInstructionElim.cpp
+++ b/llvm/lib/CodeGen/DeadMachineInstructionElim.cpp
@@ -142,9 +142,9 @@ bool DeadMachineInstructionElim::eliminateDeadMI(MachineFunction &MF) {
if (isDead(&MI)) {
LLVM_DEBUG(dbgs() << "DeadMachineInstructionElim: DELETING: " << MI);
// It is possible that some DBG_VALUE instructions refer to this
- // instruction. They get marked as undef and will be deleted
- // in the live debug variable analysis.
- MI.eraseFromParentAndMarkDBGValuesForRemoval();
+ // instruction. They will be deleted in the live debug variable
+ // analysis.
+ MI.eraseFromParent();
AnyChanges = true;
++NumDeletes;
continue;
diff --git a/llvm/lib/CodeGen/GlobalISel/Combiner.cpp b/llvm/lib/CodeGen/GlobalISel/Combiner.cpp
index 381c6df5c97ad..dd1ef74e8ad01 100644
--- a/llvm/lib/CodeGen/GlobalISel/Combiner.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/Combiner.cpp
@@ -135,7 +135,7 @@ bool Combiner::combineMachineInstrs(MachineFunction &MF,
// Erase dead insts before even adding to the list.
if (isTriviallyDead(CurMI, *MRI)) {
LLVM_DEBUG(dbgs() << CurMI << "Is dead; erasing.\n");
- CurMI.eraseFromParentAndMarkDBGValuesForRemoval();
+ CurMI.eraseFromParent();
continue;
}
WorkList.deferred_insert(&CurMI);
diff --git a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
index 755b3b8445700..f7a634dad61a3 100644
--- a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
@@ -1551,8 +1551,8 @@ void CombinerHelper::applyShiftOfShiftedLogic(MachineInstr &MI,
Builder.buildInstr(MatchInfo.Logic->getOpcode(), {Dest}, {Shift1, Shift2});
// These were one use so it's safe to remove them.
- MatchInfo.Shift2->eraseFromParentAndMarkDBGValuesForRemoval();
- MatchInfo.Logic->eraseFromParentAndMarkDBGValuesForRemoval();
+ MatchInfo.Shift2->eraseFromParent();
+ MatchInfo.Logic->eraseFromParent();
MI.eraseFromParent();
}
diff --git a/llvm/lib/CodeGen/GlobalISel/InstructionSelect.cpp b/llvm/lib/CodeGen/GlobalISel/InstructionSelect.cpp
index 9b26924863847..b10c9272a5081 100644
--- a/llvm/lib/CodeGen/GlobalISel/InstructionSelect.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/InstructionSelect.cpp
@@ -163,7 +163,7 @@ bool InstructionSelect::runOnMachineFunction(MachineFunction &MF) {
// If so, erase it.
if (isTriviallyDead(MI, MRI)) {
LLVM_DEBUG(dbgs() << "Is dead; erasing.\n");
- MI.eraseFromParentAndMarkDBGValuesForRemoval();
+ MI.eraseFromParent();
continue;
}
@@ -255,8 +255,12 @@ bool InstructionSelect::runOnMachineFunction(MachineFunction &MF) {
MachineInstr *MI = nullptr;
if (!MRI.def_empty(VReg))
MI = &*MRI.def_instr_begin(VReg);
- else if (!MRI.use_empty(VReg))
+ else if (!MRI.use_empty(VReg)) {
MI = &*MRI.use_instr_begin(VReg);
+ // Debug value instruction is permitted to use undefined vregs.
+ if (MI->isDebugValue())
+ continue;
+ }
if (!MI)
continue;
diff --git a/llvm/lib/CodeGen/GlobalISel/Utils.cpp b/llvm/lib/CodeGen/GlobalISel/Utils.cpp
index b0b84763e9222..00ee2988d17fe 100644
--- a/llvm/lib/CodeGen/GlobalISel/Utils.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/Utils.cpp
@@ -1184,25 +1184,6 @@ bool llvm::shouldOptForSize(const MachineBasicBlock &MBB,
llvm::shouldOptimizeForSize(MBB.getBasicBlock(), PSI, BFI);
}
-/// These artifacts generally don't have any debug users because they don't
-/// directly originate from IR instructions, but instead usually from
-/// legalization. Avoiding checking for debug users improves compile time.
-/// Note that truncates or extends aren't included because they have IR
-/// counterparts which can have debug users after translation.
-static bool shouldSkipDbgValueFor(MachineInstr &MI) {
- switch (MI.getOpcode()) {
- case TargetOpcode::G_UNMERGE_VALUES:
- case TargetOpcode::G_MERGE_VALUES:
- case TargetOpcode::G_CONCAT_VECTORS:
- case TargetOpcode::G_BUILD_VECTOR:
- case TargetOpcode::G_EXTRACT:
- case TargetOpcode::G_INSERT:
- return true;
- default:
- return false;
- }
-}
-
void llvm::saveUsesAndErase(MachineInstr &MI, MachineRegisterInfo &MRI,
LostDebugLocObserver *LocObserver,
SmallInstListTy &DeadInstChain) {
@@ -1212,10 +1193,7 @@ void llvm::saveUsesAndErase(MachineInstr &MI, MachineRegisterInfo &MRI,
}
LLVM_DEBUG(dbgs() << MI << "Is dead; erasing.\n");
DeadInstChain.remove(&MI);
- if (shouldSkipDbgValueFor(MI))
- MI.eraseFromParent();
- else
- MI.eraseFromParentAndMarkDBGValuesForRemoval();
+ MI.eraseFromParent();
if (LocObserver)
LocObserver->checkpoint(false);
}
diff --git a/llvm/lib/CodeGen/LiveDebugVariables.cpp b/llvm/lib/CodeGen/LiveDebugVariables.cpp
index 2272a350cc7de..e6661e5135c33 100644
--- a/llvm/lib/CodeGen/LiveDebugVariables.cpp
+++ b/llvm/lib/CodeGen/LiveDebugVariables.cpp
@@ -822,9 +822,6 @@ bool LDVImpl::handleDebugValue(MachineInstr &MI, SlotIndex Idx) {
// register that hasn't been defined yet. If we do not remove those here, then
// the re-insertion of the DBG_VALUE instruction after register allocation
// will be incorrect.
- // TODO: If earlier passes are corrected to generate sane debug information
- // (and if the machine verifier is improved to catch this), then these checks
- // could be removed or replaced by asserts.
bool Discard = false;
for (const MachineOperand &Op : MI.debug_operands()) {
if (Op.isReg() && Register::isVirtualRegister(Op.getReg())) {
diff --git a/llvm/lib/CodeGen/LiveDebugVariables.h b/llvm/lib/CodeGen/LiveDebugVariables.h
index 07dd3a83866fd..9998ce9e8dad8 100644
--- a/llvm/lib/CodeGen/LiveDebugVariables.h
+++ b/llvm/lib/CodeGen/LiveDebugVariables.h
@@ -56,6 +56,11 @@ class LLVM_LIBRARY_VISIBILITY LiveDebugVariables : public MachineFunctionPass {
bool runOnMachineFunction(MachineFunction &) override;
void releaseMemory() override;
void getAnalysisUsage(AnalysisUsage &) const override;
+
+ MachineFunctionProperties getSetProperties() const override {
+ return MachineFunctionProperties().set(
+ MachineFunctionProperties::Property::TracksDebugUserValues);
+ }
};
} // end namespace llvm
diff --git a/llvm/lib/CodeGen/MIRParser/MIRParser.cpp b/llvm/lib/CodeGen/MIRParser/MIRParser.cpp
index 6221b59293017..aaf44f52f63cd 100644
--- a/llvm/lib/CodeGen/MIRParser/MIRParser.cpp
+++ b/llvm/lib/CodeGen/MIRParser/MIRParser.cpp
@@ -457,6 +457,9 @@ MIRParserImpl::initializeMachineFunction(const yaml::MachineFunction &YamlMF,
if (YamlMF.FailsVerification)
MF.getProperties().set(
MachineFunctionProperties::Property::FailsVerification);
+ if (YamlMF.TracksDebugUserValues)
+ MF.getProperties().set(
+ MachineFunctionProperties::Property::TracksDebugUserValues);
PerFunctionMIParsingState PFS(MF, SM, IRSlots, *Target);
if (parseRegisterInfo(PFS, YamlMF))
diff --git a/llvm/lib/CodeGen/MIRPrinter.cpp b/llvm/lib/CodeGen/MIRPrinter.cpp
index f1369396e37f9..dc72f83ad0e48 100644
--- a/llvm/lib/CodeGen/MIRPrinter.cpp
+++ b/llvm/lib/CodeGen/MIRPrinter.cpp
@@ -219,6 +219,8 @@ void MIRPrinter::print(const MachineFunction &MF) {
MachineFunctionProperties::Property::FailedISel);
YamlMF.FailsVerification = MF.getProperties().hasProperty(
MachineFunctionProperties::Property::FailsVerification);
+ YamlMF.TracksDebugUserValues = MF.getProperties().hasProperty(
+ MachineFunctionProperties::Property::TracksDebugUserValues);
convert(YamlMF, MF.getRegInfo(), MF.getSubtarget().getRegisterInfo());
MachineModuleSlotTracker MST(&MF);
diff --git a/llvm/lib/CodeGen/MachineCombiner.cpp b/llvm/lib/CodeGen/MachineCombiner.cpp
index e2b6cfe55c16a..0f94d25ee4f45 100644
--- a/llvm/lib/CodeGen/MachineCombiner.cpp
+++ b/llvm/lib/CodeGen/MachineCombiner.cpp
@@ -485,7 +485,7 @@ static void insertDeleteInstructions(MachineBasicBlock *MBB, MachineInstr &MI,
MBB->insert((MachineBasicBlock::iterator)&MI, InstrPtr);
for (auto *InstrPtr : DelInstrs) {
- InstrPtr->eraseFromParentAndMarkDBGValuesForRemoval();
+ InstrPtr->eraseFromParent();
// Erase all LiveRegs defined by the removed instruction
for (auto I = RegUnits.begin(); I != RegUnits.end(); ) {
if (I->MI == InstrPtr)
diff --git a/llvm/lib/CodeGen/MachineFunction.cpp b/llvm/lib/CodeGen/MachineFunction.cpp
index ff3a39ecf0a63..b6f1a6e64e758 100644
--- a/llvm/lib/CodeGen/MachineFunction.cpp
+++ b/llvm/lib/CodeGen/MachineFunction.cpp
@@ -89,6 +89,7 @@ static cl::opt<unsigned> AlignAllFunctions(
static const char *getPropertyName(MachineFunctionProperties::Property Prop) {
using P = MachineFunctionProperties::Property;
+ // clang-format off
switch(Prop) {
case P::FailedISel: return "FailedISel";
case P::IsSSA: return "IsSSA";
@@ -100,7 +101,9 @@ static const char *getPropertyName(MachineFunctionProperties::Property Prop) {
case P::TracksLiveness: return "TracksLiveness";
case P::TiedOpsRewritten: return "TiedOpsRewritten";
case P::FailsVerification: return "FailsVerification";
+ case P::TracksDebugUserValues: return "TracksDebugUserValues";
}
+ // clang-format on
llvm_unreachable("Invalid machine function property");
}
diff --git a/llvm/lib/CodeGen/MachineInstr.cpp b/llvm/lib/CodeGen/MachineInstr.cpp
index aaa80432d2f2c..284eddaa03cb6 100644
--- a/llvm/lib/CodeGen/MachineInstr.cpp
+++ b/llvm/lib/CodeGen/MachineInstr.cpp
@@ -682,26 +682,6 @@ void MachineInstr::eraseFromParent() {
getParent()->erase(this);
}
-void MachineInstr::eraseFromParentAndMarkDBGValuesForRemoval() {
- assert(getParent() && "Not embedded in a basic block!");
- MachineBasicBlock *MBB = getParent();
- MachineFunction *MF = MBB->getParent();
- assert(MF && "Not embedded in a function!");
-
- MachineInstr *MI = (MachineInstr *)this;
- MachineRegisterInfo &MRI = MF->getRegInfo();
-
- for (const MachineOperand &MO : MI->operands()) {
- if (!MO.isReg() || !MO.isDef())
- continue;
- Register Reg = MO.getReg();
- if (!Reg.isVirtual())
- continue;
- MRI.markUsesInDebugValueAsUndef(Reg);
- }
- MI->eraseFromParent();
-}
-
void MachineInstr::eraseFromBundle() {
assert(getParent() && "Not embedded in a basic block!");
getParent()->erase_instr(this);
diff --git a/llvm/lib/CodeGen/MachineVerifier.cpp b/llvm/lib/CodeGen/MachineVerifier.cpp
index 32078db76cf33..f581df31dc4aa 100644
--- a/llvm/lib/CodeGen/MachineVerifier.cpp
+++ b/llvm/lib/CodeGen/MachineVerifier.cpp
@@ -101,6 +101,7 @@ namespace {
// Avoid querying the MachineFunctionProperties for each operand.
bool isFunctionRegBankSelected;
bool isFunctionSelected;
+ bool isFunctionTracksDebugUserValues;
using RegVector = SmallVector<Register, 16>;
using RegMaskVector = SmallVector<const uint32_t *, 4>;
@@ -384,6 +385,8 @@ unsigned MachineVerifier::verify(const MachineFunction &MF) {
MachineFunctionProperties::Property::RegBankSelected);
isFunctionSelected = MF.getProperties().hasProperty(
MachineFunctionProperties::Property::Selected);
+ isFunctionTracksDebugUserValues = MF.getProperties().hasProperty(
+ MachineFunctionProperties::Property::TracksDebugUserValues);
LiveVars = nullptr;
LiveInts = nullptr;
@@ -1980,41 +1983,50 @@ MachineVerifier::visitMachineOperand(const MachineOperand *MO, unsigned MONum) {
if (MO->isUndef())
report("Generic virtual register use cannot be undef", MO, MONum);
- // If we're post-Select, we can't have gvregs anymore.
- if (isFunctionSelected) {
- report("Generic virtual register invalid in a Selected function",
- MO, MONum);
- return;
- }
+ // Debug value instruction is permitted to use undefined vregs.
+ // This is a performance measure to skip the overhead of immediately
+ // pruning unused debug operands. The final undef substitution occurs
+ // when debug values are allocated in LDVImpl::handleDebugValue, so
+ // these verifications always apply after this pass.
+ if (isFunctionTracksDebugUserValues || !MO->isUse() ||
+ !MI->isDebugValue() || !MRI->def_empty(Reg)) {
+ // If we're post-Select, we can't have gvregs anymore.
+ if (isFunctionSelected) {
+ report("Generic virtual register invalid in a Selected function",
+ MO, MONum);
+ return;
+ }
- // The gvreg must have a type and it must not have a SubIdx.
- LLT Ty = MRI->getType(Reg);
- if (!Ty.isValid()) {
- report("Generic virtual register must have a valid type", MO,
- MONum);
- return;
- }
+ // The gvreg must have a type and it must not have a SubIdx.
+ LLT Ty = MRI->getType(Reg);
+ if (!Ty.isValid()) {
+ report("Generic virtual register must have a valid type", MO,
+ MONum);
+ return;
+ }
- const RegisterBank *RegBank = MRI->getRegBankOrNull(Reg);
+ const RegisterBank *RegBank = MRI->getRegBankOrNull(Reg);
- // If we're post-RegBankSelect, the gvreg must have a bank.
- if (!RegBank && isFunctionRegBankSelected) {
- report("Generic virtual register must have a bank in a "
- "RegBankSelected function",
- MO, MONum);
- return;
- }
+ // If we're post-RegBankSelect, the gvreg must have a bank.
+ if (!RegBank && isFunctionRegBankSelected) {
+ report("Generic virtual register must have a bank in a "
+ "RegBankSelected function",
+ MO, MONum);
+ return;
+ }
- // Make sure the register fits into its register bank if any.
- if (RegBank && Ty.isValid() &&
- RegBank->getSize() < Ty.getSizeInBits()) {
- report("Register bank is too small for virtual register", MO,
- MONum);
- errs() << "Register bank " << RegBank->getName() << " too small("
- << RegBank->getSize() << ") to fit " << Ty.getSizeInBits()
- << "-bits\n";
- return;
+ // Make sure the register fits into its register bank if any.
+ if (RegBank && Ty.isValid() &&
+ RegBank->getSize() < Ty.getSizeInBits()) {
+ report("Register bank is too small for virtual register", MO,
+ MONum);
+ errs() << "Register bank " << RegBank->getName() << " too small("
+ << RegBank->getSize() << ") to fit " << Ty.getSizeInBits()
+ << "-bits\n";
+ return;
+ }
}
+
if (SubIdx) {
report("Generic virtual register does not allow subregister index", MO,
MONum);
diff --git a/llvm/lib/Target/AMDGPU/SIFoldOperands.cpp b/llvm/lib/Target/AMDGPU/SIFoldOperands.cpp
index 200e00ee55212..1f93284fc7eeb 100644
--- a/llvm/lib/Target/AMDGPU/SIFoldOperands.cpp
+++ b/llvm/lib/Target/AMDGPU/SIFoldOperands.cpp
@@ -1620,7 +1620,7 @@ bool SIFoldOperands::tryFoldRegSequence(MachineInstr &MI) {
// Erase the REG_SEQUENCE eagerly, unless we followed a chain of COPY users,
// in which case we can erase them all later in runOnMachineFunction.
if (MRI->use_nodbg_empty(MI.getOperand(0).getReg()))
- MI.eraseFromParentAndMarkDBGValuesForRemoval();
+ MI.eraseFromParent();
return true;
}
@@ -1821,7 +1821,7 @@ bool SIFoldOperands::runOnMachineFunction(MachineFunction &MF) {
while (MRI->use_nodbg_empty(InstToErase->getOperand(0).getReg())) {
auto &SrcOp = InstToErase->getOperand(1);
auto SrcReg = SrcOp.isReg() ? SrcOp.getReg() : Register();
- InstToErase->eraseFromParentAndMarkDBGValuesForRemoval();
+ InstToErase->eraseFromParent();
InstToErase = nullptr;
if (!SrcReg || SrcReg.isPhysical())
break;
@@ -1831,7 +1831,7 @@ bool SIFoldOperands::runOnMachineFunction(MachineFunction &MF) {
}
if (InstToErase && InstToErase->isRegSequence() &&
MRI->use_nodbg_empty(InstToErase->getOperand(0).getReg()))
- InstToErase->eraseFromParentAndMarkDBGValuesForRemoval();
+ InstToErase->eraseFromParent();
}
}
return true;
diff --git a/llvm/lib/Target/NVPTX/NVPTXPeephole.cpp b/llvm/lib/Target/NVPTX/NVPTXPeephole.cpp
index 1f3b4c9440d8a..bf3c87df2e08a 100644
--- a/llvm/lib/Target/NVPTX/NVPTXPeephole.cpp
+++ b/llvm/lib/Target/NVPTX/NVPTXPeephole.cpp
@@ -126,9 +126,9 @@ static void CombineCVTAToLocal(MachineInstr &Root) {
// Check if MRI has only one non dbg use, which is Root
if (MRI.hasOneNonDBGUse(Prev.getOperand(0).getReg())) {
- Prev.eraseFromParentAndMarkDBGValuesForRemoval();
+ Prev.eraseFromParent();
}
- Root.eraseFromParentAndMarkDBGValuesForRemoval();
+ Root.eraseFromParent();
}
bool NVPTXPeephole::runOnMachineFunction(MachineFunction &MF) {
@@ -157,7 +157,7 @@ bool NVPTXPeephole::runOnMachineFunction(MachineFunction &MF) {
const auto &MRI = MF.getRegInfo();
if (MRI.use_empty(NRI->getFrameRegister(MF))) {
if (auto MI = MRI.getUniqueVRegDef(NRI->getFrameRegister(MF))) {
- MI->eraseFromParentAndMarkDBGValuesForRemoval();
+ MI->eraseFromParent();
}
}
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-dbg-value.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-dbg-value.mir
index 72fbfad89c23d..77365fee9cdf7 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/select-dbg-value.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-dbg-value.mir
@@ -62,7 +62,7 @@ body: |
liveins: $w0
; CHECK-LABEL: name: test_dbg_value_dead
; CHECK-NOT: COPY
- ; CHECK: DBG_VALUE $noreg, $noreg, !7, !DIExpression(), debug-location !9
+ ; CHECK: DBG_VALUE %0:gpr, $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/uaddo-8-16-bits.mir b/llvm/test/CodeGen/AArch64/GlobalISel/uaddo-8-16-bits.mir
index 8a235764e6156..95f9d962780ff 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/uaddo-8-16-bits.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/uaddo-8-16-bits.mir
@@ -310,7 +310,7 @@ body: |
; CHECK-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[ADD]], [[C]]
; CHECK-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
; CHECK-NEXT: [[ICMP:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), [[AND]](s32), [[C1]]
- ; CHECK-NEXT: DBG_VALUE $noreg
+ ; CHECK-NEXT: DBG_VALUE {{%[0-9]+}}:_(s16)
; CHECK-NEXT: G_BRCOND [[ICMP]](s1), %bb.2
; CHECK-NEXT: G_BR %bb.1
; CHECK-NEXT: {{ $}}
diff --git a/llvm/test/CodeGen/AMDGPU/fold-readlane.mir b/llvm/test/CodeGen/AMDGPU/fold-readlane.mir
index eb0e5b79b30b9..b76cf45c785f4 100644
--- a/llvm/test/CodeGen/AMDGPU/fold-readlane.mir
+++ b/llvm/test/CodeGen/AMDGPU/fold-readlane.mir
@@ -14,7 +14,7 @@ body: |
# GCN-LABEL: name: fold-imm-readfirstlane-dbgvalue{{$}}
# GCN: %1:sreg_32_xm0 = S_MOV_B32 123
-# GCN: DBG_VALUE $noreg, 0, 0
+# GCN: DBG_VALUE %0:vgpr_32, 0, 0
---
name: fold-imm-readfirstlane-dbgvalue
tracksRegLiveness: true
diff --git a/llvm/test/CodeGen/Generic/live-debug-vars-undef-use.mir b/llvm/test/CodeGen/Generic/live-debug-vars-undef-use.mir
new file mode 100644
index 0000000000000..62a5a2a76396c
--- /dev/null
+++ b/llvm/test/CodeGen/Generic/live-debug-vars-undef-use.mir
@@ -0,0 +1,26 @@
+# RUN: llc -verify-machineinstrs -run-pass=livedebugvars -o - %s | FileCheck %s
+# REQUIRES: aarch64-registered-target
+
+--- |
+
+ target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"
+ target triple = "aarch64--"
+ define i64 @test() { ret i64 0 }
+
+...
+
+---
+name: test
+tracksRegLiveness: true
+registers:
+ - { id: 0, class: _ }
+ - { id: 1, class: gpr64 }
+body: |
+ bb.0:
+ ; CHECK-LABEL: bb.0
+ ; CHECK-NEXT: %1:gpr64(s64) = G_CONSTANT i64 0
+ ; CHECK-NEXT: RET %1(s64)
+ DBG_VALUE %0, $noreg, $noreg, $noreg, $noreg
+ %1(s64) = G_CONSTANT i64 0
+ RET %1
+...
diff --git a/llvm/test/CodeGen/X86/GlobalISel/x86-calllowering-dbg-trunc.ll b/llvm/test/CodeGen/X86/GlobalISel/x86-calllowering-dbg-trunc.ll
new file mode 100644
index 0000000000000..90c9290a83bbd
--- /dev/null
+++ b/llvm/test/CodeGen/X86/GlobalISel/x86-calllowering-dbg-trunc.ll
@@ -0,0 +1,57 @@
+; RUN: llc -mtriple=i386-linux-gnu -global-isel -verify-machineinstrs < %s -o - | FileCheck %s --check-prefix=ALL
+
+; This file is the output of clang -g -O2
+; int test_dbg_trunc(unsigned long long a) { return a; }
+;
+; The intent of this check is to ensure the DBG_VALUE use of G_MERGE_VALUES is undef'd when the legalizer erases it.
+
+; ModuleID = 'x86-calllowering-dbg-trunc.c'
+source_filename = "x86-calllowering-dbg-trunc.c"
+target datalayout = "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-f64:32:64-f80:32-n8:16:32-S128"
+target triple = "i386"
+
+; Function Attrs: mustprogress nofree norecurse nosync nounwind readnone uwtable willreturn
+define dso_local i32 @test_dbg_trunc(i64 %a) local_unnamed_addr #0 !dbg !9 {
+; ALL-LABEL: test_dbg_trunc:
+; ALL: # %bb.0: # %entry
+; ALL: pushl %ebp
+; ALL: movl %esp, %ebp
+; ALL: movl 8(%ebp), %eax
+; ALL: #DEBUG_VALUE: test_dbg_trunc:a <- undef
+; ALL: popl %ebp
+; ALL: retl
+entry:
+ call void @llvm.dbg.value(metadata i64 %a, metadata !15, metadata !DIExpression()), !dbg !16
+ %conv = trunc i64 %a to i32, !dbg !17
+ ret i32 %conv, !dbg !18
+}
+
+; Function Attrs: nofree nosync nounwind readnone speculatable willreturn
+declare void @llvm.dbg.value(metadata, metadata, metadata) #1
+
+attributes #0 = { mustprogress nofree norecurse nosync nounwind readnone uwtable willreturn "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="pentium4" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }
+attributes #1 = { nofree nosync nounwind readnone speculatable willreturn }
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!2, !3, !4, !5, !6, !7}
+!llvm.ident = !{!8}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 14.0.0 (https://github.com/llvm/llvm-project ...)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None)
+!1 = !DIFile(filename: "x86-calllowering-dbg-trunc.c", directory: "/tmp")
+!2 = !{i32 1, !"NumRegisterParameters", i32 0}
+!3 = !{i32 7, !"Dwarf Version", i32 4}
+!4 = !{i32 2, !"Debug Info Version", i32 3}
+!5 = !{i32 1, !"wchar_size", i32 4}
+!6 = !{i32 7, !"uwtable", i32 1}
+!7 = !{i32 7, !"frame-pointer", i32 2}
+!8 = !{!"clang version 14.0.0 (https://github.com/llvm/llvm-project ...)"}
+!9 = distinct !DISubprogram(name: "test_dbg_trunc", scope: !1, file: !1, line: 1, type: !10, scopeLine: 1, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !14)
+!10 = !DISubroutineType(types: !11)
+!11 = !{!12, !13}
+!12 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+!13 = !DIBasicType(name: "unsigned long long", size: 64, encoding: DW_ATE_unsigned)
+!14 = !{!15}
+!15 = !DILocalVariable(name: "a", arg: 1, scope: !9, file: !1, line: 1, type: !13)
+!16 = !DILocation(line: 0, scope: !9)
+!17 = !DILocation(line: 1, column: 51, scope: !9)
+!18 = !DILocation(line: 1, column: 44, scope: !9)
diff --git a/llvm/test/MachineVerifier/verify-regbankselected-dbg-undef-use.mir b/llvm/test/MachineVerifier/verify-regbankselected-dbg-undef-use.mir
new file mode 100644
index 0000000000000..2745096079631
--- /dev/null
+++ b/llvm/test/MachineVerifier/verify-regbankselected-dbg-undef-use.mir
@@ -0,0 +1,38 @@
+# RUN: not --crash llc -verify-machineinstrs -run-pass none -o /dev/null %s 2>&1 | FileCheck %s
+# REQUIRES: aarch64-registered-target
+
+--- |
+
+ target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"
+ target triple = "aarch64--"
+ define void @regbankselected_notrack() { ret void }
+ define void @regbankselected_track() { ret void }
+
+...
+
+---
+name: regbankselected_notrack
+regBankSelected: true
+tracksDebugUserValues: false
+registers:
+ - { id: 0, class: _ }
+body: |
+ bb.0:
+ ; CHECK-NOT: function: regbankselected_notrack
+ DBG_VALUE %0(s64), $noreg, $noreg, $noreg, $noreg
+...
+
+---
+name: regbankselected_track
+regBankSelected: true
+tracksDebugUserValues: true
+registers:
+ - { id: 0, class: _ }
+body: |
+ bb.0:
+ ; CHECK: *** Bad machine code: Generic virtual register must have a bank in a RegBankSelected function ***
+ ; CHECK: function: regbankselected_track
+ ; CHECK: instruction: DBG_VALUE %0:_
+ ; CHECK: operand 0: %0
+ DBG_VALUE %0(s64), $noreg, $noreg, $noreg, $noreg
+...
diff --git a/llvm/test/MachineVerifier/verify-selected-dbg-undef-use.mir b/llvm/test/MachineVerifier/verify-selected-dbg-undef-use.mir
new file mode 100644
index 0000000000000..1c3e0f22e698c
--- /dev/null
+++ b/llvm/test/MachineVerifier/verify-selected-dbg-undef-use.mir
@@ -0,0 +1,40 @@
+# RUN: not --crash llc -verify-machineinstrs -run-pass none -o /dev/null %s 2>&1 | FileCheck %s
+# REQUIRES: aarch64-registered-target
+
+--- |
+
+ target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"
+ target triple = "aarch64--"
+ define void @selected_notrack() { ret void }
+ define void @selected_track() { ret void }
+
+...
+
+---
+name: selected_notrack
+regBankSelected: true
+selected: true
+tracksDebugUserValues: false
+registers:
+ - { id: 0, class: _ }
+body: |
+ bb.0:
+ ; CHECK-NOT: function: selected_notrack
+ DBG_VALUE %0, $noreg, $noreg, $noreg, $noreg
+...
+
+---
+name: selected_track
+regBankSelected: true
+selected: true
+tracksDebugUserValues: true
+registers:
+ - { id: 0, class: _ }
+body: |
+ bb.0:
+ ; CHECK: *** Bad machine code: Generic virtual register invalid in a Selected function ***
+ ; CHECK: function: selected_track
+ ; CHECK: instruction: DBG_VALUE %0:_
+ ; CHECK: operand 0: %0
+ DBG_VALUE %0, $noreg, $noreg, $noreg, $noreg
+...
More information about the llvm-commits
mailing list