[llvm] fix wrong inline assembly line/col info in the error message with ThinLTO (PR #102211)

via llvm-commits llvm-commits at lists.llvm.org
Tue Aug 6 13:15:13 PDT 2024


https://github.com/HighW4y2H3ll created https://github.com/llvm/llvm-project/pull/102211

Tests:
```
clang++ -flto=thin -c test.cpp -g
clang++ --shared -flto=thin -fuse-ld=lld test.o -v
```

```cpp
// File: test.cpp
void bad_asm() {
  asm volatile ("BAD SYNTAX$%");
}
void good_asm() {
  asm volatile ("movq $0xdeadbeef, %rax");
}
void bad_multi_asm() {
  asm ( "movl $10, %eax;"
        "BAD SYNTAX;"
        "subl %ebx, %eax;" );
}
void bad_multi_asm_linechg() {
  asm ( "movl $10, %eax;\n"
        "BAD SYNTAX;\n"
        "subl %ebx, %eax;\n" );
}
void good_multi_asm_linechg() {
  asm ( "movl $10, %eax;\n"
        "test %rax, %rax;\n"
        "subl %ebx, %eax;\n" );
}
void bad_multi_asm_op() {
  unsigned val=1, i=0;
  asm ( "movl %1, %%eax;\n"
        "BAD SYNTAX;\n"
        "subl %0, %%eax;\n" : "=r" (val) : "r" (i) : );
}
```

>From 5735e32fc185b277273842c862b7b4e363957f89 Mon Sep 17 00:00:00 2001
From: h2h <h2h at meta.com>
Date: Fri, 2 Aug 2024 17:26:47 -0700
Subject: [PATCH] fix wrong inline assembly line/col info in the error message
 with ThinLTO

Differential Revision: https://phabricator.intern.facebook.com/D60703275
---
 llvm/include/llvm/CodeGen/AsmPrinter.h            |  6 ++++--
 llvm/include/llvm/Support/SourceMgr.h             | 10 ++++++++++
 .../CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp    | 15 ++++++++++-----
 llvm/lib/Support/SourceMgr.cpp                    | 13 +++++++++++--
 4 files changed, 35 insertions(+), 9 deletions(-)

diff --git a/llvm/include/llvm/CodeGen/AsmPrinter.h b/llvm/include/llvm/CodeGen/AsmPrinter.h
index 36d1b47973870..88f437b1efaa7 100644
--- a/llvm/include/llvm/CodeGen/AsmPrinter.h
+++ b/llvm/include/llvm/CodeGen/AsmPrinter.h
@@ -877,7 +877,8 @@ class AsmPrinter : public MachineFunctionPass {
   emitInlineAsm(StringRef Str, const MCSubtargetInfo &STI,
                 const MCTargetOptions &MCOptions,
                 const MDNode *LocMDNode = nullptr,
-                InlineAsm::AsmDialect AsmDialect = InlineAsm::AD_ATT) const;
+                InlineAsm::AsmDialect AsmDialect = InlineAsm::AD_ATT,
+                const DebugLoc *DbgLoc = nullptr) const;
 
   /// This method formats and emits the specified machine instruction that is an
   /// inline asm.
@@ -886,7 +887,8 @@ class AsmPrinter : public MachineFunctionPass {
   /// Add inline assembly info to the diagnostics machinery, so we can
   /// emit file and position info. Returns SrcMgr memory buffer position.
   unsigned addInlineAsmDiagBuffer(StringRef AsmStr,
-                                  const MDNode *LocMDNode) const;
+                                  const MDNode *LocMDNode,
+                                  const DebugLoc *DbgLoc) const;
 
   //===------------------------------------------------------------------===//
   // Internal Implementation Details
diff --git a/llvm/include/llvm/Support/SourceMgr.h b/llvm/include/llvm/Support/SourceMgr.h
index 7a4b6de1162da..167ccb8a4810d 100644
--- a/llvm/include/llvm/Support/SourceMgr.h
+++ b/llvm/include/llvm/Support/SourceMgr.h
@@ -59,6 +59,9 @@ class SourceMgr {
     /// dynamically based on the size of Buffer.
     mutable void *OffsetCache = nullptr;
 
+    // Base Source LineNo and Column where this Buffer starts
+    unsigned BaseLine, BaseCol;
+
     /// Look up a given \p Ptr in the buffer, determining which line it came
     /// from.
     unsigned getLineNumber(const char *Ptr) const;
@@ -143,9 +146,16 @@ class SourceMgr {
   /// the memory buffer.
   unsigned AddNewSourceBuffer(std::unique_ptr<MemoryBuffer> F,
                               SMLoc IncludeLoc) {
+    return AddNewSourceBuffer(std::move(F), 0, 0, IncludeLoc);
+  }
+  unsigned AddNewSourceBuffer(std::unique_ptr<MemoryBuffer> F,
+                              unsigned Line, unsigned Col,
+                              SMLoc IncludeLoc) {
     SrcBuffer NB;
     NB.Buffer = std::move(F);
     NB.IncludeLoc = IncludeLoc;
+    NB.BaseLine = Line;
+    NB.BaseCol = Col;
     Buffers.push_back(std::move(NB));
     return Buffers.size();
   }
diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp
index 6fe8d0e0af995..0f62269aeb334 100644
--- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp
@@ -43,7 +43,8 @@ using namespace llvm;
 #define DEBUG_TYPE "asm-printer"
 
 unsigned AsmPrinter::addInlineAsmDiagBuffer(StringRef AsmStr,
-                                            const MDNode *LocMDNode) const {
+                                            const MDNode *LocMDNode,
+                                            const DebugLoc *DbgLoc) const {
   MCContext &Context = MMI->getContext();
   Context.initInlineSourceManager();
   SourceMgr &SrcMgr = *Context.getInlineSourceManager();
@@ -55,7 +56,9 @@ unsigned AsmPrinter::addInlineAsmDiagBuffer(StringRef AsmStr,
   Buffer = MemoryBuffer::getMemBufferCopy(AsmStr, "<inline asm>");
 
   // Tell SrcMgr about this buffer, it takes ownership of the buffer.
-  unsigned BufNum = SrcMgr.AddNewSourceBuffer(std::move(Buffer), SMLoc());
+  unsigned BufNum = DbgLoc ? \
+                    SrcMgr.AddNewSourceBuffer(std::move(Buffer), DbgLoc->getLine()-1, DbgLoc->getCol()-1, SMLoc()) : \
+                    SrcMgr.AddNewSourceBuffer(std::move(Buffer), SMLoc());
 
   // Store LocMDNode in DiagInfo, using BufNum as an identifier.
   if (LocMDNode) {
@@ -71,7 +74,8 @@ unsigned AsmPrinter::addInlineAsmDiagBuffer(StringRef AsmStr,
 void AsmPrinter::emitInlineAsm(StringRef Str, const MCSubtargetInfo &STI,
                                const MCTargetOptions &MCOptions,
                                const MDNode *LocMDNode,
-                               InlineAsm::AsmDialect Dialect) const {
+                               InlineAsm::AsmDialect Dialect,
+                               const DebugLoc *DbgLoc) const {
   assert(!Str.empty() && "Can't emit empty inline asm block");
 
   // Remember if the buffer is nul terminated or not so we can avoid a copy.
@@ -95,7 +99,7 @@ void AsmPrinter::emitInlineAsm(StringRef Str, const MCSubtargetInfo &STI,
     return;
   }
 
-  unsigned BufNum = addInlineAsmDiagBuffer(Str, LocMDNode);
+  unsigned BufNum = addInlineAsmDiagBuffer(Str, LocMDNode, DbgLoc);
   SourceMgr &SrcMgr = *MMI->getContext().getInlineSourceManager();
   SrcMgr.setIncludeDirs(MCOptions.IASSearchPaths);
 
@@ -415,8 +419,9 @@ void AsmPrinter::emitInlineAsm(const MachineInstr *MI) const {
     }
   }
 
+  const DebugLoc &DbgLoc = MI->getDebugLoc();
   emitInlineAsm(StringData, getSubtargetInfo(), TM.Options.MCOptions, LocMD,
-                MI->getInlineAsmDialect());
+                MI->getInlineAsmDialect(), DbgLoc ? &DbgLoc : nullptr);
 
   // Emit the #NOAPP end marker.  This has to happen even if verbose-asm isn't
   // enabled, so we use emitRawComment.
diff --git a/llvm/lib/Support/SourceMgr.cpp b/llvm/lib/Support/SourceMgr.cpp
index 3f97213d86c05..4a8355bd8e934 100644
--- a/llvm/lib/Support/SourceMgr.cpp
+++ b/llvm/lib/Support/SourceMgr.cpp
@@ -114,7 +114,7 @@ unsigned SourceMgr::SrcBuffer::getLineNumberSpecialized(const char *Ptr) const {
 
   // llvm::lower_bound gives the number of EOL before PtrOffset. Add 1 to get
   // the line number.
-  return llvm::lower_bound(Offsets, PtrOffset) - Offsets.begin() + 1;
+  return BaseLine + llvm::lower_bound(Offsets, PtrOffset) - Offsets.begin() + 1;
 }
 
 /// Look up a given \p Ptr in the buffer, determining which line it came
@@ -137,6 +137,10 @@ const char *SourceMgr::SrcBuffer::getPointerForLineNumberSpecialized(
   std::vector<T> &Offsets =
       GetOrCreateOffsetCache<T>(OffsetCache, Buffer.get());
 
+  // Offset the LineNo where the Buffer starts
+  if (LineNo >= BaseLine)
+    LineNo -= BaseLine;
+
   // We start counting line and column numbers from 1.
   if (LineNo != 0)
     --LineNo;
@@ -169,6 +173,7 @@ SourceMgr::SrcBuffer::getPointerForLineNumber(unsigned LineNo) const {
 
 SourceMgr::SrcBuffer::SrcBuffer(SourceMgr::SrcBuffer &&Other)
     : Buffer(std::move(Other.Buffer)), OffsetCache(Other.OffsetCache),
+      BaseLine(Other.BaseLine), BaseCol(Other.BaseCol),
       IncludeLoc(Other.IncludeLoc) {
   Other.OffsetCache = nullptr;
 }
@@ -202,7 +207,7 @@ SourceMgr::getLineAndColumn(SMLoc Loc, unsigned BufferID) const {
   size_t NewlineOffs = StringRef(BufStart, Ptr - BufStart).find_last_of("\n\r");
   if (NewlineOffs == StringRef::npos)
     NewlineOffs = ~(size_t)0;
-  return std::make_pair(LineNo, Ptr - BufStart - NewlineOffs);
+  return std::make_pair(LineNo, Ptr - BufStart - NewlineOffs + SB.BaseCol);
 }
 
 // FIXME: Note that the formatting of source locations is spread between
@@ -238,6 +243,10 @@ SMLoc SourceMgr::FindLocForLineAndColumn(unsigned BufferID, unsigned LineNo,
   if (!Ptr)
     return SMLoc();
 
+  // Offset the ColNo where Buffer starts
+  if (ColNo >= SB.BaseCol)
+    ColNo -= SB.BaseCol;
+
   // We start counting line and column numbers from 1.
   if (ColNo != 0)
     --ColNo;



More information about the llvm-commits mailing list