[lld] Add module name to LTO inline asm diagnostic

Close #52781: for LTO, the inline asm diagnostic uses `<inline asm>` as the file
name (lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp) and it is unclear which
module has the issue.

With this patch, we will see the module name (say `asm.o`) before `<inline asm>` with ThinLTO.

```
% clang -flto=thin -c asm.c && myld.lld asm.o -e f
ld.lld: error: asm.o <inline asm>:1:2: invalid instruction mnemonic 'invalid'
        invalid
        ^~~~~~~
```

For regular LTO, unfortunately the original module name is lost and we only get
ld-temp.o.

Reviewed By: #lld-macho, ychen, Jez Ng

Differential Revision: https://reviews.llvm.org/D118434
This commit is contained in:
Fangrui Song 2022-01-28 11:32:42 -08:00
parent 4abfe47e1f
commit 33b38339a0
5 changed files with 57 additions and 5 deletions

View File

@ -107,6 +107,13 @@ void lld::diagnosticHandler(const DiagnosticInfo &di) {
SmallString<128> s;
raw_svector_ostream os(s);
DiagnosticPrinterRawOStream dp(os);
// For an inline asm diagnostic, prepend the module name to get something like
// "$module <inline asm>:1:5: ".
if (auto *dism = dyn_cast<DiagnosticInfoSrcMgr>(&di))
if (dism->isInlineAsmDiag())
os << dism->getModuleName() << ' ';
di.print(dp);
switch (di.getSeverity()) {
case DS_Error:

View File

@ -0,0 +1,19 @@
; REQUIRES: x86
; RUN: llvm-as %s -o %t.bc
; RUN: not ld.lld -shared %t.bc -o /dev/null 2>&1 | FileCheck %s --check-prefix=REGULAR
;; For regular LTO, the original module name is lost.
; REGULAR: error: ld-temp.o <inline asm>:1:2: invalid instruction mnemonic 'invalid'
; RUN: opt -module-summary %s -o %t.bc
; RUN: not ld.lld -shared %t.bc -o /dev/null 2>&1 | FileCheck %s --check-prefix=THIN
; THIN: error: {{.*}}.bc <inline asm>:1:2: invalid instruction mnemonic 'invalid'
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
define void @foo() {
call void asm "invalid", ""()
ret void
}

View File

@ -0,0 +1,22 @@
; REQUIRES: x86
; RUN: llvm-as %s -o %t.bc
; RUN: not %lld %t.bc -o /dev/null 2>&1 | FileCheck %s --check-prefix=REGULAR
;; For regular LTO, the original module name is lost.
;; TODO Fix the line number
; REGULAR: error: ld-temp.o <inline asm>:3:1: invalid instruction mnemonic 'invalid'
; RUN: opt -module-summary %s -o %t.bc
; RUN: not %lld %t.bc -o /dev/null 2>&1 | FileCheck %s --check-prefix=THIN
; THIN: error: {{.*}}.bc <inline asm>:2:1: invalid instruction mnemonic 'invalid'
target triple = "x86_64-apple-macosx10.15.0"
target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
module asm ".text"
module asm "invalid"
define void @main() {
ret void
}

View File

@ -1049,18 +1049,20 @@ static DiagnosticSeverity getDiagnosticSeverity(SourceMgr::DiagKind DK) {
/// Diagnostic information for SMDiagnostic reporting.
class DiagnosticInfoSrcMgr : public DiagnosticInfo {
const SMDiagnostic &Diagnostic;
StringRef ModName;
// For inlineasm !srcloc translation.
bool InlineAsmDiag;
unsigned LocCookie;
public:
DiagnosticInfoSrcMgr(const SMDiagnostic &Diagnostic,
DiagnosticInfoSrcMgr(const SMDiagnostic &Diagnostic, StringRef ModName,
bool InlineAsmDiag = true, unsigned LocCookie = 0)
: DiagnosticInfo(DK_SrcMgr, getDiagnosticSeverity(Diagnostic.getKind())),
Diagnostic(Diagnostic), InlineAsmDiag(InlineAsmDiag),
Diagnostic(Diagnostic), ModName(ModName), InlineAsmDiag(InlineAsmDiag),
LocCookie(LocCookie) {}
StringRef getModuleName() const { return ModName; }
bool isInlineAsmDiag() const { return InlineAsmDiag; }
const SMDiagnostic &getSMDiag() const { return Diagnostic; }
unsigned getLocCookie() const { return LocCookie; }

View File

@ -400,12 +400,14 @@ bool MachineModuleInfoWrapperPass::doInitialization(Module &M) {
// FIXME: Do this for new pass manager.
LLVMContext &Ctx = M.getContext();
MMI.getContext().setDiagnosticHandler(
[&Ctx](const SMDiagnostic &SMD, bool IsInlineAsm, const SourceMgr &SrcMgr,
std::vector<const MDNode *> &LocInfos) {
[&Ctx, &M](const SMDiagnostic &SMD, bool IsInlineAsm,
const SourceMgr &SrcMgr,
std::vector<const MDNode *> &LocInfos) {
unsigned LocCookie = 0;
if (IsInlineAsm)
LocCookie = getLocCookie(SMD, SrcMgr, LocInfos);
Ctx.diagnose(DiagnosticInfoSrcMgr(SMD, IsInlineAsm, LocCookie));
Ctx.diagnose(
DiagnosticInfoSrcMgr(SMD, M.getName(), IsInlineAsm, LocCookie));
});
MMI.DbgInfoAvailable = !M.debug_compile_units().empty();
return false;