[llvm] [MC][X86/M68k] Emit syntax directive for AT&T (PR #167234)
Raul Tambre via llvm-commits
llvm-commits at lists.llvm.org
Mon Nov 10 12:59:35 PST 2025
https://github.com/tambry updated https://github.com/llvm/llvm-project/pull/167234
>From a9732a21afe912a1a6e74e8b9fe93e00be5f84de Mon Sep 17 00:00:00 2001
From: Raul Tambre <raul at tambre.ee>
Date: Sun, 9 Nov 2025 16:41:20 +0200
Subject: [PATCH] [MC][X86/m68k] Emit syntax directive for AT&T
This eases interoperability by making it explicit in emitted assembly code which syntax is used.
Refactored to remove X86-specific directives and logic from the generic MC(Asm)Streamer.
Motivated by building LLVM with `-mllvm -x86-asm-syntax=intel` (i.e. a global preference for Intel
syntax). A Bolt test (`runtime/X86/fdata-escape-chars.ll`) was using `llc` to compile to assembly
and then assembling with `clang`. The specific option causes Clang to assume Intel syntax but only
for assembly and not inline assembly.
---
llvm/docs/ReleaseNotes.md | 2 ++
llvm/include/llvm/MC/MCStreamer.h | 2 +-
llvm/lib/MC/MCAsmStreamer.cpp | 14 ++++++--------
llvm/lib/MC/MCStreamer.cpp | 2 +-
llvm/lib/Target/M68k/M68kAsmPrinter.cpp | 6 +++++-
llvm/lib/Target/X86/X86AsmPrinter.cpp | 8 +++++++-
llvm/test/CodeGen/X86/asm-syntax-directive.ll | 7 +++++++
llvm/test/CodeGen/X86/coal-sections.ll | 2 +-
8 files changed, 30 insertions(+), 13 deletions(-)
create mode 100644 llvm/test/CodeGen/X86/asm-syntax-directive.ll
diff --git a/llvm/docs/ReleaseNotes.md b/llvm/docs/ReleaseNotes.md
index fd78c97c86d24..ee8072c68855d 100644
--- a/llvm/docs/ReleaseNotes.md
+++ b/llvm/docs/ReleaseNotes.md
@@ -152,6 +152,8 @@ Changes to the X86 Backend
* `-mcpu=wildcatlake` is now supported.
* `-mcpu=novalake` is now supported.
+* `.att_syntax` is now emitted at the beginning of the file when emitting AT&T
+ syntax assembly.
Changes to the OCaml bindings
-----------------------------
diff --git a/llvm/include/llvm/MC/MCStreamer.h b/llvm/include/llvm/MC/MCStreamer.h
index 79c715e3820a6..eaee7957e090d 100644
--- a/llvm/include/llvm/MC/MCStreamer.h
+++ b/llvm/include/llvm/MC/MCStreamer.h
@@ -1055,7 +1055,7 @@ class LLVM_ABI MCStreamer {
/// Get the .xdata section used for the given section.
MCSection *getAssociatedXDataSection(const MCSection *TextSec);
- virtual void emitSyntaxDirective();
+ virtual void emitSyntaxDirective(StringRef Syntax, StringRef Options);
/// Record a relocation described by the .reloc directive.
virtual void emitRelocDirective(const MCExpr &Offset, StringRef Name,
diff --git a/llvm/lib/MC/MCAsmStreamer.cpp b/llvm/lib/MC/MCAsmStreamer.cpp
index 885fa55b65d50..dc5673234ed2e 100644
--- a/llvm/lib/MC/MCAsmStreamer.cpp
+++ b/llvm/lib/MC/MCAsmStreamer.cpp
@@ -123,7 +123,7 @@ class MCAsmStreamer final : public MCStreamer {
EmitCommentsAndEOL();
}
- void emitSyntaxDirective() override;
+ void emitSyntaxDirective(StringRef Syntax, StringRef Options) override;
void EmitCommentsAndEOL();
@@ -796,14 +796,12 @@ void MCAsmStreamer::emitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {
EmitEOL();
}
-void MCAsmStreamer::emitSyntaxDirective() {
- if (MAI->getAssemblerDialect() == 1) {
- OS << "\t.intel_syntax noprefix";
- EmitEOL();
+void MCAsmStreamer::emitSyntaxDirective(StringRef Syntax, StringRef Options) {
+ OS << "\t." << Syntax << "_syntax";
+ if (!Options.empty()) {
+ OS << " " << Options;
}
- // FIXME: Currently emit unprefix'ed registers.
- // The intel_syntax directive has one optional argument
- // with may have a value of prefix or noprefix.
+ EmitEOL();
}
void MCAsmStreamer::beginCOFFSymbolDef(const MCSymbol *Symbol) {
diff --git a/llvm/lib/MC/MCStreamer.cpp b/llvm/lib/MC/MCStreamer.cpp
index bc7398120096e..108ddf9910f82 100644
--- a/llvm/lib/MC/MCStreamer.cpp
+++ b/llvm/lib/MC/MCStreamer.cpp
@@ -876,7 +876,7 @@ MCSection *MCStreamer::getAssociatedXDataSection(const MCSection *TextSec) {
TextSec);
}
-void MCStreamer::emitSyntaxDirective() {}
+void MCStreamer::emitSyntaxDirective(StringRef Syntax, StringRef Options) {}
static unsigned encodeSEHRegNum(MCContext &Ctx, MCRegister Reg) {
return Ctx.getRegisterInfo()->getSEHRegNum(Reg);
diff --git a/llvm/lib/Target/M68k/M68kAsmPrinter.cpp b/llvm/lib/Target/M68k/M68kAsmPrinter.cpp
index 0437400b81d84..15b4760a2f06e 100644
--- a/llvm/lib/Target/M68k/M68kAsmPrinter.cpp
+++ b/llvm/lib/Target/M68k/M68kAsmPrinter.cpp
@@ -190,7 +190,11 @@ void M68kAsmPrinter::emitFunctionBodyStart() {}
void M68kAsmPrinter::emitFunctionBodyEnd() {}
void M68kAsmPrinter::emitStartOfAsmFile(Module &M) {
- OutStreamer->emitSyntaxDirective();
+ // m68k assemblers generally don't support .att_syntax so we only emit the
+ // directive for Intel syntax.
+ if (MAI->getAssemblerDialect() == InlineAsm::AD_Intel) {
+ OutStreamer->emitSyntaxDirective("intel", "noprefix");
+ }
}
void M68kAsmPrinter::emitEndOfAsmFile(Module &M) {}
diff --git a/llvm/lib/Target/X86/X86AsmPrinter.cpp b/llvm/lib/Target/X86/X86AsmPrinter.cpp
index 84b921222a116..7dbc548d3c05b 100644
--- a/llvm/lib/Target/X86/X86AsmPrinter.cpp
+++ b/llvm/lib/Target/X86/X86AsmPrinter.cpp
@@ -932,7 +932,13 @@ void X86AsmPrinter::emitStartOfAsmFile(Module &M) {
if (M.getModuleFlag("import-call-optimization"))
EnableImportCallOptimization = true;
}
- OutStreamer->emitSyntaxDirective();
+
+ // FIXME: Currently emit unprefix'ed registers.
+ // The intel_syntax directive has one optional argument
+ // with may have a value of prefix or noprefix.
+ const bool IntelSyntax = MAI->getAssemblerDialect() == InlineAsm::AD_Intel;
+ OutStreamer->emitSyntaxDirective(IntelSyntax ? "intel" : "att",
+ IntelSyntax ? "noprefix" : "");
// If this is not inline asm and we're in 16-bit
// mode prefix assembly with .code16.
diff --git a/llvm/test/CodeGen/X86/asm-syntax-directive.ll b/llvm/test/CodeGen/X86/asm-syntax-directive.ll
new file mode 100644
index 0000000000000..4cdf4408c2084
--- /dev/null
+++ b/llvm/test/CodeGen/X86/asm-syntax-directive.ll
@@ -0,0 +1,7 @@
+;; Make sure that we always emit an assembly syntax directive for X86.
+; RUN: llc < %s -mtriple=x86_64 | FileCheck %s --check-prefix=ATT
+; RUN: llc < %s -mtriple=x86_64 -x86-asm-syntax=att | FileCheck %s --check-prefix=ATT
+; RUN: llc < %s -mtriple=x86_64 -x86-asm-syntax=intel | FileCheck %s --check-prefix=INTEL
+
+; INTEL: .intel_syntax noprefix
+; ATT: .att_syntax
diff --git a/llvm/test/CodeGen/X86/coal-sections.ll b/llvm/test/CodeGen/X86/coal-sections.ll
index 3fed158befdd8..faab0397a4053 100644
--- a/llvm/test/CodeGen/X86/coal-sections.ll
+++ b/llvm/test/CodeGen/X86/coal-sections.ll
@@ -3,7 +3,7 @@
; Check that *coal* sections are not emitted.
; CHECK: .section __TEXT,__text,regular,pure_instructions{{$}}
-; CHECK-NEXT: .globl _foo
+; CHECK: .globl _foo
; CHECK: .section __TEXT,__const{{$}}
; CHECK-NEXT: .globl _a
More information about the llvm-commits
mailing list