[llvm] Improving ThinLTO error message for inline assembly errors (PR #102211)

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


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

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

---
 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 36d1b479738704..88f437b1efaa79 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 7a4b6de1162da4..167ccb8a4810de 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 6fe8d0e0af9951..0f62269aeb334d 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 3f97213d86c055..4a8355bd8e9346 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;

>From b706152156cd75a003d3e61ff1656a2694489cc0 Mon Sep 17 00:00:00 2001
From: h2h <h2h at meta.com>
Date: Wed, 7 Aug 2024 16:35:44 -0700
Subject: [PATCH 2/7] include source filename

---
 llvm/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp
index 0f62269aeb334d..b784856e6d246d 100644
--- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp
@@ -22,6 +22,7 @@
 #include "llvm/CodeGen/TargetSubtargetInfo.h"
 #include "llvm/IR/Constants.h"
 #include "llvm/IR/DataLayout.h"
+#include "llvm/IR/DebugInfoMetadata.h"
 #include "llvm/IR/DiagnosticInfo.h"
 #include "llvm/IR/InlineAsm.h"
 #include "llvm/IR/LLVMContext.h"
@@ -50,10 +51,11 @@ unsigned AsmPrinter::addInlineAsmDiagBuffer(StringRef AsmStr,
   SourceMgr &SrcMgr = *Context.getInlineSourceManager();
   std::vector<const MDNode *> &LocInfos = Context.getLocInfos();
 
+  DIScope *Scope = DbgLoc ? dyn_cast<DIScope>(DbgLoc->getScope()) : nullptr;
   std::unique_ptr<MemoryBuffer> Buffer;
   // The inline asm source manager will outlive AsmStr, so make a copy of the
   // string for SourceMgr to own.
-  Buffer = MemoryBuffer::getMemBufferCopy(AsmStr, "<inline asm>");
+  Buffer = MemoryBuffer::getMemBufferCopy(AsmStr, Scope ? Scope->getFilename() : "<inline asm>");
 
   // Tell SrcMgr about this buffer, it takes ownership of the buffer.
   unsigned BufNum = DbgLoc ? \

>From c1bca4ca33a17970e7ba36b4130f547957721db5 Mon Sep 17 00:00:00 2001
From: h2h <h2h at meta.com>
Date: Wed, 7 Aug 2024 16:36:02 -0700
Subject: [PATCH 3/7] add testcase

---
 .../CodeGen/Generic/inline-asm-debuginfo.c    | 33 +++++++++++++++++++
 1 file changed, 33 insertions(+)
 create mode 100644 llvm/test/CodeGen/Generic/inline-asm-debuginfo.c

diff --git a/llvm/test/CodeGen/Generic/inline-asm-debuginfo.c b/llvm/test/CodeGen/Generic/inline-asm-debuginfo.c
new file mode 100644
index 00000000000000..e6856344c02758
--- /dev/null
+++ b/llvm/test/CodeGen/Generic/inline-asm-debuginfo.c
@@ -0,0 +1,33 @@
+// RUN: set +o pipefail; clang -emit-llvm -c %s -g -o /dev/stdout | llc -o /dev/null 2>&1 | FileCheck %s
+void bad_asm() {
+  asm volatile ("BAD SYNTAX$%"); // CHECK: inline-asm-debuginfo.c:3:16: error: unknown token in expression
+}
+
+void good_asm() {
+  asm volatile ("movq $0xdeadbeef, %rax");
+}
+
+void bad_multi_asm() {
+  asm ( "movl $10, %eax;"
+        "BAD SYNTAX;"   // CHECK: inline-asm-debuginfo.c:11:19: error: invalid instruction mnemonic 'bad'
+        "subl %ebx, %eax;" );
+}
+
+void bad_multi_asm_linechg() {
+  asm ( "movl $10, %eax;\n"
+        "BAD SYNTAX;\n" // CHECK: inline-asm-debuginfo.c:18:3: error: invalid instruction mnemonic 'bad'
+        "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" // CHECK: inline-asm-debuginfo.c:31:3: error: invalid instruction mnemonic 'bad'
+        "subl %0, %%eax;\n" : "=r" (val) : "r" (i) : );
+}

>From c9f092a3e35b1a5ba91518a29fe612fdb34fb246 Mon Sep 17 00:00:00 2001
From: h2h <h2h at meta.com>
Date: Wed, 7 Aug 2024 17:05:09 -0700
Subject: [PATCH 4/7] make clang-format happy

---
 llvm/include/llvm/CodeGen/AsmPrinter.h             | 14 ++++++--------
 llvm/include/llvm/Support/SourceMgr.h              |  5 ++---
 .../lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp | 12 +++++++-----
 3 files changed, 15 insertions(+), 16 deletions(-)

diff --git a/llvm/include/llvm/CodeGen/AsmPrinter.h b/llvm/include/llvm/CodeGen/AsmPrinter.h
index 88f437b1efaa79..7897bcabed02d8 100644
--- a/llvm/include/llvm/CodeGen/AsmPrinter.h
+++ b/llvm/include/llvm/CodeGen/AsmPrinter.h
@@ -873,12 +873,11 @@ class AsmPrinter : public MachineFunctionPass {
   void emitFunctionPrefix(ArrayRef<const Constant *> Prefix);
 
   /// Emit a blob of inline asm to the output streamer.
-  void
-  emitInlineAsm(StringRef Str, const MCSubtargetInfo &STI,
-                const MCTargetOptions &MCOptions,
-                const MDNode *LocMDNode = nullptr,
-                InlineAsm::AsmDialect AsmDialect = InlineAsm::AD_ATT,
-                const DebugLoc *DbgLoc = nullptr) const;
+  void emitInlineAsm(StringRef Str, const MCSubtargetInfo &STI,
+                     const MCTargetOptions &MCOptions,
+                     const MDNode *LocMDNode = nullptr,
+                     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,8 +885,7 @@ 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,
+  unsigned addInlineAsmDiagBuffer(StringRef AsmStr, const MDNode *LocMDNode,
                                   const DebugLoc *DbgLoc) const;
 
   //===------------------------------------------------------------------===//
diff --git a/llvm/include/llvm/Support/SourceMgr.h b/llvm/include/llvm/Support/SourceMgr.h
index 167ccb8a4810de..6a0ef62c252c5d 100644
--- a/llvm/include/llvm/Support/SourceMgr.h
+++ b/llvm/include/llvm/Support/SourceMgr.h
@@ -148,9 +148,8 @@ class SourceMgr {
                               SMLoc IncludeLoc) {
     return AddNewSourceBuffer(std::move(F), 0, 0, IncludeLoc);
   }
-  unsigned AddNewSourceBuffer(std::unique_ptr<MemoryBuffer> F,
-                              unsigned Line, unsigned Col,
-                              SMLoc IncludeLoc) {
+  unsigned AddNewSourceBuffer(std::unique_ptr<MemoryBuffer> F, unsigned Line,
+                              unsigned Col, SMLoc IncludeLoc) {
     SrcBuffer NB;
     NB.Buffer = std::move(F);
     NB.IncludeLoc = IncludeLoc;
diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp
index b784856e6d246d..67dec6678c4ce8 100644
--- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp
@@ -55,12 +55,15 @@ unsigned AsmPrinter::addInlineAsmDiagBuffer(StringRef AsmStr,
   std::unique_ptr<MemoryBuffer> Buffer;
   // The inline asm source manager will outlive AsmStr, so make a copy of the
   // string for SourceMgr to own.
-  Buffer = MemoryBuffer::getMemBufferCopy(AsmStr, Scope ? Scope->getFilename() : "<inline asm>");
+  Buffer = MemoryBuffer::getMemBufferCopy(AsmStr, Scope ? Scope->getFilename()
+                                                        : "<inline asm>");
 
   // Tell SrcMgr about this buffer, it takes ownership of the buffer.
-  unsigned BufNum = DbgLoc ? \
-                    SrcMgr.AddNewSourceBuffer(std::move(Buffer), DbgLoc->getLine()-1, DbgLoc->getCol()-1, SMLoc()) : \
-                    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,6 @@ unsigned AsmPrinter::addInlineAsmDiagBuffer(StringRef AsmStr,
   return BufNum;
 }
 
-
 /// EmitInlineAsm - Emit a blob of inline asm to the output streamer.
 void AsmPrinter::emitInlineAsm(StringRef Str, const MCSubtargetInfo &STI,
                                const MCTargetOptions &MCOptions,

>From 53e8ae9f08d87d7247e5a8a6a4a504a86f8dbf6f Mon Sep 17 00:00:00 2001
From: h2h <h2h at meta.com>
Date: Thu, 8 Aug 2024 23:09:45 -0700
Subject: [PATCH 5/7] simplify testcase

---
 .../CodeGen/Generic/inline-asm-debuginfo.c    | 34 +++++--------------
 1 file changed, 9 insertions(+), 25 deletions(-)

diff --git a/llvm/test/CodeGen/Generic/inline-asm-debuginfo.c b/llvm/test/CodeGen/Generic/inline-asm-debuginfo.c
index e6856344c02758..b60e465fbc5ae1 100644
--- a/llvm/test/CodeGen/Generic/inline-asm-debuginfo.c
+++ b/llvm/test/CodeGen/Generic/inline-asm-debuginfo.c
@@ -1,33 +1,17 @@
-// RUN: set +o pipefail; clang -emit-llvm -c %s -g -o /dev/stdout | llc -o /dev/null 2>&1 | FileCheck %s
+// RUN: set +o pipefail; clang -emit-llvm -c %s -g -o %t
+// RUN: llc %t 2>&1 | FileCheck %s
 void bad_asm() {
-  asm volatile ("BAD SYNTAX$%"); // CHECK: inline-asm-debuginfo.c:3:16: error: unknown token in expression
-}
-
-void good_asm() {
-  asm volatile ("movq $0xdeadbeef, %rax");
+  asm volatile ("BAD SYNTAX$%"); // CHECK: inline-asm-debuginfo.c:4:16: error: unknown token in expression
 }
 
 void bad_multi_asm() {
-  asm ( "movl $10, %eax;"
-        "BAD SYNTAX;"   // CHECK: inline-asm-debuginfo.c:11:19: error: invalid instruction mnemonic 'bad'
-        "subl %ebx, %eax;" );
+  asm ( ";"
+        "BAD SYNTAX;"   // CHECK: inline-asm-debuginfo.c:8:5: error: invalid instruction mnemonic 'bad'
+        ";" );
 }
 
 void bad_multi_asm_linechg() {
-  asm ( "movl $10, %eax;\n"
-        "BAD SYNTAX;\n" // CHECK: inline-asm-debuginfo.c:18:3: error: invalid instruction mnemonic 'bad'
-        "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" // CHECK: inline-asm-debuginfo.c:31:3: error: invalid instruction mnemonic 'bad'
-        "subl %0, %%eax;\n" : "=r" (val) : "r" (i) : );
+  asm ( ";\n"
+        "BAD SYNTAX;\n" // CHECK: inline-asm-debuginfo.c:15:3: error: invalid instruction mnemonic 'bad'
+        ";\n" );
 }

>From 58d20c38b760c980469abdb1406383b29330aeb5 Mon Sep 17 00:00:00 2001
From: h2h <h2h at meta.com>
Date: Mon, 12 Aug 2024 21:35:33 -0700
Subject: [PATCH 6/7] use clang style error message for inline assembly

---
 llvm/include/llvm/Support/SourceMgr.h         | 29 ++++++++--
 .../AsmPrinter/AsmPrinterInlineAsm.cpp        |  8 +--
 llvm/lib/Support/SourceMgr.cpp                | 56 ++++++++++++++-----
 .../CodeGen/Generic/inline-asm-debuginfo.c    |  6 +-
 4 files changed, 75 insertions(+), 24 deletions(-)

diff --git a/llvm/include/llvm/Support/SourceMgr.h b/llvm/include/llvm/Support/SourceMgr.h
index 6a0ef62c252c5d..e7239f54c5b4b5 100644
--- a/llvm/include/llvm/Support/SourceMgr.h
+++ b/llvm/include/llvm/Support/SourceMgr.h
@@ -61,6 +61,7 @@ class SourceMgr {
 
     // Base Source LineNo and Column where this Buffer starts
     unsigned BaseLine, BaseCol;
+    StringRef SourceFilename;
 
     /// Look up a given \p Ptr in the buffer, determining which line it came
     /// from.
@@ -146,15 +147,16 @@ class SourceMgr {
   /// the memory buffer.
   unsigned AddNewSourceBuffer(std::unique_ptr<MemoryBuffer> F,
                               SMLoc IncludeLoc) {
-    return AddNewSourceBuffer(std::move(F), 0, 0, IncludeLoc);
+    return AddNewSourceBuffer(std::move(F), "", 0, 0, IncludeLoc);
   }
-  unsigned AddNewSourceBuffer(std::unique_ptr<MemoryBuffer> F, unsigned Line,
-                              unsigned Col, SMLoc IncludeLoc) {
+  unsigned AddNewSourceBuffer(std::unique_ptr<MemoryBuffer> F, StringRef SrcFN,
+                              unsigned Line, unsigned Col, SMLoc IncludeLoc) {
     SrcBuffer NB;
     NB.Buffer = std::move(F);
     NB.IncludeLoc = IncludeLoc;
     NB.BaseLine = Line;
     NB.BaseCol = Col;
+    NB.SourceFilename = SrcFN;
     Buffers.push_back(std::move(NB));
     return Buffers.size();
   }
@@ -210,6 +212,11 @@ class SourceMgr {
   /// specified file. This is not a fast method.
   std::pair<unsigned, unsigned> getLineAndColumn(SMLoc Loc,
                                                  unsigned BufferID = 0) const;
+  /// Similiar to `getLineAndColumn` but propagates debug info
+  std::pair<unsigned, unsigned>
+  getDebugLineAndColumn(SMLoc Loc, unsigned BufferID = 0) const;
+  /// Get the source filename from debug info, return "" if no debug info found
+  StringRef getDebugFilename(SMLoc Loc, unsigned BufferID = 0) const;
 
   /// Get a string with the \p SMLoc filename and line number
   /// formatted in the standard style.
@@ -293,6 +300,9 @@ class SMDiagnostic {
   std::string Filename;
   int LineNo = 0;
   int ColumnNo = 0;
+  std::string SrcFilename;
+  int SrcLineNo = 0;
+  int SrcColumnNo = 0;
   SourceMgr::DiagKind Kind = SourceMgr::DK_Error;
   std::string Message, LineContents;
   std::vector<std::pair<unsigned, unsigned>> Ranges;
@@ -303,13 +313,24 @@ class SMDiagnostic {
   SMDiagnostic() = default;
   // Diagnostic with no location (e.g. file not found, command line arg error).
   SMDiagnostic(StringRef filename, SourceMgr::DiagKind Knd, StringRef Msg)
-      : Filename(filename), LineNo(-1), ColumnNo(-1), Kind(Knd), Message(Msg) {}
+      : Filename(filename), LineNo(-1), ColumnNo(-1), SrcFilename(filename),
+        SrcLineNo(-1), SrcColumnNo(-1), Kind(Knd), Message(Msg) {}
 
   // Diagnostic with a location.
   SMDiagnostic(const SourceMgr &sm, SMLoc L, StringRef FN, int Line, int Col,
                SourceMgr::DiagKind Kind, StringRef Msg, StringRef LineStr,
                ArrayRef<std::pair<unsigned, unsigned>> Ranges,
                ArrayRef<SMFixIt> FixIts = {});
+  SMDiagnostic(const SourceMgr &sm, SMLoc L, StringRef FN, int Line, int Col,
+               StringRef SrcFN, int SrcLine, int SrcCol,
+               SourceMgr::DiagKind Kind, StringRef Msg, StringRef LineStr,
+               ArrayRef<std::pair<unsigned, unsigned>> Ranges,
+               ArrayRef<SMFixIt> FixIts = {})
+      : SMDiagnostic(sm, L, FN, Line, Col, Kind, Msg, LineStr, Ranges, FixIts) {
+    SrcFilename = std::string(SrcFN);
+    SrcLineNo = SrcLine;
+    SrcColumnNo = SrcCol;
+  }
 
   const SourceMgr *getSourceMgr() const { return SM; }
   SMLoc getLoc() const { return Loc; }
diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp
index 67dec6678c4ce8..00520e8b89487b 100644
--- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp
@@ -55,13 +55,13 @@ unsigned AsmPrinter::addInlineAsmDiagBuffer(StringRef AsmStr,
   std::unique_ptr<MemoryBuffer> Buffer;
   // The inline asm source manager will outlive AsmStr, so make a copy of the
   // string for SourceMgr to own.
-  Buffer = MemoryBuffer::getMemBufferCopy(AsmStr, Scope ? Scope->getFilename()
-                                                        : "<inline asm>");
+  Buffer = MemoryBuffer::getMemBufferCopy(AsmStr, "<inline asm>");
 
   // Tell SrcMgr about this buffer, it takes ownership of the buffer.
   unsigned BufNum =
-      DbgLoc
-          ? SrcMgr.AddNewSourceBuffer(std::move(Buffer), DbgLoc->getLine() - 1,
+      (DbgLoc && Scope)
+          ? SrcMgr.AddNewSourceBuffer(std::move(Buffer), Scope->getFilename(),
+                                      DbgLoc->getLine() - 1,
                                       DbgLoc->getCol() - 1, SMLoc())
           : SrcMgr.AddNewSourceBuffer(std::move(Buffer), SMLoc());
 
diff --git a/llvm/lib/Support/SourceMgr.cpp b/llvm/lib/Support/SourceMgr.cpp
index 4a8355bd8e9346..dd4900d0bc8d70 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 BaseLine + llvm::lower_bound(Offsets, PtrOffset) - Offsets.begin() + 1;
+  return llvm::lower_bound(Offsets, PtrOffset) - Offsets.begin() + 1;
 }
 
 /// Look up a given \p Ptr in the buffer, determining which line it came
@@ -137,10 +137,6 @@ 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;
@@ -174,7 +170,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) {
+      SourceFilename(Other.SourceFilename), IncludeLoc(Other.IncludeLoc) {
   Other.OffsetCache = nullptr;
 }
 
@@ -193,6 +189,29 @@ SourceMgr::SrcBuffer::~SrcBuffer() {
   }
 }
 
+StringRef SourceMgr::getDebugFilename(SMLoc Loc, unsigned BufferID) const {
+  if (!BufferID)
+    BufferID = FindBufferContainingLoc(Loc);
+  assert(BufferID && "Invalid location!");
+
+  auto &SB = getBufferInfo(BufferID);
+
+  return SB.SourceFilename;
+}
+
+std::pair<unsigned, unsigned>
+SourceMgr::getDebugLineAndColumn(SMLoc Loc, unsigned BufferID) const {
+  if (!BufferID)
+    BufferID = FindBufferContainingLoc(Loc);
+  assert(BufferID && "Invalid location!");
+
+  auto &SB = getBufferInfo(BufferID);
+
+  std::pair<unsigned, unsigned> LineAndCol = getLineAndColumn(Loc, BufferID);
+  return std::make_pair(SB.BaseLine + LineAndCol.first,
+                        SB.BaseCol + LineAndCol.second);
+}
+
 std::pair<unsigned, unsigned>
 SourceMgr::getLineAndColumn(SMLoc Loc, unsigned BufferID) const {
   if (!BufferID)
@@ -207,7 +226,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 + SB.BaseCol);
+  return std::make_pair(LineNo, Ptr - BufStart - NewlineOffs);
 }
 
 // FIXME: Note that the formatting of source locations is spread between
@@ -243,10 +262,6 @@ 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;
@@ -286,9 +301,10 @@ SMDiagnostic SourceMgr::GetMessage(SMLoc Loc, SourceMgr::DiagKind Kind,
   // First thing to do: find the current buffer containing the specified
   // location to pull out the source line.
   SmallVector<std::pair<unsigned, unsigned>, 4> ColRanges;
-  std::pair<unsigned, unsigned> LineAndCol;
+  std::pair<unsigned, unsigned> LineAndCol, DbgLineAndCol;
   StringRef BufferID = "<unknown>";
   StringRef LineStr;
+  StringRef DbgFN;
 
   if (Loc.isValid()) {
     unsigned CurBuf = FindBufferContainingLoc(Loc);
@@ -334,10 +350,13 @@ SMDiagnostic SourceMgr::GetMessage(SMLoc Loc, SourceMgr::DiagKind Kind,
     }
 
     LineAndCol = getLineAndColumn(Loc, CurBuf);
+    DbgLineAndCol = getDebugLineAndColumn(Loc, CurBuf);
+    DbgFN = getDebugFilename(Loc, CurBuf);
   }
 
   return SMDiagnostic(*this, Loc, BufferID, LineAndCol.first,
-                      LineAndCol.second - 1, Kind, Msg.str(), LineStr,
+                      LineAndCol.second - 1, DbgFN, DbgLineAndCol.first,
+                      DbgLineAndCol.second - 1, Kind, Msg.str(), LineStr,
                       ColRanges, FixIts);
 }
 
@@ -390,6 +409,7 @@ SMDiagnostic::SMDiagnostic(const SourceMgr &sm, SMLoc L, StringRef FN, int Line,
                            ArrayRef<std::pair<unsigned, unsigned>> Ranges,
                            ArrayRef<SMFixIt> Hints)
     : SM(&sm), Loc(L), Filename(std::string(FN)), LineNo(Line), ColumnNo(Col),
+      SrcFilename(std::string(FN)), SrcLineNo(Line), SrcColumnNo(Col),
       Kind(Kind), Message(Msg), LineContents(LineStr), Ranges(Ranges.vec()),
       FixIts(Hints) {
   llvm::sort(FixIts);
@@ -501,6 +521,16 @@ void SMDiagnostic::print(const char *ProgName, raw_ostream &OS, bool ShowColors,
       S << ProgName << ": ";
 
     if (ShowLocation && !Filename.empty()) {
+      if (Filename == "<inline asm>" && !SrcFilename.empty()) {
+        S << SrcFilename;
+        if (SrcLineNo != -1) {
+          S << ':' << SrcLineNo;
+          if (SrcColumnNo != -1)
+            S << ':' << (SrcColumnNo + 1);
+        }
+        S << ": ";
+      }
+
       if (Filename == "-")
         S << "<stdin>";
       else
diff --git a/llvm/test/CodeGen/Generic/inline-asm-debuginfo.c b/llvm/test/CodeGen/Generic/inline-asm-debuginfo.c
index b60e465fbc5ae1..20effeb191f449 100644
--- a/llvm/test/CodeGen/Generic/inline-asm-debuginfo.c
+++ b/llvm/test/CodeGen/Generic/inline-asm-debuginfo.c
@@ -1,17 +1,17 @@
 // RUN: set +o pipefail; clang -emit-llvm -c %s -g -o %t
 // RUN: llc %t 2>&1 | FileCheck %s
 void bad_asm() {
-  asm volatile ("BAD SYNTAX$%"); // CHECK: inline-asm-debuginfo.c:4:16: error: unknown token in expression
+  asm volatile ("BAD SYNTAX$%"); // CHECK: inline-asm-debuginfo.c:4:16: <inline asm>:1:14: error: unknown token in expression
 }
 
 void bad_multi_asm() {
   asm ( ";"
-        "BAD SYNTAX;"   // CHECK: inline-asm-debuginfo.c:8:5: error: invalid instruction mnemonic 'bad'
+        "BAD SYNTAX;"   // CHECK: inline-asm-debuginfo.c:8:5: <inline asm>:1:3: error: invalid instruction mnemonic 'bad'
         ";" );
 }
 
 void bad_multi_asm_linechg() {
   asm ( ";\n"
-        "BAD SYNTAX;\n" // CHECK: inline-asm-debuginfo.c:15:3: error: invalid instruction mnemonic 'bad'
+        "BAD SYNTAX;\n" // CHECK: inline-asm-debuginfo.c:15:3: <inline asm>:2:1: error: invalid instruction mnemonic 'bad'
         ";\n" );
 }

>From 65949a83be2bd05221f0871b1de65de7ca565217 Mon Sep 17 00:00:00 2001
From: h2h <h2h at meta.com>
Date: Tue, 13 Aug 2024 14:57:37 -0700
Subject: [PATCH 7/7] more portable way to disable pipefail

---
 llvm/test/CodeGen/Generic/inline-asm-debuginfo.c | 2 +-
 llvm/test/CodeGen/Generic/lit.local.cfg          | 1 +
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/llvm/test/CodeGen/Generic/inline-asm-debuginfo.c b/llvm/test/CodeGen/Generic/inline-asm-debuginfo.c
index 20effeb191f449..3986034caa3ec8 100644
--- a/llvm/test/CodeGen/Generic/inline-asm-debuginfo.c
+++ b/llvm/test/CodeGen/Generic/inline-asm-debuginfo.c
@@ -1,4 +1,4 @@
-// RUN: set +o pipefail; clang -emit-llvm -c %s -g -o %t
+// RUN: clang -emit-llvm -c %s -g -o %t
 // RUN: llc %t 2>&1 | FileCheck %s
 void bad_asm() {
   asm volatile ("BAD SYNTAX$%"); // CHECK: inline-asm-debuginfo.c:4:16: <inline asm>:1:14: error: unknown token in expression
diff --git a/llvm/test/CodeGen/Generic/lit.local.cfg b/llvm/test/CodeGen/Generic/lit.local.cfg
index 1eae465c12545f..873068862fbbb9 100644
--- a/llvm/test/CodeGen/Generic/lit.local.cfg
+++ b/llvm/test/CodeGen/Generic/lit.local.cfg
@@ -1,2 +1,3 @@
 if not config.target_triple:
     config.unsupported = True
+config.pipefail = False



More information about the llvm-commits mailing list