[llvm] r356442 - [DebugInfo] Introduce DW_OP_LLVM_convert

Markus Lavin via llvm-commits llvm-commits at lists.llvm.org
Tue Mar 19 01:48:19 PDT 2019


Author: markus
Date: Tue Mar 19 01:48:19 2019
New Revision: 356442

URL: http://llvm.org/viewvc/llvm-project?rev=356442&view=rev
Log:
[DebugInfo] Introduce DW_OP_LLVM_convert

Introduce a DW_OP_LLVM_convert Dwarf expression pseudo op that allows
for a convenient way to perform type conversions on the Dwarf expression
stack. As an additional bonus it paves the way for using other Dwarf
v5 ops that need to reference a base_type.

The new DW_OP_LLVM_convert is used from lib/Transforms/Utils/Local.cpp
to perform sext/zext on debug values but mainly the patch is about
preparing terrain for adding other Dwarf v5 ops that need to reference a
base_type.

For Dwarf v5 the op maps to DW_OP_convert and for earlier versions a
complex shift & mask pattern is generated to emulate sext/zext.

Differential Revision: https://reviews.llvm.org/D56587

Added:
    llvm/trunk/test/DebugInfo/Generic/convert-debugloc.ll
    llvm/trunk/test/DebugInfo/Generic/convert-inlined.ll
    llvm/trunk/test/DebugInfo/Generic/convert-linked.ll
Modified:
    llvm/trunk/docs/LangRef.rst
    llvm/trunk/include/llvm/BinaryFormat/Dwarf.h
    llvm/trunk/include/llvm/CodeGen/AsmPrinter.h
    llvm/trunk/include/llvm/CodeGen/DIE.h
    llvm/trunk/include/llvm/CodeGen/DIEValue.def
    llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFDebugLoc.h
    llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFExpression.h
    llvm/trunk/include/llvm/MC/MCStreamer.h
    llvm/trunk/lib/AsmParser/LLParser.cpp
    llvm/trunk/lib/BinaryFormat/Dwarf.cpp
    llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp
    llvm/trunk/lib/CodeGen/AsmPrinter/ByteStreamer.h
    llvm/trunk/lib/CodeGen/AsmPrinter/DIE.cpp
    llvm/trunk/lib/CodeGen/AsmPrinter/DIEHash.cpp
    llvm/trunk/lib/CodeGen/AsmPrinter/DebugLocEntry.h
    llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
    llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h
    llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
    llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h
    llvm/trunk/lib/CodeGen/AsmPrinter/DwarfExpression.cpp
    llvm/trunk/lib/CodeGen/AsmPrinter/DwarfExpression.h
    llvm/trunk/lib/CodeGen/AsmPrinter/DwarfFile.h
    llvm/trunk/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
    llvm/trunk/lib/CodeGen/AsmPrinter/LLVMBuild.txt
    llvm/trunk/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp
    llvm/trunk/lib/DebugInfo/DWARF/DWARFDie.cpp
    llvm/trunk/lib/DebugInfo/DWARF/DWARFExpression.cpp
    llvm/trunk/lib/IR/AsmWriter.cpp
    llvm/trunk/lib/IR/DebugInfoMetadata.cpp
    llvm/trunk/lib/MC/MCStreamer.cpp
    llvm/trunk/lib/Transforms/Utils/Local.cpp
    llvm/trunk/test/Assembler/diexpression.ll
    llvm/trunk/test/Transforms/InstCombine/cast-set-preserve-signed-dbg-val.ll
    llvm/trunk/unittests/Transforms/Utils/LocalTest.cpp

Modified: llvm/trunk/docs/LangRef.rst
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/LangRef.rst?rev=356442&r1=356441&r2=356442&view=diff
==============================================================================
--- llvm/trunk/docs/LangRef.rst (original)
+++ llvm/trunk/docs/LangRef.rst Tue Mar 19 01:48:19 2019
@@ -4682,6 +4682,10 @@ The current supported opcode vocabulary
   here, respectively) of the variable fragment from the working expression. Note
   that contrary to DW_OP_bit_piece, the offset is describing the location
   within the described source variable.
+- ``DW_OP_LLVM_convert, 16, DW_ATE_signed`` specifies a bit size and encoding
+  (``16`` and ``DW_ATE_signed`` here, respectively) to which the top of the
+  expression stack is to be converted. Maps into a ``DW_OP_convert`` operation
+  that references a base type constructed from the supplied values.
 - ``DW_OP_swap`` swaps top two stack entries.
 - ``DW_OP_xderef`` provides extended dereference mechanism. The entry at the top
   of the stack is treated as an address. The second stack entry is treated as an

Modified: llvm/trunk/include/llvm/BinaryFormat/Dwarf.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/BinaryFormat/Dwarf.h?rev=356442&r1=356441&r2=356442&view=diff
==============================================================================
--- llvm/trunk/include/llvm/BinaryFormat/Dwarf.h (original)
+++ llvm/trunk/include/llvm/BinaryFormat/Dwarf.h Tue Mar 19 01:48:19 2019
@@ -129,7 +129,8 @@ enum LocationAtom {
 #include "llvm/BinaryFormat/Dwarf.def"
   DW_OP_lo_user = 0xe0,
   DW_OP_hi_user = 0xff,
-  DW_OP_LLVM_fragment = 0x1000 ///< Only used in LLVM metadata.
+  DW_OP_LLVM_fragment = 0x1000, ///< Only used in LLVM metadata.
+  DW_OP_LLVM_convert  = 0x1001  ///< Only used in LLVM metadata.
 };
 
 enum TypeKind : uint8_t {

Modified: llvm/trunk/include/llvm/CodeGen/AsmPrinter.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/AsmPrinter.h?rev=356442&r1=356441&r2=356442&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/AsmPrinter.h (original)
+++ llvm/trunk/include/llvm/CodeGen/AsmPrinter.h Tue Mar 19 01:48:19 2019
@@ -510,7 +510,7 @@ public:
   void EmitSLEB128(int64_t Value, const char *Desc = nullptr) const;
 
   /// Emit the specified unsigned leb128 value.
-  void EmitULEB128(uint64_t Value, const char *Desc = nullptr) const;
+  void EmitULEB128(uint64_t Value, const char *Desc = nullptr, unsigned PadTo = 0) const;
 
   /// Emit a .byte 42 directive that corresponds to an encoding.  If verbose
   /// assembly output is enabled, we output comments describing the encoding.

Modified: llvm/trunk/include/llvm/CodeGen/DIE.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/DIE.h?rev=356442&r1=356441&r2=356442&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/DIE.h (original)
+++ llvm/trunk/include/llvm/CodeGen/DIE.h Tue Mar 19 01:48:19 2019
@@ -38,6 +38,7 @@ namespace llvm {
 class AsmPrinter;
 class DIE;
 class DIEUnit;
+class DwarfCompileUnit;
 class MCExpr;
 class MCSection;
 class MCSymbol;
@@ -230,6 +231,25 @@ public:
 };
 
 //===--------------------------------------------------------------------===//
+/// A BaseTypeRef DIE.
+class DIEBaseTypeRef {
+  const DwarfCompileUnit *CU;
+  const uint64_t Index;
+  static constexpr unsigned ULEB128PadSize = 4;
+
+public:
+  explicit DIEBaseTypeRef(const DwarfCompileUnit *TheCU, uint64_t Idx)
+    : CU(TheCU), Index(Idx) {}
+
+  /// EmitValue - Emit base type reference.
+  void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const;
+  /// SizeOf - Determine size of the base type reference in bytes.
+  unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const;
+
+  void print(raw_ostream &O) const;
+};
+
+//===--------------------------------------------------------------------===//
 /// A simple label difference DIE.
 ///
 class DIEDelta {
@@ -349,7 +369,7 @@ private:
   /// should be stored by reference instead of by value.
   using ValTy = AlignedCharArrayUnion<DIEInteger, DIEString, DIEExpr, DIELabel,
                                       DIEDelta *, DIEEntry, DIEBlock *,
-                                      DIELoc *, DIELocList>;
+                                      DIELoc *, DIELocList, DIEBaseTypeRef *>;
 
   static_assert(sizeof(ValTy) <= sizeof(uint64_t) ||
                     sizeof(ValTy) <= sizeof(void *),
@@ -501,6 +521,18 @@ struct IntrusiveBackListBase {
     }
     Last = &N;
   }
+
+  void push_front(Node &N) {
+    assert(N.Next.getPointer() == &N && "Expected unlinked node");
+    assert(N.Next.getInt() == true && "Expected unlinked node");
+
+    if (Last) {
+      N.Next.setPointerAndInt(Last->Next.getPointer(), false);
+      Last->Next.setPointerAndInt(&N, true);
+    } else {
+      Last = &N;
+    }
+  }
 };
 
 template <class T> class IntrusiveBackList : IntrusiveBackListBase {
@@ -508,8 +540,15 @@ public:
   using IntrusiveBackListBase::empty;
 
   void push_back(T &N) { IntrusiveBackListBase::push_back(N); }
+  void push_front(T &N) { IntrusiveBackListBase::push_front(N); }
   T &back() { return *static_cast<T *>(Last); }
   const T &back() const { return *static_cast<T *>(Last); }
+  T &front() {
+    return *static_cast<T *>(Last ? Last->Next.getPointer() : nullptr);
+  }
+  const T &front() const {
+    return *static_cast<T *>(Last ? Last->Next.getPointer() : nullptr);
+  }
 
   class const_iterator;
   class iterator
@@ -772,6 +811,13 @@ public:
     return Children.back();
   }
 
+  DIE &addChildFront(DIE *Child) {
+    assert(!Child->getParent() && "Child should be orphaned");
+    Child->Owner = this;
+    Children.push_front(*Child);
+    return Children.front();
+  }
+
   /// Find a value in the DIE with the attribute given.
   ///
   /// Returns a default-constructed DIEValue (where \a DIEValue::getType()

Modified: llvm/trunk/include/llvm/CodeGen/DIEValue.def
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/DIEValue.def?rev=356442&r1=356441&r2=356442&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/DIEValue.def (original)
+++ llvm/trunk/include/llvm/CodeGen/DIEValue.def Tue Mar 19 01:48:19 2019
@@ -34,6 +34,7 @@ HANDLE_DIEVALUE_SMALL(Integer)
 HANDLE_DIEVALUE_SMALL(String)
 HANDLE_DIEVALUE_SMALL(Expr)
 HANDLE_DIEVALUE_SMALL(Label)
+HANDLE_DIEVALUE_LARGE(BaseTypeRef)
 HANDLE_DIEVALUE_LARGE(Delta)
 HANDLE_DIEVALUE_SMALL(Entry)
 HANDLE_DIEVALUE_LARGE(Block)

Modified: llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFDebugLoc.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFDebugLoc.h?rev=356442&r1=356441&r2=356442&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFDebugLoc.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFDebugLoc.h Tue Mar 19 01:48:19 2019
@@ -86,7 +86,7 @@ public:
     SmallVector<Entry, 2> Entries;
     void dump(raw_ostream &OS, uint64_t BaseAddr, bool IsLittleEndian,
               unsigned AddressSize, const MCRegisterInfo *RegInfo,
-              unsigned Indent) const;
+              DWARFUnit *U, unsigned Indent) const;
   };
 
 private:

Modified: llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFExpression.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFExpression.h?rev=356442&r1=356441&r2=356442&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFExpression.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFExpression.h Tue Mar 19 01:48:19 2019
@@ -79,11 +79,13 @@ public:
     bool Error;
     uint32_t EndOffset;
     uint64_t Operands[2];
+    uint32_t OperandEndOffsets[2];
 
   public:
     Description &getDescription() { return Desc; }
     uint8_t getCode() { return Opcode; }
     uint64_t getRawOperand(unsigned Idx) { return Operands[Idx]; }
+    uint32_t getOperandEndOffset(unsigned Idx) { return OperandEndOffsets[Idx]; }
     uint32_t getEndOffset() { return EndOffset; }
     bool extract(DataExtractor Data, uint16_t Version, uint8_t AddressSize,
                  uint32_t Offset);

Modified: llvm/trunk/include/llvm/MC/MCStreamer.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCStreamer.h?rev=356442&r1=356441&r2=356442&view=diff
==============================================================================
--- llvm/trunk/include/llvm/MC/MCStreamer.h (original)
+++ llvm/trunk/include/llvm/MC/MCStreamer.h Tue Mar 19 01:48:19 2019
@@ -634,7 +634,7 @@ public:
 
   /// Special case of EmitULEB128Value that avoids the client having to
   /// pass in a MCExpr for constant integers.
-  void EmitULEB128IntValue(uint64_t Value);
+  void EmitULEB128IntValue(uint64_t Value, unsigned PadTo = 0);
 
   /// Special case of EmitSLEB128Value that avoids the client having to
   /// pass in a MCExpr for constant integers.

Modified: llvm/trunk/lib/AsmParser/LLParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLParser.cpp?rev=356442&r1=356441&r2=356442&view=diff
==============================================================================
--- llvm/trunk/lib/AsmParser/LLParser.cpp (original)
+++ llvm/trunk/lib/AsmParser/LLParser.cpp Tue Mar 19 01:48:19 2019
@@ -4838,6 +4838,15 @@ bool LLParser::ParseDIExpression(MDNode
         return TokError(Twine("invalid DWARF op '") + Lex.getStrVal() + "'");
       }
 
+      if (Lex.getKind() == lltok::DwarfAttEncoding) {
+        if (unsigned Op = dwarf::getAttributeEncoding(Lex.getStrVal())) {
+          Lex.Lex();
+          Elements.push_back(Op);
+          continue;
+        }
+        return TokError(Twine("invalid DWARF attribute encoding '") + Lex.getStrVal() + "'");
+      }
+
       if (Lex.getKind() != lltok::APSInt || Lex.getAPSIntVal().isSigned())
         return TokError("expected unsigned integer");
 

Modified: llvm/trunk/lib/BinaryFormat/Dwarf.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/BinaryFormat/Dwarf.cpp?rev=356442&r1=356441&r2=356442&view=diff
==============================================================================
--- llvm/trunk/lib/BinaryFormat/Dwarf.cpp (original)
+++ llvm/trunk/lib/BinaryFormat/Dwarf.cpp Tue Mar 19 01:48:19 2019
@@ -143,6 +143,8 @@ StringRef llvm::dwarf::OperationEncoding
   case DW_OP_##NAME:                                                           \
     return "DW_OP_" #NAME;
 #include "llvm/BinaryFormat/Dwarf.def"
+  case DW_OP_LLVM_convert:
+    return "DW_OP_LLVM_convert";
   case DW_OP_LLVM_fragment:
     return "DW_OP_LLVM_fragment";
   }
@@ -153,6 +155,7 @@ unsigned llvm::dwarf::getOperationEncodi
 #define HANDLE_DW_OP(ID, NAME, VERSION, VENDOR)                                \
   .Case("DW_OP_" #NAME, DW_OP_##NAME)
 #include "llvm/BinaryFormat/Dwarf.def"
+      .Case("DW_OP_LLVM_convert", DW_OP_LLVM_convert)
       .Case("DW_OP_LLVM_fragment", DW_OP_LLVM_fragment)
       .Default(0);
 }

Modified: llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp?rev=356442&r1=356441&r2=356442&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp Tue Mar 19 01:48:19 2019
@@ -42,11 +42,11 @@ void AsmPrinter::EmitSLEB128(int64_t Val
   OutStreamer->EmitSLEB128IntValue(Value);
 }
 
-void AsmPrinter::EmitULEB128(uint64_t Value, const char *Desc) const {
+void AsmPrinter::EmitULEB128(uint64_t Value, const char *Desc, unsigned PadTo) const {
   if (isVerbose() && Desc)
     OutStreamer->AddComment(Desc);
 
-  OutStreamer->EmitULEB128IntValue(Value);
+  OutStreamer->EmitULEB128IntValue(Value, PadTo);
 }
 
 /// Emit something like ".uleb128 Hi-Lo".

Modified: llvm/trunk/lib/CodeGen/AsmPrinter/ByteStreamer.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/ByteStreamer.h?rev=356442&r1=356441&r2=356442&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/ByteStreamer.h (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/ByteStreamer.h Tue Mar 19 01:48:19 2019
@@ -31,7 +31,7 @@ class ByteStreamer {
   // For now we're just handling the calls we need for dwarf emission/hashing.
   virtual void EmitInt8(uint8_t Byte, const Twine &Comment = "") = 0;
   virtual void EmitSLEB128(uint64_t DWord, const Twine &Comment = "") = 0;
-  virtual void EmitULEB128(uint64_t DWord, const Twine &Comment = "") = 0;
+  virtual void EmitULEB128(uint64_t DWord, const Twine &Comment = "", unsigned PadTo = 0) = 0;
 };
 
 class APByteStreamer final : public ByteStreamer {
@@ -48,7 +48,7 @@ public:
     AP.OutStreamer->AddComment(Comment);
     AP.EmitSLEB128(DWord);
   }
-  void EmitULEB128(uint64_t DWord, const Twine &Comment) override {
+  void EmitULEB128(uint64_t DWord, const Twine &Comment, unsigned PadTo) override {
     AP.OutStreamer->AddComment(Comment);
     AP.EmitULEB128(DWord);
   }
@@ -65,7 +65,7 @@ class HashingByteStreamer final : public
   void EmitSLEB128(uint64_t DWord, const Twine &Comment) override {
     Hash.addSLEB128(DWord);
   }
-  void EmitULEB128(uint64_t DWord, const Twine &Comment) override {
+  void EmitULEB128(uint64_t DWord, const Twine &Comment, unsigned PadTo) override {
     Hash.addULEB128(DWord);
   }
 };
@@ -102,9 +102,9 @@ public:
 
     }
   }
-  void EmitULEB128(uint64_t DWord, const Twine &Comment) override {
+  void EmitULEB128(uint64_t DWord, const Twine &Comment, unsigned PadTo) override {
     raw_svector_ostream OSE(Buffer);
-    unsigned Length = encodeULEB128(DWord, OSE);
+    unsigned Length = encodeULEB128(DWord, OSE, PadTo);
     if (GenerateComments) {
       Comments.push_back(Comment.str());
       // Add some empty comments to keep the Buffer and Comments vectors aligned

Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DIE.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DIE.cpp?rev=356442&r1=356441&r2=356442&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/DIE.cpp (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/DIE.cpp Tue Mar 19 01:48:19 2019
@@ -506,6 +506,23 @@ LLVM_DUMP_METHOD
 void DIELabel::print(raw_ostream &O) const { O << "Lbl: " << Label->getName(); }
 
 //===----------------------------------------------------------------------===//
+// DIEBaseTypeRef Implementation
+//===----------------------------------------------------------------------===//
+
+void DIEBaseTypeRef::EmitValue(const AsmPrinter *AP, dwarf::Form Form) const {
+  uint64_t Offset = CU->ExprRefedBaseTypes[Index].Die->getOffset();
+  assert(Offset < (1ULL << (ULEB128PadSize * 7)) && "Offset wont fit");
+  AP->EmitULEB128(Offset, nullptr, ULEB128PadSize);
+}
+
+unsigned DIEBaseTypeRef::SizeOf(const AsmPrinter *AP, dwarf::Form Form) const {
+  return ULEB128PadSize;
+}
+
+LLVM_DUMP_METHOD
+void DIEBaseTypeRef::print(raw_ostream &O) const { O << "BaseTypeRef: " << Index; }
+
+//===----------------------------------------------------------------------===//
 // DIEDelta Implementation
 //===----------------------------------------------------------------------===//
 

Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DIEHash.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DIEHash.cpp?rev=356442&r1=356441&r2=356442&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/DIEHash.cpp (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/DIEHash.cpp Tue Mar 19 01:48:19 2019
@@ -225,7 +225,7 @@ void DIEHash::hashLocList(const DIELocLi
   DwarfDebug &DD = *AP->getDwarfDebug();
   const DebugLocStream &Locs = DD.getDebugLocs();
   for (const auto &Entry : Locs.getEntries(Locs.getList(LocList.getValue())))
-    DD.emitDebugLocEntry(Streamer, Entry);
+    DD.emitDebugLocEntry(Streamer, Entry, nullptr);
 }
 
 // Hash an individual attribute \param Attr based on the type of attribute and
@@ -309,6 +309,7 @@ void DIEHash::hashAttribute(const DIEVal
     // FIXME: It's uncertain whether or not we should handle this at the moment.
   case DIEValue::isExpr:
   case DIEValue::isLabel:
+  case DIEValue::isBaseTypeRef:
   case DIEValue::isDelta:
     llvm_unreachable("Add support for additional value types.");
   }

Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DebugLocEntry.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DebugLocEntry.h?rev=356442&r1=356441&r2=356442&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/DebugLocEntry.h (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/DebugLocEntry.h Tue Mar 19 01:48:19 2019
@@ -148,8 +148,10 @@ public:
   }
 
   /// Lower this entry into a DWARF expression.
-  void finalize(const AsmPrinter &AP, DebugLocStream::ListBuilder &List,
-                const DIBasicType *BT);
+  void finalize(const AsmPrinter &AP,
+                DebugLocStream::ListBuilder &List,
+                const DIBasicType *BT,
+                DwarfCompileUnit &TheCU);
 };
 
 /// Compare two Values for equality.

Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp?rev=356442&r1=356441&r2=356442&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp Tue Mar 19 01:48:19 2019
@@ -17,6 +17,7 @@
 #include "DwarfUnit.h"
 #include "llvm/ADT/None.h"
 #include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/BinaryFormat/Dwarf.h"
@@ -1185,3 +1186,26 @@ void DwarfCompileUnit::addAddrTableBase(
                                          : dwarf::DW_AT_GNU_addr_base,
                   Label, TLOF.getDwarfAddrSection()->getBeginSymbol());
 }
+
+void DwarfCompileUnit::addBaseTypeRef(DIEValueList &Die, int64_t Idx) {
+  Die.addValue(DIEValueAllocator, (dwarf::Attribute)0, dwarf::DW_FORM_udata,
+               new (DIEValueAllocator) DIEBaseTypeRef(this, Idx));
+}
+
+void DwarfCompileUnit::createBaseTypeDIEs() {
+  // Insert the base_type DIEs directly after the CU so that their offsets will
+  // fit in the fixed size ULEB128 used inside the location expressions.
+  // Maintain order by iterating backwards and inserting to the front of CU
+  // child list.
+  for (auto &Btr : reverse(ExprRefedBaseTypes)) {
+    DIE &Die = getUnitDie().addChildFront(
+      DIE::get(DIEValueAllocator, dwarf::DW_TAG_base_type));
+    Twine T(dwarf::AttributeEncodingString(Btr.Encoding) + "_" + Twine(Btr.BitSize));
+    SmallString<32> Str;
+    addString(Die, dwarf::DW_AT_name, T.toStringRef(Str));
+    addUInt(Die, dwarf::DW_AT_encoding, dwarf::DW_FORM_data1, Btr.Encoding);
+    addUInt(Die, dwarf::DW_AT_byte_size, None, Btr.BitSize / 8);
+
+    Btr.Die = &Die;
+  }
+}

Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h?rev=356442&r1=356441&r2=356442&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h Tue Mar 19 01:48:19 2019
@@ -124,6 +124,16 @@ public:
     const DIExpression *Expr;
   };
 
+  struct BaseTypeRef {
+    BaseTypeRef(unsigned BitSize, dwarf::TypeKind Encoding) :
+      BitSize(BitSize), Encoding(Encoding) {}
+    unsigned BitSize;
+    dwarf::TypeKind Encoding;
+    DIE *Die = nullptr;
+  };
+
+  std::vector<BaseTypeRef> ExprRefedBaseTypes;
+
   /// Get or create global variable DIE.
   DIE *
   getOrCreateGlobalVariableDIE(const DIGlobalVariable *GV,
@@ -199,6 +209,8 @@ public:
                               SmallVectorImpl<DIE *> &Children,
                               bool *HasNonScopeChildren = nullptr);
 
+  void createBaseTypeDIEs();
+
   /// Construct a DIE for this subprogram scope.
   DIE &constructSubprogramScopeDIE(const DISubprogram *Sub,
                                    LexicalScope *Scope);
@@ -313,6 +325,8 @@ public:
   void setDWOId(uint64_t DwoId) { DWOId = DwoId; }
 
   bool hasDwarfPubSections() const;
+
+  void addBaseTypeRef(DIEValueList &Die, int64_t Idx);
 };
 
 } // end namespace llvm

Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp?rev=356442&r1=356441&r2=356442&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp Tue Mar 19 01:48:19 2019
@@ -41,6 +41,8 @@
 #include "llvm/CodeGen/TargetInstrInfo.h"
 #include "llvm/CodeGen/TargetRegisterInfo.h"
 #include "llvm/CodeGen/TargetSubtargetInfo.h"
+#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
+#include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"
 #include "llvm/IR/Constants.h"
 #include "llvm/IR/DebugInfoMetadata.h"
 #include "llvm/IR/DebugLoc.h"
@@ -161,6 +163,7 @@ static const char *const DWARFGroupName
 static const char *const DWARFGroupDescription = "DWARF Emission";
 static const char *const DbgTimerName = "writer";
 static const char *const DbgTimerDescription = "DWARF Debug Writer";
+static constexpr unsigned ULEB128PadSize = 4;
 
 void DebugLocDwarfExpression::emitOp(uint8_t Op, const char *Comment) {
   BS.EmitInt8(
@@ -176,6 +179,11 @@ void DebugLocDwarfExpression::emitUnsign
   BS.EmitULEB128(Value, Twine(Value));
 }
 
+void DebugLocDwarfExpression::emitBaseTypeRef(uint64_t Idx) {
+  assert(Idx < (1ULL << (ULEB128PadSize * 7)) && "Idx wont fit");
+  BS.EmitULEB128(Idx, Twine(Idx), ULEB128PadSize);
+}
+
 bool DebugLocDwarfExpression::isFrameRegister(const TargetRegisterInfo &TRI,
                                               unsigned MachineReg) {
   // This information is not available while emitting .debug_loc entries.
@@ -940,6 +948,11 @@ void DwarfDebug::endModule() {
   assert(CurFn == nullptr);
   assert(CurMI == nullptr);
 
+  for (const auto &P : CUMap) {
+    auto &CU = *P.second;
+    CU.createBaseTypeDIEs();
+  }
+
   // If we aren't actually generating debug info (check beginModule -
   // conditionalized on !DisableDebugInfoPrinting and the presence of the
   // llvm.dbg.cu metadata node)
@@ -1369,7 +1382,7 @@ void DwarfDebug::collectEntityInfo(Dwarf
 
     // Finalize the entry by lowering it into a DWARF bytestream.
     for (auto &Entry : Entries)
-      Entry.finalize(*Asm, List, BT);
+      Entry.finalize(*Asm, List, BT, TheCU);
   }
 
   // For each InlinedEntity collected from DBG_LABEL instructions, convert to
@@ -1911,13 +1924,55 @@ void DwarfDebug::emitDebugStr() {
                      StringOffsetsSection, /* UseRelativeOffsets = */ true);
 }
 
-void DwarfDebug::emitDebugLocEntry(ByteStreamer &Streamer,
-                                   const DebugLocStream::Entry &Entry) {
+void DwarfDebug::emitDebugLocEntry(ByteStreamer &Streamer, const
+                                   DebugLocStream::Entry &Entry,
+                                   const DwarfCompileUnit *CU) {
   auto &&Comments = DebugLocs.getComments(Entry);
   auto Comment = Comments.begin();
   auto End = Comments.end();
-  for (uint8_t Byte : DebugLocs.getBytes(Entry))
-    Streamer.EmitInt8(Byte, Comment != End ? *(Comment++) : "");
+
+  // The expressions are inserted into a byte stream rather early (see
+  // DwarfExpression::addExpression) so for those ops (e.g. DW_OP_convert) that
+  // need to reference a base_type DIE the offset of that DIE is not yet known.
+  // To deal with this we instead insert a placeholder early and then extract
+  // it here and replace it with the real reference.
+  unsigned PtrSize = Asm->MAI->getCodePointerSize();
+  DWARFDataExtractor Data(StringRef(DebugLocs.getBytes(Entry).data(),
+                                    DebugLocs.getBytes(Entry).size()),
+                          Asm->getDataLayout().isLittleEndian(), PtrSize);
+  DWARFExpression Expr(Data, getDwarfVersion(), PtrSize);
+
+  using Encoding = DWARFExpression::Operation::Encoding;
+  uint32_t Offset = 0;
+  for (auto &Op : Expr) {
+    assert(Op.getCode() != dwarf::DW_OP_const_type &&
+           "3 operand ops not yet supported");
+    Streamer.EmitInt8(Op.getCode(), Comment != End ? *(Comment++) : "");
+    Offset++;
+    for (unsigned I = 0; I < 2; ++I) {
+      if (Op.getDescription().Op[I] == Encoding::SizeNA)
+        continue;
+      if (Op.getDescription().Op[I] == Encoding::BaseTypeRef) {
+          if (CU) {
+            uint64_t Offset = CU->ExprRefedBaseTypes[Op.getRawOperand(I)].Die->getOffset();
+            assert(Offset < (1ULL << (ULEB128PadSize * 7)) && "Offset wont fit");
+            Asm->EmitULEB128(Offset, nullptr, ULEB128PadSize);
+          } else {
+            // Emit a reference to the 'generic type'.
+            Asm->EmitULEB128(0, nullptr, ULEB128PadSize);
+          }
+          // Make sure comments stay aligned.
+          for (unsigned J = 0; J < ULEB128PadSize; ++J)
+            if (Comment != End)
+              Comment++;
+      } else {
+        for (uint32_t J = Offset; J < Op.getOperandEndOffset(I); ++J)
+          Streamer.EmitInt8(Data.getData()[J], Comment != End ? *(Comment++) : "");
+      }
+      Offset = Op.getOperandEndOffset(I);
+    }
+    assert(Offset == Op.getEndOffset());
+  }
 }
 
 static void emitDebugLocValue(const AsmPrinter &AP, const DIBasicType *BT,
@@ -1951,11 +2006,12 @@ static void emitDebugLocValue(const AsmP
 
 void DebugLocEntry::finalize(const AsmPrinter &AP,
                              DebugLocStream::ListBuilder &List,
-                             const DIBasicType *BT) {
+                             const DIBasicType *BT,
+                             DwarfCompileUnit &TheCU) {
   assert(Begin != End && "unexpected location list entry with empty range");
   DebugLocStream::EntryBuilder Entry(List, Begin, End);
   BufferByteStreamer Streamer = Entry.getStreamer();
-  DebugLocDwarfExpression DwarfExpr(AP.getDwarfVersion(), Streamer);
+  DebugLocDwarfExpression DwarfExpr(AP.getDwarfVersion(), Streamer, TheCU);
   const DebugLocEntry::Value &Value = Values[0];
   if (Value.isFragment()) {
     // Emit all fragments that belong to the same variable and range.
@@ -1975,7 +2031,8 @@ void DebugLocEntry::finalize(const AsmPr
   DwarfExpr.finalize();
 }
 
-void DwarfDebug::emitDebugLocEntryLocation(const DebugLocStream::Entry &Entry) {
+void DwarfDebug::emitDebugLocEntryLocation(const DebugLocStream::Entry &Entry,
+                                           const DwarfCompileUnit *CU) {
   // Emit the size.
   Asm->OutStreamer->AddComment("Loc expr size");
   if (getDwarfVersion() >= 5)
@@ -1984,7 +2041,7 @@ void DwarfDebug::emitDebugLocEntryLocati
     Asm->emitInt16(DebugLocs.getBytes(Entry).size());
   // Emit the entry.
   APByteStreamer Streamer(*Asm);
-  emitDebugLocEntry(Streamer, Entry);
+  emitDebugLocEntry(Streamer, Entry, CU);
 }
 
 // Emit the common part of the DWARF 5 range/locations list tables header.
@@ -2084,7 +2141,7 @@ void DwarfDebug::emitDebugLoc() {
           Asm->EmitLabelDifference(Entry.EndSym, Base, Size);
         }
 
-        emitDebugLocEntryLocation(Entry);
+        emitDebugLocEntryLocation(Entry, CU);
         continue;
       }
 
@@ -2105,7 +2162,7 @@ void DwarfDebug::emitDebugLoc() {
         Asm->OutStreamer->EmitSymbolValue(Entry.EndSym, Size);
       }
 
-      emitDebugLocEntryLocation(Entry);
+      emitDebugLocEntryLocation(Entry, CU);
     }
 
     if (IsLocLists) {
@@ -2141,7 +2198,7 @@ void DwarfDebug::emitDebugLocDWO() {
       Asm->EmitULEB128(idx);
       Asm->EmitLabelDifference(Entry.EndSym, Entry.BeginSym, 4);
 
-      emitDebugLocEntryLocation(Entry);
+      emitDebugLocEntryLocation(Entry, List.CU);
     }
     Asm->emitInt8(dwarf::DW_LLE_end_of_list);
   }

Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h?rev=356442&r1=356441&r2=356442&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h Tue Mar 19 01:48:19 2019
@@ -682,10 +682,12 @@ public:
   /// Emit an entry for the debug loc section. This can be used to
   /// handle an entry that's going to be emitted into the debug loc section.
   void emitDebugLocEntry(ByteStreamer &Streamer,
-                         const DebugLocStream::Entry &Entry);
+                         const DebugLocStream::Entry &Entry,
+                         const DwarfCompileUnit *CU);
 
   /// Emit the location for a debug loc entry, including the size header.
-  void emitDebugLocEntryLocation(const DebugLocStream::Entry &Entry);
+  void emitDebugLocEntryLocation(const DebugLocStream::Entry &Entry,
+                                 const DwarfCompileUnit *CU);
 
   /// Find the MDNode for the given reference.
   template <typename T> T *resolve(TypedDINodeRef<T> Ref) const {

Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfExpression.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfExpression.cpp?rev=356442&r1=356441&r2=356442&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfExpression.cpp (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfExpression.cpp Tue Mar 19 01:48:19 2019
@@ -11,6 +11,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "DwarfExpression.h"
+#include "DwarfCompileUnit.h"
 #include "llvm/ADT/APInt.h"
 #include "llvm/ADT/SmallBitVector.h"
 #include "llvm/BinaryFormat/Dwarf.h"
@@ -318,6 +319,8 @@ void DwarfExpression::addExpression(DIEx
   if (SubRegisterSizeInBits && N && (N->getOp() != dwarf::DW_OP_LLVM_fragment))
     maskSubRegister();
 
+  Optional<DIExpression::ExprOperand> PrevConvertOp = None;
+
   while (ExprCursor) {
     auto Op = ExprCursor.take();
     switch (Op->getOp()) {
@@ -384,6 +387,42 @@ void DwarfExpression::addExpression(DIEx
       assert(LocationKind != Register);
       emitConstu(Op->getArg(0));
       break;
+    case dwarf::DW_OP_LLVM_convert: {
+      unsigned BitSize = Op->getArg(0);
+      dwarf::TypeKind Encoding = static_cast<dwarf::TypeKind>(Op->getArg(1));
+      if (DwarfVersion >= 5) {
+        emitOp(dwarf::DW_OP_convert);
+        // Reuse the base_type if we already have one in this CU otherwise we
+        // create a new one.
+        unsigned I = 0, E = CU.ExprRefedBaseTypes.size();
+        for (; I != E; ++I)
+          if (CU.ExprRefedBaseTypes[I].BitSize == BitSize &&
+              CU.ExprRefedBaseTypes[I].Encoding == Encoding)
+            break;
+
+        if (I == E)
+          CU.ExprRefedBaseTypes.emplace_back(BitSize, Encoding);
+
+        // If targeting a location-list; simply emit the index into the raw
+        // byte stream as ULEB128, DwarfDebug::emitDebugLocEntry has been
+        // fitted with means to extract it later.
+        // If targeting a inlined DW_AT_location; insert a DIEBaseTypeRef
+        // (containing the index and a resolve mechanism during emit) into the
+        // DIE value list.
+        emitBaseTypeRef(I);
+      } else {
+        if (PrevConvertOp && PrevConvertOp->getArg(0) < BitSize) {
+          if (Encoding == dwarf::DW_ATE_signed)
+            emitLegacySExt(PrevConvertOp->getArg(0));
+          else if (Encoding == dwarf::DW_ATE_unsigned)
+            emitLegacyZExt(PrevConvertOp->getArg(0));
+          PrevConvertOp = None;
+        } else {
+          PrevConvertOp = Op;
+        }
+      }
+      break;
+    }
     case dwarf::DW_OP_stack_value:
       LocationKind = Implicit;
       break;
@@ -436,3 +475,25 @@ void DwarfExpression::addFragmentOffset(
     addOpPiece(FragmentOffset - OffsetInBits);
   OffsetInBits = FragmentOffset;
 }
+
+void DwarfExpression::emitLegacySExt(unsigned FromBits) {
+  // (((X >> (FromBits - 1)) * (~0)) << FromBits) | X
+  emitOp(dwarf::DW_OP_dup);
+  emitOp(dwarf::DW_OP_constu);
+  emitUnsigned(FromBits - 1);
+  emitOp(dwarf::DW_OP_shr);
+  emitOp(dwarf::DW_OP_lit0);
+  emitOp(dwarf::DW_OP_not);
+  emitOp(dwarf::DW_OP_mul);
+  emitOp(dwarf::DW_OP_constu);
+  emitUnsigned(FromBits);
+  emitOp(dwarf::DW_OP_shl);
+  emitOp(dwarf::DW_OP_or);
+}
+
+void DwarfExpression::emitLegacyZExt(unsigned FromBits) {
+  // (X & (1 << FromBits - 1))
+  emitOp(dwarf::DW_OP_constu);
+  emitUnsigned((1ULL << FromBits) - 1);
+  emitOp(dwarf::DW_OP_and);
+}

Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfExpression.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfExpression.h?rev=356442&r1=356441&r2=356442&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfExpression.h (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfExpression.h Tue Mar 19 01:48:19 2019
@@ -27,7 +27,7 @@ namespace llvm {
 class AsmPrinter;
 class APInt;
 class ByteStreamer;
-class DwarfUnit;
+class DwarfCompileUnit;
 class DIELoc;
 class TargetRegisterInfo;
 
@@ -104,6 +104,8 @@ protected:
     const char *Comment;
   };
 
+  DwarfCompileUnit &CU;
+
   /// The register location, if any.
   SmallVector<Register, 2> DwarfRegs;
 
@@ -137,6 +139,8 @@ protected:
   /// Emit a raw unsigned value.
   virtual void emitUnsigned(uint64_t Value) = 0;
 
+  virtual void emitBaseTypeRef(uint64_t Idx) = 0;
+
   /// Emit a normalized unsigned constant.
   void emitConstu(uint64_t Value);
 
@@ -199,7 +203,8 @@ protected:
   ~DwarfExpression() = default;
 
 public:
-  DwarfExpression(unsigned DwarfVersion) : DwarfVersion(DwarfVersion) {}
+  DwarfExpression(unsigned DwarfVersion, DwarfCompileUnit &CU)
+    : CU(CU), DwarfVersion(DwarfVersion) {}
 
   /// This needs to be called last to commit any pending changes.
   void finalize();
@@ -247,6 +252,9 @@ public:
   /// If applicable, emit an empty DW_OP_piece / DW_OP_bit_piece to advance to
   /// the fragment described by \c Expr.
   void addFragmentOffset(const DIExpression *Expr);
+
+  void emitLegacySExt(unsigned FromBits);
+  void emitLegacyZExt(unsigned FromBits);
 };
 
 /// DwarfExpression implementation for .debug_loc entries.
@@ -256,27 +264,28 @@ class DebugLocDwarfExpression final : pu
   void emitOp(uint8_t Op, const char *Comment = nullptr) override;
   void emitSigned(int64_t Value) override;
   void emitUnsigned(uint64_t Value) override;
+  void emitBaseTypeRef(uint64_t Idx) override;
   bool isFrameRegister(const TargetRegisterInfo &TRI,
                        unsigned MachineReg) override;
 
 public:
-  DebugLocDwarfExpression(unsigned DwarfVersion, ByteStreamer &BS)
-      : DwarfExpression(DwarfVersion), BS(BS) {}
+  DebugLocDwarfExpression(unsigned DwarfVersion, ByteStreamer &BS, DwarfCompileUnit &CU)
+      : DwarfExpression(DwarfVersion, CU), BS(BS) {}
 };
 
 /// DwarfExpression implementation for singular DW_AT_location.
 class DIEDwarfExpression final : public DwarfExpression {
 const AsmPrinter &AP;
-  DwarfUnit &DU;
   DIELoc &DIE;
 
   void emitOp(uint8_t Op, const char *Comment = nullptr) override;
   void emitSigned(int64_t Value) override;
   void emitUnsigned(uint64_t Value) override;
+  void emitBaseTypeRef(uint64_t Idx) override;
   bool isFrameRegister(const TargetRegisterInfo &TRI,
                        unsigned MachineReg) override;
 public:
-  DIEDwarfExpression(const AsmPrinter &AP, DwarfUnit &DU, DIELoc &DIE);
+  DIEDwarfExpression(const AsmPrinter &AP, DwarfCompileUnit &CU, DIELoc &DIE);
 
   DIELoc *finalize() {
     DwarfExpression::finalize();

Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfFile.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfFile.h?rev=356442&r1=356441&r2=356442&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfFile.h (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfFile.h Tue Mar 19 01:48:19 2019
@@ -147,7 +147,7 @@ public:
   void emitUnits(bool UseOffsets);
 
   /// Emit the given unit to its section.
-  void emitUnit(DwarfUnit *U, bool UseOffsets);
+  void emitUnit(DwarfUnit *TheU, bool UseOffsets);
 
   /// Emit a set of abbreviations to the specific section.
   void emitAbbrevs(MCSection *);

Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfUnit.cpp?rev=356442&r1=356441&r2=356442&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfUnit.cpp (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfUnit.cpp Tue Mar 19 01:48:19 2019
@@ -46,21 +46,26 @@ using namespace llvm;
 
 #define DEBUG_TYPE "dwarfdebug"
 
-DIEDwarfExpression::DIEDwarfExpression(const AsmPrinter &AP, DwarfUnit &DU,
+DIEDwarfExpression::DIEDwarfExpression(const AsmPrinter &AP,
+                                       DwarfCompileUnit &CU,
                                        DIELoc &DIE)
-    : DwarfExpression(AP.getDwarfVersion()), AP(AP), DU(DU),
+    : DwarfExpression(AP.getDwarfVersion(), CU), AP(AP),
       DIE(DIE) {}
 
 void DIEDwarfExpression::emitOp(uint8_t Op, const char* Comment) {
-  DU.addUInt(DIE, dwarf::DW_FORM_data1, Op);
+  CU.addUInt(DIE, dwarf::DW_FORM_data1, Op);
 }
 
 void DIEDwarfExpression::emitSigned(int64_t Value) {
-  DU.addSInt(DIE, dwarf::DW_FORM_sdata, Value);
+  CU.addSInt(DIE, dwarf::DW_FORM_sdata, Value);
 }
 
 void DIEDwarfExpression::emitUnsigned(uint64_t Value) {
-  DU.addUInt(DIE, dwarf::DW_FORM_udata, Value);
+  CU.addUInt(DIE, dwarf::DW_FORM_udata, Value);
+}
+
+void DIEDwarfExpression::emitBaseTypeRef(uint64_t Idx) {
+  CU.addBaseTypeRef(DIE, Idx);
 }
 
 bool DIEDwarfExpression::isFrameRegister(const TargetRegisterInfo &TRI,

Modified: llvm/trunk/lib/CodeGen/AsmPrinter/LLVMBuild.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/LLVMBuild.txt?rev=356442&r1=356441&r2=356442&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/LLVMBuild.txt (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/LLVMBuild.txt Tue Mar 19 01:48:19 2019
@@ -18,4 +18,4 @@
 type = Library
 name = AsmPrinter
 parent = Libraries
-required_libraries = Analysis BinaryFormat CodeGen Core DebugInfoCodeView DebugInfoMSF MC MCParser Support Target
+required_libraries = Analysis BinaryFormat CodeGen Core DebugInfoCodeView DebugInfoDWARF DebugInfoMSF MC MCParser Support Target

Modified: llvm/trunk/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp?rev=356442&r1=356441&r2=356442&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp (original)
+++ llvm/trunk/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp Tue Mar 19 01:48:19 2019
@@ -225,6 +225,7 @@ void DWARFDebugLoclists::LocationList::d
                                             bool IsLittleEndian,
                                             unsigned AddressSize,
                                             const MCRegisterInfo *MRI,
+                                            DWARFUnit *U,
                                             unsigned Indent) const {
   for (const Entry &E : Entries) {
     switch (E.Kind) {
@@ -254,7 +255,7 @@ void DWARFDebugLoclists::LocationList::d
       llvm_unreachable("unreachable locations list kind");
     }
 
-    dumpExpression(OS, E.Loc, IsLittleEndian, AddressSize, MRI, nullptr);
+    dumpExpression(OS, E.Loc, IsLittleEndian, AddressSize, MRI, U);
   }
 }
 
@@ -263,7 +264,7 @@ void DWARFDebugLoclists::dump(raw_ostrea
                               Optional<uint64_t> Offset) const {
   auto DumpLocationList = [&](const LocationList &L) {
     OS << format("0x%8.8x: ", L.Offset);
-    L.dump(OS, BaseAddr, IsLittleEndian, AddressSize, MRI, /*Indent=*/12);
+    L.dump(OS, BaseAddr, IsLittleEndian, AddressSize, MRI, nullptr, /*Indent=*/12);
     OS << "\n\n";
   };
 

Modified: llvm/trunk/lib/DebugInfo/DWARF/DWARFDie.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARF/DWARFDie.cpp?rev=356442&r1=356441&r2=356442&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/DWARF/DWARFDie.cpp (original)
+++ llvm/trunk/lib/DebugInfo/DWARF/DWARFDie.cpp Tue Mar 19 01:48:19 2019
@@ -130,7 +130,7 @@ static void dumpLocation(raw_ostream &OS
 
       if (LL)
         LL->dump(OS, BaseAddr, Ctx.isLittleEndian(), Obj.getAddressSize(), MRI,
-                 Indent);
+                 U, Indent);
       else
         OS << "error extracting location list.";
     }

Modified: llvm/trunk/lib/DebugInfo/DWARF/DWARFExpression.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARF/DWARFExpression.cpp?rev=356442&r1=356441&r2=356442&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/DWARF/DWARFExpression.cpp (original)
+++ llvm/trunk/lib/DebugInfo/DWARF/DWARFExpression.cpp Tue Mar 19 01:48:19 2019
@@ -188,6 +188,8 @@ bool DWARFExpression::Operation::extract
     default:
       llvm_unreachable("Unknown DWARFExpression Op size");
     }
+
+    OperandEndOffsets[Operand] = Offset;
   }
 
   EndOffset = Offset;

Modified: llvm/trunk/lib/IR/AsmWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/AsmWriter.cpp?rev=356442&r1=356441&r2=356442&view=diff
==============================================================================
--- llvm/trunk/lib/IR/AsmWriter.cpp (original)
+++ llvm/trunk/lib/IR/AsmWriter.cpp Tue Mar 19 01:48:19 2019
@@ -2123,8 +2123,13 @@ static void writeDIExpression(raw_ostrea
       assert(!OpStr.empty() && "Expected valid opcode");
 
       Out << FS << OpStr;
-      for (unsigned A = 0, AE = I->getNumArgs(); A != AE; ++A)
-        Out << FS << I->getArg(A);
+      if (I->getOp() == dwarf::DW_OP_LLVM_convert) {
+        Out << FS << I->getArg(0);
+        Out << FS << dwarf::AttributeEncodingString(I->getArg(1));
+      } else {
+        for (unsigned A = 0, AE = I->getNumArgs(); A != AE; ++A)
+          Out << FS << I->getArg(A);
+      }
     }
   } else {
     for (const auto &I : N->getElements())

Modified: llvm/trunk/lib/IR/DebugInfoMetadata.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/DebugInfoMetadata.cpp?rev=356442&r1=356441&r2=356442&view=diff
==============================================================================
--- llvm/trunk/lib/IR/DebugInfoMetadata.cpp (original)
+++ llvm/trunk/lib/IR/DebugInfoMetadata.cpp Tue Mar 19 01:48:19 2019
@@ -813,6 +813,7 @@ DIExpression *DIExpression::getImpl(LLVM
 
 unsigned DIExpression::ExprOperand::getSize() const {
   switch (getOp()) {
+  case dwarf::DW_OP_LLVM_convert:
   case dwarf::DW_OP_LLVM_fragment:
     return 3;
   case dwarf::DW_OP_constu:
@@ -857,6 +858,7 @@ bool DIExpression::isValid() const {
         return false;
       break;
     }
+    case dwarf::DW_OP_LLVM_convert:
     case dwarf::DW_OP_constu:
     case dwarf::DW_OP_plus_uconst:
     case dwarf::DW_OP_plus:

Modified: llvm/trunk/lib/MC/MCStreamer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCStreamer.cpp?rev=356442&r1=356441&r2=356442&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCStreamer.cpp (original)
+++ llvm/trunk/lib/MC/MCStreamer.cpp Tue Mar 19 01:48:19 2019
@@ -135,10 +135,10 @@ void MCStreamer::EmitIntValue(uint64_t V
 
 /// EmitULEB128IntValue - Special case of EmitULEB128Value that avoids the
 /// client having to pass in a MCExpr for constant integers.
-void MCStreamer::EmitULEB128IntValue(uint64_t Value) {
+void MCStreamer::EmitULEB128IntValue(uint64_t Value, unsigned PadTo) {
   SmallString<128> Tmp;
   raw_svector_ostream OSE(Tmp);
-  encodeULEB128(Value, OSE);
+  encodeULEB128(Value, OSE, PadTo);
   EmitBytes(OSE.str());
 }
 

Modified: llvm/trunk/lib/Transforms/Utils/Local.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/Local.cpp?rev=356442&r1=356441&r2=356442&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Utils/Local.cpp (original)
+++ llvm/trunk/lib/Transforms/Utils/Local.cpp Tue Mar 19 01:48:19 2019
@@ -1861,21 +1861,10 @@ bool llvm::replaceAllDbgUsesWith(Instruc
         return None;
 
       bool Signed = *Signedness == DIBasicType::Signedness::Signed;
-
-      if (!Signed) {
-        // In the unsigned case, assume that a debugger will initialize the
-        // high bits to 0 and do a no-op conversion.
-        return Identity(DII);
-      } else {
-        // In the signed case, the high bits are given by sign extension, i.e:
-        //   (To >> (ToBits - 1)) * ((2 ^ FromBits) - 1)
-        // Calculate the high bits and OR them together with the low bits.
-        SmallVector<uint64_t, 8> Ops({dwarf::DW_OP_dup, dwarf::DW_OP_constu,
-                                      (ToBits - 1), dwarf::DW_OP_shr,
-                                      dwarf::DW_OP_lit0, dwarf::DW_OP_not,
-                                      dwarf::DW_OP_mul, dwarf::DW_OP_or});
-        return DIExpression::appendToStack(DII.getExpression(), Ops);
-      }
+      dwarf::TypeKind TK = Signed ? dwarf::DW_ATE_signed : dwarf::DW_ATE_unsigned;
+      SmallVector<uint64_t, 8> Ops({dwarf::DW_OP_LLVM_convert, ToBits, TK,
+                                   dwarf::DW_OP_LLVM_convert, FromBits, TK});
+      return DIExpression::appendToStack(DII.getExpression(), Ops);
     };
     return rewriteDebugUsers(From, To, DomPoint, DT, SignOrZeroExt);
   }

Modified: llvm/trunk/test/Assembler/diexpression.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Assembler/diexpression.ll?rev=356442&r1=356441&r2=356442&view=diff
==============================================================================
--- llvm/trunk/test/Assembler/diexpression.ll (original)
+++ llvm/trunk/test/Assembler/diexpression.ll Tue Mar 19 01:48:19 2019
@@ -8,9 +8,10 @@
 ; CHECK-SAME: !DIExpression(DW_OP_LLVM_fragment, 3, 7),
 ; CHECK-SAME: !DIExpression(DW_OP_deref, DW_OP_plus_uconst, 3, DW_OP_LLVM_fragment, 3, 7),
 ; CHECK-SAME: !DIExpression(DW_OP_constu, 2, DW_OP_swap, DW_OP_xderef),
-; CHECK-SAME: !DIExpression(DW_OP_plus_uconst, 3)}
+; CHECK-SAME: !DIExpression(DW_OP_plus_uconst, 3)
+; CHECK-SAME: !DIExpression(DW_OP_LLVM_convert, 16, DW_ATE_unsigned, DW_OP_LLVM_convert, 32, DW_ATE_signed)}
 
-!named = !{!0, !1, !2, !3, !4, !5, !6}
+!named = !{!0, !1, !2, !3, !4, !5, !6, !7}
 
 !0 = !DIExpression()
 !1 = !DIExpression(DW_OP_deref)
@@ -19,3 +20,4 @@
 !4 = !DIExpression(DW_OP_deref, DW_OP_plus_uconst, 3, DW_OP_LLVM_fragment, 3, 7)
 !5 = !DIExpression(DW_OP_constu, 2, DW_OP_swap, DW_OP_xderef)
 !6 = !DIExpression(DW_OP_plus_uconst, 3)
+!7 = !DIExpression(DW_OP_LLVM_convert, 16, DW_ATE_unsigned, DW_OP_LLVM_convert, 32, DW_ATE_signed)

Added: llvm/trunk/test/DebugInfo/Generic/convert-debugloc.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/Generic/convert-debugloc.ll?rev=356442&view=auto
==============================================================================
--- llvm/trunk/test/DebugInfo/Generic/convert-debugloc.ll (added)
+++ llvm/trunk/test/DebugInfo/Generic/convert-debugloc.ll Tue Mar 19 01:48:19 2019
@@ -0,0 +1,164 @@
+; RUN: llc -dwarf-version=5 -filetype=obj -O0 < %s | llvm-dwarfdump - | FileCheck %s --match-full-lines --check-prefix=DW5-CHECK
+; RUN: llc -dwarf-version=4 -filetype=obj -O0 < %s | llvm-dwarfdump - | FileCheck %s --match-full-lines --check-prefix=DW4-CHECK
+
+; DW5-CHECK: .debug_info contents:
+; DW5-CHECK-NEXT: 0x00000000: Compile Unit: length = 0x0000005c version = 0x0005 unit_type = DW_UT_compile abbr_offset = 0x0000 addr_size = 0x08 (next unit at 0x00000060)
+; DW5-CHECK-EMPTY:
+; DW5-CHECK-NEXT: 0x0000000c: DW_TAG_compile_unit
+; DW5-CHECK-NEXT:               DW_AT_producer	("clang version 9.0.0 (trunk 353791) (llvm/trunk 353801)")
+; DW5-CHECK-NEXT:               DW_AT_language	(DW_LANG_C99)
+; DW5-CHECK-NEXT:               DW_AT_name	("dbg.c")
+; DW5-CHECK-NEXT:               DW_AT_str_offsets_base	(0x00000008)
+; DW5-CHECK-NEXT:               DW_AT_stmt_list	(0x00000000)
+; DW5-CHECK-NEXT:               DW_AT_comp_dir	("/tmp")
+; DW5-CHECK-NEXT:               DW_AT_addr_base	(0x00000008)
+; DW5-CHECK-NEXT:               DW_AT_low_pc	(0x0000000000000000)
+; DW5-CHECK-NEXT:               DW_AT_high_pc	(0x0000000000000007)
+; DW5-CHECK-NEXT:               DW_AT_loclists_base	(0x0000000c)
+; DW5-CHECK-EMPTY:
+; DW5-CHECK-NEXT: 0x00000027:   DW_TAG_base_type
+; DW5-CHECK-NEXT:                 DW_AT_name	("DW_ATE_signed_8")
+; DW5-CHECK-NEXT:                 DW_AT_encoding	(DW_ATE_signed)
+; DW5-CHECK-NEXT:                 DW_AT_byte_size	(0x01)
+; DW5-CHECK-EMPTY:
+; DW5-CHECK-NEXT: 0x0000002b:   DW_TAG_base_type
+; DW5-CHECK-NEXT:                 DW_AT_name	("DW_ATE_signed_32")
+; DW5-CHECK-NEXT:                 DW_AT_encoding	(DW_ATE_signed)
+; DW5-CHECK-NEXT:                 DW_AT_byte_size	(0x04)
+; DW5-CHECK-EMPTY:
+; DW5-CHECK-NEXT: 0x0000002f:   DW_TAG_subprogram
+; DW5-CHECK-NEXT:                 DW_AT_low_pc	(0x0000000000000000)
+; DW5-CHECK-NEXT:                 DW_AT_high_pc	(0x0000000000000007)
+; DW5-CHECK-NEXT:                 DW_AT_frame_base	(DW_OP_reg7 RSP)
+; DW5-CHECK-NEXT:                 DW_AT_name	("foo")
+; DW5-CHECK-NEXT:                 DW_AT_decl_file	("/tmp/dbg.c")
+; DW5-CHECK-NEXT:                 DW_AT_decl_line	(1)
+; DW5-CHECK-NEXT:                 DW_AT_prototyped	(true)
+; DW5-CHECK-NEXT:                 DW_AT_type	(0x00000057 "signed char")
+; DW5-CHECK-NEXT:                 DW_AT_external	(true)
+; DW5-CHECK-EMPTY:
+; DW5-CHECK-NEXT: 0x0000003e:     DW_TAG_formal_parameter
+; DW5-CHECK-NEXT:                   DW_AT_location	(0x0000000c
+; DW5-CHECK-NEXT:                      [0x0000000000000003, 0x0000000000000006): DW_OP_reg0 RAX)
+; DW5-CHECK-NEXT:                   DW_AT_name	("x")
+; DW5-CHECK-NEXT:                   DW_AT_decl_file	("/tmp/dbg.c")
+; DW5-CHECK-NEXT:                   DW_AT_decl_line	(1)
+; DW5-CHECK-NEXT:                   DW_AT_type	(0x00000057 "signed char")
+; DW5-CHECK-EMPTY:
+; DW5-CHECK-NEXT: 0x0000004a:     DW_TAG_variable
+; DW5-CHECK-NEXT:                   DW_AT_location	(0x00000012
+; DW5-CHECK-NEXT:                      [0x0000000000000003, 0x0000000000000006): DW_OP_breg0 RAX+0, DW_OP_constu 0xff, DW_OP_and, DW_OP_convert (0x00000027) "DW_ATE_signed_8", DW_OP_convert (0x0000002b) "DW_ATE_signed_32", DW_OP_stack_value)
+; DW5-CHECK-NEXT:                   DW_AT_name	("y")
+; DW5-CHECK-NEXT:                   DW_AT_decl_file	("/tmp/dbg.c")
+; DW5-CHECK-NEXT:                   DW_AT_decl_line	(3)
+; DW5-CHECK-NEXT:                   DW_AT_type	(0x0000005b "int")
+; DW5-CHECK-EMPTY:
+; DW5-CHECK-NEXT: 0x00000056:     NULL
+; DW5-CHECK-EMPTY:
+; DW5-CHECK-NEXT: 0x00000057:   DW_TAG_base_type
+; DW5-CHECK-NEXT:                 DW_AT_name	("signed char")
+; DW5-CHECK-NEXT:                 DW_AT_encoding	(DW_ATE_signed_char)
+; DW5-CHECK-NEXT:                 DW_AT_byte_size	(0x01)
+; DW5-CHECK-EMPTY:
+; DW5-CHECK-NEXT: 0x0000005b:   DW_TAG_base_type
+; DW5-CHECK-NEXT:                 DW_AT_name	("int")
+; DW5-CHECK-NEXT:                 DW_AT_encoding	(DW_ATE_signed)
+; DW5-CHECK-NEXT:                 DW_AT_byte_size	(0x04)
+; DW5-CHECK-EMPTY:
+; DW5-CHECK-NEXT: 0x0000005f:   NULL
+
+
+; DW4-CHECK: .debug_info contents:
+; DW4-CHECK-NEXT: 0x00000000: Compile Unit: length = 0x0000006d version = 0x0004 abbr_offset = 0x0000 addr_size = 0x08 (next unit at 0x00000071)
+; DW4-CHECK-EMPTY:
+; DW4-CHECK-NEXT: 0x0000000b: DW_TAG_compile_unit
+; DW4-CHECK-NEXT:               DW_AT_producer	("clang version 9.0.0 (trunk 353791) (llvm/trunk 353801)")
+; DW4-CHECK-NEXT:               DW_AT_language	(DW_LANG_C99)
+; DW4-CHECK-NEXT:               DW_AT_name	("dbg.c")
+; DW4-CHECK-NEXT:               DW_AT_stmt_list	(0x00000000)
+; DW4-CHECK-NEXT:               DW_AT_comp_dir	("/tmp")
+; DW4-CHECK-NEXT:               DW_AT_low_pc	(0x0000000000000000)
+; DW4-CHECK-NEXT:               DW_AT_high_pc	(0x0000000000000007)
+; DW4-CHECK-EMPTY:
+; DW4-CHECK-NEXT: 0x0000002a:   DW_TAG_subprogram
+; DW4-CHECK-NEXT:                 DW_AT_low_pc	(0x0000000000000000)
+; DW4-CHECK-NEXT:                 DW_AT_high_pc	(0x0000000000000007)
+; DW4-CHECK-NEXT:                 DW_AT_frame_base	(DW_OP_reg7 RSP)
+; DW4-CHECK-NEXT:                 DW_AT_name	("foo")
+; DW4-CHECK-NEXT:                 DW_AT_decl_file	("/tmp/dbg.c")
+; DW4-CHECK-NEXT:                 DW_AT_decl_line	(1)
+; DW4-CHECK-NEXT:                 DW_AT_prototyped	(true)
+; DW4-CHECK-NEXT:                 DW_AT_type	(0x00000062 "signed char")
+; DW4-CHECK-NEXT:                 DW_AT_external	(true)
+; DW4-CHECK-EMPTY:
+; DW4-CHECK-NEXT: 0x00000043:     DW_TAG_formal_parameter
+; DW4-CHECK-NEXT:                   DW_AT_location	(0x00000000
+; DW4-CHECK-NEXT:                      [0x0000000000000003,  0x0000000000000006): DW_OP_reg0 RAX)
+; DW4-CHECK-NEXT:                   DW_AT_name	("x")
+; DW4-CHECK-NEXT:                   DW_AT_decl_file	("/tmp/dbg.c")
+; DW4-CHECK-NEXT:                   DW_AT_decl_line	(1)
+; DW4-CHECK-NEXT:                   DW_AT_type	(0x00000062 "signed char")
+; DW4-CHECK-EMPTY:
+; DW4-CHECK-NEXT: 0x00000052:     DW_TAG_variable
+; DW4-CHECK-NEXT:                   DW_AT_location	(0x00000023
+; DW4-CHECK-NEXT:                      [0x0000000000000003,  0x0000000000000006): DW_OP_breg0 RAX+0, DW_OP_constu 0xff, DW_OP_and, DW_OP_dup, DW_OP_constu 0x7, DW_OP_shr, DW_OP_lit0, DW_OP_not, DW_OP_mul, DW_OP_constu 0x8, DW_OP_shl, DW_OP_or, DW_OP_stack_value)
+; DW4-CHECK-NEXT:                   DW_AT_name	("y")
+; DW4-CHECK-NEXT:                   DW_AT_decl_file	("/tmp/dbg.c")
+; DW4-CHECK-NEXT:                   DW_AT_decl_line	(3)
+; DW4-CHECK-NEXT:                   DW_AT_type	(0x00000069 "int")
+; DW4-CHECK-EMPTY:
+; DW4-CHECK-NEXT: 0x00000061:     NULL
+; DW4-CHECK-EMPTY:
+; DW4-CHECK-NEXT: 0x00000062:   DW_TAG_base_type
+; DW4-CHECK-NEXT:                 DW_AT_name	("signed char")
+; DW4-CHECK-NEXT:                 DW_AT_encoding	(DW_ATE_signed_char)
+; DW4-CHECK-NEXT:                 DW_AT_byte_size	(0x01)
+; DW4-CHECK-EMPTY:
+; DW4-CHECK-NEXT: 0x00000069:   DW_TAG_base_type
+; DW4-CHECK-NEXT:                 DW_AT_name	("int")
+; DW4-CHECK-NEXT:                 DW_AT_encoding	(DW_ATE_signed)
+; DW4-CHECK-NEXT:                 DW_AT_byte_size	(0x04)
+; DW4-CHECK-EMPTY:
+; DW4-CHECK-NEXT: 0x00000070:   NULL
+
+
+; ModuleID = 'dbg.ll'
+source_filename = "dbg.c"
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+; Function Attrs: noinline nounwind uwtable
+define dso_local signext i8 @foo(i8 signext %x) !dbg !7 {
+entry:
+  call void @llvm.dbg.value(metadata i8 %x, metadata !11, metadata !DIExpression()), !dbg !12
+  call void @llvm.dbg.value(metadata i8 %x, metadata !13, metadata !DIExpression(DW_OP_LLVM_convert, 8, DW_ATE_signed, DW_OP_LLVM_convert, 32, DW_ATE_signed, DW_OP_stack_value)), !dbg !15
+  ret i8 %x, !dbg !16
+}
+
+; Function Attrs: nounwind readnone speculatable
+declare void @llvm.dbg.declare(metadata, metadata, metadata)
+
+; Function Attrs: nounwind readnone speculatable
+declare void @llvm.dbg.value(metadata, metadata, metadata)
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!3, !4, !5}
+!llvm.ident = !{!6}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 9.0.0 (trunk 353791) (llvm/trunk 353801)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, nameTableKind: None)
+!1 = !DIFile(filename: "dbg.c", directory: "/tmp", checksumkind: CSK_MD5, checksum: "2a034da6937f5b9cf6dd2d89127f57fd")
+!2 = !{}
+!3 = !{i32 2, !"Dwarf Version", i32 5}
+!4 = !{i32 2, !"Debug Info Version", i32 3}
+!5 = !{i32 1, !"wchar_size", i32 4}
+!6 = !{!"clang version 9.0.0 (trunk 353791) (llvm/trunk 353801)"}
+!7 = distinct !DISubprogram(name: "foo", scope: !1, file: !1, line: 1, type: !8, scopeLine: 2, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !2)
+!8 = !DISubroutineType(types: !9)
+!9 = !{!10, !10}
+!10 = !DIBasicType(name: "signed char", size: 8, encoding: DW_ATE_signed_char)
+!11 = !DILocalVariable(name: "x", arg: 1, scope: !7, file: !1, line: 1, type: !10)
+!12 = !DILocation(line: 1, column: 29, scope: !7)
+!13 = !DILocalVariable(name: "y", scope: !7, file: !1, line: 3, type: !14)
+!14 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+!15 = !DILocation(line: 3, column: 14, scope: !7)
+!16 = !DILocation(line: 4, column: 3, scope: !7)

Added: llvm/trunk/test/DebugInfo/Generic/convert-inlined.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/Generic/convert-inlined.ll?rev=356442&view=auto
==============================================================================
--- llvm/trunk/test/DebugInfo/Generic/convert-inlined.ll (added)
+++ llvm/trunk/test/DebugInfo/Generic/convert-inlined.ll Tue Mar 19 01:48:19 2019
@@ -0,0 +1,87 @@
+; RUN: llc -dwarf-version=5 -filetype=obj -O0 < %s | llvm-dwarfdump - | FileCheck %s --match-full-lines --check-prefix=DW5-CHECK
+; RUN: llc -dwarf-version=4 -filetype=obj -O0 < %s | llvm-dwarfdump - | FileCheck %s --match-full-lines --check-prefix=DW4-CHECK
+
+; DW5-CHECK: .debug_info contents:
+; DW5-CHECK-NEXT: 0x00000000: Compile Unit: length = 0x0000003e version = 0x0005 unit_type = DW_UT_compile abbr_offset = 0x0000 addr_size = 0x08 (next unit at 0x00000042)
+; DW5-CHECK-EMPTY:
+; DW5-CHECK-NEXT: 0x0000000c: DW_TAG_compile_unit
+; DW5-CHECK-NEXT:               DW_AT_producer	("clang version 9.0.0 (trunk 353791) (llvm/trunk 353801)")
+; DW5-CHECK-NEXT:               DW_AT_language	(DW_LANG_C99)
+; DW5-CHECK-NEXT:               DW_AT_name	("dbg.c")
+; DW5-CHECK-NEXT:               DW_AT_str_offsets_base	(0x00000008)
+; DW5-CHECK-NEXT:               DW_AT_stmt_list	(0x00000000)
+; DW5-CHECK-NEXT:               DW_AT_comp_dir	("/tmp")
+; DW5-CHECK-NEXT:               DW_AT_addr_base	(0x00000008)
+; DW5-CHECK-EMPTY:
+; DW5-CHECK-NEXT: 0x0000001e:   DW_TAG_base_type
+; DW5-CHECK-NEXT:                 DW_AT_name	("DW_ATE_signed_8")
+; DW5-CHECK-NEXT:                 DW_AT_encoding	(DW_ATE_signed)
+; DW5-CHECK-NEXT:                 DW_AT_byte_size	(0x01)
+; DW5-CHECK-EMPTY:
+; DW5-CHECK-NEXT: 0x00000022:   DW_TAG_base_type
+; DW5-CHECK-NEXT:                 DW_AT_name	("DW_ATE_signed_32")
+; DW5-CHECK-NEXT:                 DW_AT_encoding	(DW_ATE_signed)
+; DW5-CHECK-NEXT:                 DW_AT_byte_size	(0x04)
+; DW5-CHECK-EMPTY:
+; DW5-CHECK-NEXT: 0x00000026:   DW_TAG_variable
+; DW5-CHECK-NEXT:                 DW_AT_name	("global")
+; DW5-CHECK-NEXT:                 DW_AT_type	(0x0000003d "int")
+; DW5-CHECK-NEXT:                 DW_AT_external	(true)
+; DW5-CHECK-NEXT:                 DW_AT_decl_file	("/tmp/dbg.c")
+; DW5-CHECK-NEXT:                 DW_AT_decl_line	(1)
+; DW5-CHECK-NEXT:                 DW_AT_location	(DW_OP_addrx 0x0, DW_OP_deref, DW_OP_convert (0x0000001e) "DW_ATE_signed_8", DW_OP_convert (0x00000022) "DW_ATE_signed_32", DW_OP_stack_value)
+; DW5-CHECK-EMPTY:
+; DW5-CHECK-NEXT: 0x0000003d:   DW_TAG_base_type
+; DW5-CHECK-NEXT:                 DW_AT_name	("int")
+; DW5-CHECK-NEXT:                 DW_AT_encoding	(DW_ATE_signed)
+; DW5-CHECK-NEXT:                 DW_AT_byte_size	(0x04)
+; DW5-CHECK-EMPTY:
+; DW5-CHECK-NEXT: 0x00000041:   NULL
+
+
+; DW4-CHECK: .debug_info contents:
+; DW4-CHECK-NEXT: 0x00000000: Compile Unit: length = 0x00000044 version = 0x0004 abbr_offset = 0x0000 addr_size = 0x08 (next unit at 0x00000048)
+; DW4-CHECK-EMPTY:
+; DW4-CHECK-NEXT: 0x0000000b: DW_TAG_compile_unit
+; DW4-CHECK-NEXT:               DW_AT_producer	("clang version 9.0.0 (trunk 353791) (llvm/trunk 353801)")
+; DW4-CHECK-NEXT:               DW_AT_language	(DW_LANG_C99)
+; DW4-CHECK-NEXT:               DW_AT_name	("dbg.c")
+; DW4-CHECK-NEXT:               DW_AT_stmt_list	(0x00000000)
+; DW4-CHECK-NEXT:               DW_AT_comp_dir	("/tmp")
+; DW4-CHECK-EMPTY:
+; DW4-CHECK-NEXT: 0x0000001e:   DW_TAG_variable
+; DW4-CHECK-NEXT:                 DW_AT_name	("global")
+; DW4-CHECK-NEXT:                 DW_AT_type	(0x00000040 "int")
+; DW4-CHECK-NEXT:                 DW_AT_external	(true)
+; DW4-CHECK-NEXT:                 DW_AT_decl_file	("/tmp/dbg.c")
+; DW4-CHECK-NEXT:                 DW_AT_decl_line	(1)
+; DW4-CHECK-NEXT:                 DW_AT_location	(DW_OP_addr 0x0, DW_OP_deref, DW_OP_dup, DW_OP_constu 0x7, DW_OP_shr, DW_OP_lit0, DW_OP_not, DW_OP_mul, DW_OP_constu 0x8, DW_OP_shl, DW_OP_or, DW_OP_stack_value)
+; DW4-CHECK-EMPTY:
+; DW4-CHECK-NEXT: 0x00000040:   DW_TAG_base_type
+; DW4-CHECK-NEXT:                 DW_AT_name	("int")
+; DW4-CHECK-NEXT:                 DW_AT_encoding	(DW_ATE_signed)
+; DW4-CHECK-NEXT:                 DW_AT_byte_size	(0x04)
+; DW4-CHECK-EMPTY:
+; DW4-CHECK-NEXT: 0x00000047:   NULL
+
+source_filename = "dbg.c"
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+ at global = dso_local global i32 255, align 4, !dbg !0
+
+!llvm.dbg.cu = !{!2}
+!llvm.module.flags = !{!7, !8, !9}
+!llvm.ident = !{!10}
+
+!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression(DW_OP_deref, DW_OP_LLVM_convert, 8, DW_ATE_signed, DW_OP_LLVM_convert, 32, DW_ATE_signed, DW_OP_stack_value))
+!1 = distinct !DIGlobalVariable(name: "global", scope: !2, file: !3, line: 1, type: !6, isLocal: false, isDefinition: true)
+!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 9.0.0 (trunk 353791) (llvm/trunk 353801)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5, nameTableKind: None)
+!3 = !DIFile(filename: "dbg.c", directory: "/tmp", checksumkind: CSK_MD5, checksum: "7c731722dd7304ccb8e366ae80269b82")
+!4 = !{}
+!5 = !{!0}
+!6 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+!7 = !{i32 2, !"Dwarf Version", i32 5}
+!8 = !{i32 2, !"Debug Info Version", i32 3}
+!9 = !{i32 1, !"wchar_size", i32 4}
+!10 = !{!"clang version 9.0.0 (trunk 353791) (llvm/trunk 353801)"}

Added: llvm/trunk/test/DebugInfo/Generic/convert-linked.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/Generic/convert-linked.ll?rev=356442&view=auto
==============================================================================
--- llvm/trunk/test/DebugInfo/Generic/convert-linked.ll (added)
+++ llvm/trunk/test/DebugInfo/Generic/convert-linked.ll Tue Mar 19 01:48:19 2019
@@ -0,0 +1,72 @@
+; RUN: llc -filetype=obj -O0 < %s | llvm-dwarfdump - | FileCheck %s
+
+; CHECK: DW_TAG_compile_unit
+; CHECK: [[CU0BT0:0x[0-9a-f]+]]: DW_TAG_base_type
+; CHECK-NEXT: DW_ATE_signed_8
+; CHECK: [[CU0BT1:0x[0-9a-f]+]]: DW_TAG_base_type
+; CHECK-NEXT: DW_ATE_signed_32
+; CHECK: DW_TAG_variable
+; CHECK: DW_OP_convert ([[CU0BT0]]) "DW_ATE_signed_8", DW_OP_convert ([[CU0BT1]]) "DW_ATE_signed_32"
+
+; CHECK: DW_TAG_compile_unit
+; CHECK: [[CU1BT0:0x[0-9a-f]+]]: DW_TAG_base_type
+; CHECK-NEXT: DW_ATE_signed_8
+; CHECK: [[CU1BT1:0x[0-9a-f]+]]: DW_TAG_base_type
+; CHECK-NEXT: DW_ATE_signed_16
+; CHECK: DW_TAG_variable
+; CHECK: DW_OP_convert ([[CU1BT0]]) "DW_ATE_signed_8", DW_OP_convert ([[CU1BT1]]) "DW_ATE_signed_16"
+
+; ModuleID = 'llvm-link'
+source_filename = "llvm-link"
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+define dso_local signext i8 @foo(i8 signext %x) !dbg !9 {
+entry:
+  call void @llvm.dbg.value(metadata i8 %x, metadata !13, metadata !DIExpression()), !dbg !14
+  call void @llvm.dbg.value(metadata i8 %x, metadata !15, metadata !DIExpression(DW_OP_LLVM_convert, 8, DW_ATE_signed, DW_OP_LLVM_convert, 32, DW_ATE_signed, DW_OP_stack_value)), !dbg !17
+  ret i8 %x, !dbg !18
+}
+
+define dso_local signext i8 @bar(i8 signext %x) !dbg !19 {
+entry:
+  call void @llvm.dbg.value(metadata i8 %x, metadata !20, metadata !DIExpression()), !dbg !21
+  call void @llvm.dbg.value(metadata i8 %x, metadata !22, metadata !DIExpression(DW_OP_LLVM_convert, 8, DW_ATE_signed, DW_OP_LLVM_convert, 16, DW_ATE_signed, DW_OP_stack_value)), !dbg !24
+  ret i8 %x, !dbg !25
+}
+
+; Function Attrs: nounwind readnone speculatable
+declare void @llvm.dbg.value(metadata, metadata, metadata) #1
+
+attributes #1 = { nounwind readnone speculatable }
+
+!llvm.dbg.cu = !{!0, !3}
+!llvm.ident = !{!5, !5}
+!llvm.module.flags = !{!6, !7, !8}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 9.0.0 ", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, nameTableKind: None)
+!1 = !DIFile(filename: "dbg-foo.c", directory: "/tmp", checksumkind: CSK_MD5, checksum: "b35f80a032deb2a30bc187d564b5a775")
+!2 = !{}
+!3 = distinct !DICompileUnit(language: DW_LANG_C99, file: !4, producer: "clang version 9.0.0 ", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, nameTableKind: None)
+!4 = !DIFile(filename: "dbg-bar.c", directory: "/tmp", checksumkind: CSK_MD5, checksum: "9836bb594260d883960455e7d8bc51ea")
+!5 = !{!"clang version 9.0.0 "}
+!6 = !{i32 2, !"Dwarf Version", i32 5}
+!7 = !{i32 2, !"Debug Info Version", i32 3}
+!8 = !{i32 1, !"wchar_size", i32 4}
+!9 = distinct !DISubprogram(name: "foo", scope: !1, file: !1, line: 7, type: !10, scopeLine: 8, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !2)
+!10 = !DISubroutineType(types: !11)
+!11 = !{!12, !12}
+!12 = !DIBasicType(name: "signed char", size: 8, encoding: DW_ATE_signed_char)
+!13 = !DILocalVariable(name: "x", arg: 1, scope: !9, file: !1, line: 7, type: !12)
+!14 = !DILocation(line: 7, column: 29, scope: !9)
+!15 = !DILocalVariable(name: "y", scope: !9, file: !1, line: 9, type: !16)
+!16 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+!17 = !DILocation(line: 9, column: 14, scope: !9)
+!18 = !DILocation(line: 10, column: 3, scope: !9)
+!19 = distinct !DISubprogram(name: "bar", scope: !4, file: !4, line: 1, type: !10, scopeLine: 2, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !3, retainedNodes: !2)
+!20 = !DILocalVariable(name: "x", arg: 1, scope: !19, file: !4, line: 1, type: !12)
+!21 = !DILocation(line: 1, column: 29, scope: !19)
+!22 = !DILocalVariable(name: "z", scope: !19, file: !4, line: 3, type: !23)
+!23 = !DIBasicType(name: "short", size: 16, encoding: DW_ATE_signed)
+!24 = !DILocation(line: 3, column: 16, scope: !19)
+!25 = !DILocation(line: 4, column: 3, scope: !19)

Modified: llvm/trunk/test/Transforms/InstCombine/cast-set-preserve-signed-dbg-val.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/cast-set-preserve-signed-dbg-val.ll?rev=356442&r1=356441&r2=356442&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/cast-set-preserve-signed-dbg-val.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/cast-set-preserve-signed-dbg-val.ll Tue Mar 19 01:48:19 2019
@@ -14,7 +14,7 @@ define i16 @test5(i16 %A) !dbg !34 {
   ;
   ; The high 16 bits of the original 'and' require sign-extending the new 16-bit and:
   ; CHECK-NEXT: call void @llvm.dbg.value(metadata i16 [[and]], metadata [[C:![0-9]+]],
-  ; CHECK-SAME:    metadata !DIExpression(DW_OP_dup, DW_OP_constu, 15, DW_OP_shr, DW_OP_lit0, DW_OP_not, DW_OP_mul, DW_OP_or, DW_OP_stack_value)
+  ; CHECK-SAME:    metadata !DIExpression(DW_OP_LLVM_convert, 16, DW_ATE_signed, DW_OP_LLVM_convert, 32, DW_ATE_signed, DW_OP_stack_value)
 
   %D = trunc i32 %C to i16, !dbg !42
   call void @llvm.dbg.value(metadata i16 %D, metadata !38, metadata !DIExpression()), !dbg !42

Modified: llvm/trunk/unittests/Transforms/Utils/LocalTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Transforms/Utils/LocalTest.cpp?rev=356442&r1=356441&r2=356442&view=diff
==============================================================================
--- llvm/trunk/unittests/Transforms/Utils/LocalTest.cpp (original)
+++ llvm/trunk/unittests/Transforms/Utils/LocalTest.cpp Tue Mar 19 01:48:19 2019
@@ -788,31 +788,35 @@ TEST(Local, ReplaceAllDbgUsesWith) {
   };
 
   // Case 1: The original expr is empty, so no deref is needed.
-  EXPECT_TRUE(hasADbgVal({DW_OP_dup, DW_OP_constu, 31, DW_OP_shr, DW_OP_lit0,
-                          DW_OP_not, DW_OP_mul, DW_OP_or, DW_OP_stack_value}));
+  EXPECT_TRUE(hasADbgVal({DW_OP_LLVM_convert, 32, DW_ATE_signed,
+                         DW_OP_LLVM_convert, 64, DW_ATE_signed,
+                         DW_OP_stack_value}));
 
   // Case 2: Perform an address calculation with the original expr, deref it,
   // then sign-extend the result.
-  EXPECT_TRUE(hasADbgVal({DW_OP_lit0, DW_OP_mul, DW_OP_deref, DW_OP_dup,
-                          DW_OP_constu, 31, DW_OP_shr, DW_OP_lit0, DW_OP_not,
-                          DW_OP_mul, DW_OP_or, DW_OP_stack_value}));
+  EXPECT_TRUE(hasADbgVal({DW_OP_lit0, DW_OP_mul, DW_OP_deref,
+                         DW_OP_LLVM_convert, 32, DW_ATE_signed,
+                         DW_OP_LLVM_convert, 64, DW_ATE_signed,
+                         DW_OP_stack_value}));
 
   // Case 3: Insert the sign-extension logic before the DW_OP_stack_value.
-  EXPECT_TRUE(hasADbgVal({DW_OP_lit0, DW_OP_mul, DW_OP_dup, DW_OP_constu, 31,
-                          DW_OP_shr, DW_OP_lit0, DW_OP_not, DW_OP_mul, DW_OP_or,
-                          DW_OP_stack_value}));
+  EXPECT_TRUE(hasADbgVal({DW_OP_lit0, DW_OP_mul, DW_OP_LLVM_convert, 32,
+                         DW_ATE_signed, DW_OP_LLVM_convert, 64, DW_ATE_signed,
+                         DW_OP_stack_value}));
 
   // Cases 4-6: Just like cases 1-3, but preserve the fragment at the end.
-  EXPECT_TRUE(hasADbgVal({DW_OP_dup, DW_OP_constu, 31, DW_OP_shr, DW_OP_lit0,
-                          DW_OP_not, DW_OP_mul, DW_OP_or, DW_OP_stack_value,
-                          DW_OP_LLVM_fragment, 0, 8}));
-  EXPECT_TRUE(
-      hasADbgVal({DW_OP_lit0, DW_OP_mul, DW_OP_deref, DW_OP_dup, DW_OP_constu,
-                  31, DW_OP_shr, DW_OP_lit0, DW_OP_not, DW_OP_mul, DW_OP_or,
-                  DW_OP_stack_value, DW_OP_LLVM_fragment, 0, 8}));
-  EXPECT_TRUE(hasADbgVal({DW_OP_lit0, DW_OP_mul, DW_OP_dup, DW_OP_constu, 31,
-                          DW_OP_shr, DW_OP_lit0, DW_OP_not, DW_OP_mul, DW_OP_or,
-                          DW_OP_stack_value, DW_OP_LLVM_fragment, 0, 8}));
+  EXPECT_TRUE(hasADbgVal({DW_OP_LLVM_convert, 32, DW_ATE_signed,
+                         DW_OP_LLVM_convert, 64, DW_ATE_signed,
+                         DW_OP_stack_value, DW_OP_LLVM_fragment, 0, 8}));
+
+  EXPECT_TRUE(hasADbgVal({DW_OP_lit0, DW_OP_mul, DW_OP_deref,
+                         DW_OP_LLVM_convert, 32, DW_ATE_signed,
+                         DW_OP_LLVM_convert, 64, DW_ATE_signed,
+                         DW_OP_stack_value, DW_OP_LLVM_fragment, 0, 8}));
+
+  EXPECT_TRUE(hasADbgVal({DW_OP_lit0, DW_OP_mul, DW_OP_LLVM_convert, 32,
+                         DW_ATE_signed, DW_OP_LLVM_convert, 64, DW_ATE_signed,
+                         DW_OP_stack_value, DW_OP_LLVM_fragment, 0, 8}));
 
   verifyModule(*M, &errs(), &BrokenDebugInfo);
   ASSERT_FALSE(BrokenDebugInfo);




More information about the llvm-commits mailing list