diff options
author | Jeremy Morse <jeremy.morse@sony.com> | 2022-02-10 11:07:15 +0000 |
---|---|---|
committer | Jeremy Morse <jeremy.morse@sony.com> | 2022-02-10 11:25:08 +0000 |
commit | be5734ddaae3521f8ccf3dbf4e747f51aa448936 (patch) | |
tree | 42d7af9ab53e5c9e84d86cbae3f5dd7feb16c075 /llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.cpp | |
parent | 8fa45b826a68037904e2c4b7a9e2de7c4a798bd3 (diff) | |
download | llvm-be5734ddaae3521f8ccf3dbf4e747f51aa448936.zip llvm-be5734ddaae3521f8ccf3dbf4e747f51aa448936.tar.gz llvm-be5734ddaae3521f8ccf3dbf4e747f51aa448936.tar.bz2 |
[DebugInfo][InstrRef] Don't fire assertions if debug-info is faulty
It's inevitable that optimisation passes will fail to update debug-info:
when that happens, it's best if the compiler doesn't crash as a result.
Therefore, downgrade a few assertions / failure modes that would crash
when illegal debug-info was seen, to instead drop variable locations. In
practice this means that an instruction reference to a nonexistant or
illegal operand should be tolerated.
Differential Revision: https://reviews.llvm.org/D118998
Diffstat (limited to 'llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.cpp')
-rw-r--r-- | llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.cpp | 79 |
1 files changed, 58 insertions, 21 deletions
diff --git a/llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.cpp b/llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.cpp index b6632f9..4c2484f 100644 --- a/llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.cpp +++ b/llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.cpp @@ -1091,15 +1091,25 @@ bool InstrRefBasedLDV::transferDebugInstrRef(MachineInstr &MI, if (L) NewID = ValueIDNum(BlockNo, InstrIt->second.second, *L); } else if (OpNo != MachineFunction::DebugOperandMemNumber) { - assert(OpNo < TargetInstr.getNumOperands()); - const MachineOperand &MO = TargetInstr.getOperand(OpNo); - - // Today, this can only be a register. - assert(MO.isReg() && MO.isDef()); + // Permit the debug-info to be completely wrong: identifying a nonexistant + // operand, or one that is not a register definition, means something + // unexpected happened during optimisation. Broken debug-info, however, + // shouldn't crash the compiler -- instead leave the variable value as + // None, which will make it appear "optimised out". + if (OpNo < TargetInstr.getNumOperands()) { + const MachineOperand &MO = TargetInstr.getOperand(OpNo); + + if (MO.isReg() && MO.isDef() && MO.getReg()) { + unsigned LocID = MTracker->getLocID(MO.getReg()); + LocIdx L = MTracker->LocIDToLocIdx[LocID]; + NewID = ValueIDNum(BlockNo, InstrIt->second.second, L); + } + } - unsigned LocID = MTracker->getLocID(MO.getReg()); - LocIdx L = MTracker->LocIDToLocIdx[LocID]; - NewID = ValueIDNum(BlockNo, InstrIt->second.second, L); + if (!NewID) { + LLVM_DEBUG( + { dbgs() << "Seen instruction reference to illegal operand\n"; }); + } } // else: NewID is left as None. } else if (PHIIt != DebugPHINumToValue.end() && PHIIt->InstrNum == InstNo) { @@ -1249,7 +1259,16 @@ bool InstrRefBasedLDV::transferDebugPHI(MachineInstr &MI) { const MachineOperand &MO = MI.getOperand(0); unsigned InstrNum = MI.getOperand(1).getImm(); - if (MO.isReg()) { + auto EmitBadPHI = [this, &MI, InstrNum](void) -> bool { + // Helper lambda to do any accounting when we fail to find a location for + // a DBG_PHI. This can happen if DBG_PHIs are malformed, or refer to a + // dead stack slot, for example. + // Record a DebugPHIRecord with an empty value + location. + DebugPHINumToValue.push_back({InstrNum, MI.getParent(), None, None}); + return true; + }; + + if (MO.isReg() && MO.getReg()) { // The value is whatever's currently in the register. Read and record it, // to be analysed later. Register Reg = MO.getReg(); @@ -1261,15 +1280,14 @@ bool InstrRefBasedLDV::transferDebugPHI(MachineInstr &MI) { // Ensure this register is tracked. for (MCRegAliasIterator RAI(MO.getReg(), TRI, true); RAI.isValid(); ++RAI) MTracker->lookupOrTrackRegister(*RAI); - } else { + } else if (MO.isFI()) { // The value is whatever's in this stack slot. - assert(MO.isFI()); unsigned FI = MO.getIndex(); // If the stack slot is dead, then this was optimized away. // FIXME: stack slot colouring should account for slots that get merged. if (MFI->isDeadObjectIndex(FI)) - return true; + return EmitBadPHI(); // Identify this spill slot, ensure it's tracked. Register Base; @@ -1280,7 +1298,7 @@ bool InstrRefBasedLDV::transferDebugPHI(MachineInstr &MI) { // We might be able to find a value, but have chosen not to, to avoid // tracking too much stack information. if (!SpillNo) - return true; + return EmitBadPHI(); // Problem: what value should we extract from the stack? LLVM does not // record what size the last store to the slot was, and it would become @@ -1315,8 +1333,17 @@ bool InstrRefBasedLDV::transferDebugPHI(MachineInstr &MI) { } // Record this DBG_PHI for later analysis. - auto DbgPHI = DebugPHIRecord({InstrNum, MI.getParent(), *Result, *SpillLoc}); + auto DbgPHI = + DebugPHIRecord({InstrNum, MI.getParent(), *Result, *SpillLoc}); DebugPHINumToValue.push_back(DbgPHI); + } else { + // Else: if the operand is neither a legal register or a stack slot, then + // we're being fed illegal debug-info. Record an empty PHI, so that any + // debug users trying to read this number will be put off trying to + // interpret the value. + LLVM_DEBUG( + { dbgs() << "Seen DBG_PHI with unrecognised operand format\n"; }); + return EmitBadPHI(); } return true; @@ -3165,7 +3192,10 @@ bool InstrRefBasedLDV::ExtendRanges(MachineFunction &MF, // either live-through machine values, or PHIs. for (auto &DBG_PHI : DebugPHINumToValue) { // Identify unresolved block-live-ins. - ValueIDNum &Num = DBG_PHI.ValueRead; + if (!DBG_PHI.ValueRead) + continue; + + ValueIDNum &Num = *DBG_PHI.ValueRead; if (!Num.isPHI()) continue; @@ -3566,17 +3596,24 @@ Optional<ValueIDNum> InstrRefBasedLDV::resolveDbgPHIsImpl( if (LowerIt == UpperIt) return None; + // If any DBG_PHIs referred to a location we didn't understand, don't try to + // compute a value. There might be scenarios where we could recover a value + // for some range of DBG_INSTR_REFs, but at this point we can have high + // confidence that we've seen a bug. + auto DBGPHIRange = make_range(LowerIt, UpperIt); + for (const DebugPHIRecord &DBG_PHI : DBGPHIRange) + if (!DBG_PHI.ValueRead) + return None; + // If there's only one DBG_PHI, then that is our value number. if (std::distance(LowerIt, UpperIt) == 1) - return LowerIt->ValueRead; - - auto DBGPHIRange = make_range(LowerIt, UpperIt); + return *LowerIt->ValueRead; // Pick out the location (physreg, slot) where any PHIs must occur. It's // technically possible for us to merge values in different registers in each // block, but highly unlikely that LLVM will generate such code after register // allocation. - LocIdx Loc = LowerIt->ReadLoc; + LocIdx Loc = *LowerIt->ReadLoc; // We have several DBG_PHIs, and a use position (the Here inst). All each // DBG_PHI does is identify a value at a program position. We can treat each @@ -3595,7 +3632,7 @@ Optional<ValueIDNum> InstrRefBasedLDV::resolveDbgPHIsImpl( // for the SSAUpdater. for (const auto &DBG_PHI : DBGPHIRange) { LDVSSABlock *Block = Updater.getSSALDVBlock(DBG_PHI.MBB); - const ValueIDNum &Num = DBG_PHI.ValueRead; + const ValueIDNum &Num = *DBG_PHI.ValueRead; AvailableValues.insert(std::make_pair(Block, Num.asU64())); } @@ -3629,7 +3666,7 @@ Optional<ValueIDNum> InstrRefBasedLDV::resolveDbgPHIsImpl( // Define all the input DBG_PHI values in ValidatedValues. for (const auto &DBG_PHI : DBGPHIRange) { LDVSSABlock *Block = Updater.getSSALDVBlock(DBG_PHI.MBB); - const ValueIDNum &Num = DBG_PHI.ValueRead; + const ValueIDNum &Num = *DBG_PHI.ValueRead; ValidatedValues.insert(std::make_pair(Block, Num)); } |