diff options
Diffstat (limited to 'llvm/lib/CodeGen')
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp | 7 | ||||
-rw-r--r-- | llvm/lib/CodeGen/TargetInstrInfo.cpp | 21 |
2 files changed, 23 insertions, 5 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp index 1c5a244d7c5..96ce3600417 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp @@ -246,8 +246,8 @@ bool DwarfExpression::addMachineRegExpression(const TargetRegisterInfo &TRI, // a call site parameter expression and if that expression is just a register // location, emit it with addBReg and offset 0, because we should emit a DWARF // expression representing a value, rather than a location. - if (!isMemoryLocation() && !HasComplexExpression && - (!isParameterValue() || isEntryValue())) { + if (!isMemoryLocation() && !HasComplexExpression && (!isParameterValue() || + isEntryValue())) { for (auto &Reg : DwarfRegs) { if (Reg.DwarfRegNo >= 0) addReg(Reg.DwarfRegNo, Reg.Comment); @@ -436,9 +436,6 @@ void DwarfExpression::addExpression(DIExpressionCursor &&ExprCursor, break; case dwarf::DW_OP_deref: assert(!isRegisterLocation()); - // For more detailed explanation see llvm.org/PR43343. - assert(!isParameterValue() && "Parameter entry values should not be " - "dereferenced due to safety reasons."); if (!isMemoryLocation() && ::isMemoryLocation(ExprCursor)) // Turning this into a memory location description makes the deref // implicit. diff --git a/llvm/lib/CodeGen/TargetInstrInfo.cpp b/llvm/lib/CodeGen/TargetInstrInfo.cpp index 81238307d3f..2b987dabd24 100644 --- a/llvm/lib/CodeGen/TargetInstrInfo.cpp +++ b/llvm/lib/CodeGen/TargetInstrInfo.cpp @@ -1131,6 +1131,27 @@ TargetInstrInfo::describeLoadedValue(const MachineInstr &MI) const { } else if (auto DestSrc = isAddImmediate(MI, Offset)) { Expr = DIExpression::prepend(Expr, DIExpression::ApplyOffset, Offset); return ParamLoadedValue(*DestSrc->Source, Expr); + } else if (MI.hasOneMemOperand()) { + // Only describe memory which provably does not escape the function. As + // described in llvm.org/PR43343, escaped memory may be clobbered by the + // callee (or by another thread). + const auto &TII = MF->getSubtarget().getInstrInfo(); + const MachineFrameInfo &MFI = MF->getFrameInfo(); + const MachineMemOperand *MMO = MI.memoperands()[0]; + const PseudoSourceValue *PSV = MMO->getPseudoValue(); + + // If the address points to "special" memory (e.g. a spill slot), it's + // sufficient to check that it isn't aliased by any high-level IR value. + if (!PSV || PSV->mayAlias(&MFI)) + return None; + + const auto &TRI = MF->getSubtarget().getRegisterInfo(); + const MachineOperand *BaseOp; + if (!TII->getMemOperandWithOffset(MI, BaseOp, Offset, TRI)) + return None; + + Expr = DIExpression::prepend(Expr, DIExpression::DerefAfter, Offset); + return ParamLoadedValue(*BaseOp, Expr); } return None; |