[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