[clang] [llvm] [LFI] Add MCLFIRewriter infrastructure (PR #172906)
Zachary Yedidia via cfe-commits
cfe-commits at lists.llvm.org
Thu Feb 19 13:52:32 PST 2026
https://github.com/zyedidia updated https://github.com/llvm/llvm-project/pull/172906
>From 9cb2b6018574a11d34e794a7cae02f274c8672e8 Mon Sep 17 00:00:00 2001
From: Zachary Yedidia <zyedidia at gmail.com>
Date: Wed, 21 Jan 2026 17:35:59 -0500
Subject: [PATCH 1/8] [LFI] Add MCLFIRewriter infrastructure
---
clang/tools/driver/cc1as_main.cpp | 3 +
llvm/include/llvm/MC/MCLFI.h | 23 ++++++
llvm/include/llvm/MC/MCLFIRewriter.h | 70 +++++++++++++++++
.../llvm/MC/MCParser/MCAsmParserExtension.h | 16 ++--
llvm/include/llvm/MC/MCStreamer.h | 7 ++
llvm/include/llvm/MC/TargetRegistry.h | 21 ++++++
llvm/lib/MC/CMakeLists.txt | 2 +
llvm/lib/MC/MCAsmStreamer.cpp | 5 ++
llvm/lib/MC/MCLFI.cpp | 75 +++++++++++++++++++
llvm/lib/MC/MCLFIRewriter.cpp | 61 +++++++++++++++
llvm/lib/MC/MCObjectStreamer.cpp | 5 ++
llvm/lib/MC/MCParser/AsmParser.cpp | 9 ++-
llvm/lib/MC/MCParser/CMakeLists.txt | 1 +
llvm/lib/MC/MCParser/LFIAsmParser.cpp | 69 +++++++++++++++++
llvm/lib/MC/MCStreamer.cpp | 3 +
llvm/tools/llvm-mc/llvm-mc.cpp | 14 ++++
16 files changed, 375 insertions(+), 9 deletions(-)
create mode 100644 llvm/include/llvm/MC/MCLFI.h
create mode 100644 llvm/include/llvm/MC/MCLFIRewriter.h
create mode 100644 llvm/lib/MC/MCLFI.cpp
create mode 100644 llvm/lib/MC/MCLFIRewriter.cpp
create mode 100644 llvm/lib/MC/MCParser/LFIAsmParser.cpp
diff --git a/clang/tools/driver/cc1as_main.cpp b/clang/tools/driver/cc1as_main.cpp
index ccc48a77891d7..6cbccbc3d7408 100644
--- a/clang/tools/driver/cc1as_main.cpp
+++ b/clang/tools/driver/cc1as_main.cpp
@@ -28,6 +28,7 @@
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCInstPrinter.h"
#include "llvm/MC/MCInstrInfo.h"
+#include "llvm/MC/MCLFI.h"
#include "llvm/MC/MCObjectFileInfo.h"
#include "llvm/MC/MCObjectWriter.h"
#include "llvm/MC/MCParser/MCAsmParser.h"
@@ -593,6 +594,8 @@ static bool ExecuteAssemblerImpl(AssemblerInvocation &Opts,
Triple T(Opts.Triple);
Str.reset(TheTarget->createMCObjectStreamer(
T, Ctx, std::move(MAB), std::move(OW), std::move(CE), *STI));
+ if (T.isLFI())
+ initializeLFIMCStreamer(*Str.get(), Ctx, T);
if (T.isOSBinFormatMachO() && T.isOSDarwin()) {
Triple *TVT = Opts.DarwinTargetVariantTriple
? &*Opts.DarwinTargetVariantTriple
diff --git a/llvm/include/llvm/MC/MCLFI.h b/llvm/include/llvm/MC/MCLFI.h
new file mode 100644
index 0000000000000..6598453952642
--- /dev/null
+++ b/llvm/include/llvm/MC/MCLFI.h
@@ -0,0 +1,23 @@
+//===- MCLFI.h - LFI-specific code for MC -----------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+// This file was written by the LFI and Native Client authors.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Compiler.h"
+
+namespace llvm {
+
+class MCContext;
+class MCStreamer;
+class Triple;
+
+LLVM_ABI void initializeLFIMCStreamer(MCStreamer &Streamer, MCContext &Ctx,
+ const Triple &TheTriple);
+
+} // namespace llvm
diff --git a/llvm/include/llvm/MC/MCLFIRewriter.h b/llvm/include/llvm/MC/MCLFIRewriter.h
new file mode 100644
index 0000000000000..06e1d03b21efe
--- /dev/null
+++ b/llvm/include/llvm/MC/MCLFIRewriter.h
@@ -0,0 +1,70 @@
+//===- llvm/MC/MCLFIRewriter.h ----------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+// This file was written by the LFI and Native Client authors.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the MCLFIRewriter class. This is an abstract
+// class that encapsulates the rewriting logic for MCInsts.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCLFIREWRITER_H
+#define LLVM_MC_MCLFIREWRITER_H
+
+#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCInstrInfo.h"
+#include "llvm/MC/MCRegisterInfo.h"
+#include "llvm/Support/Compiler.h"
+
+namespace llvm {
+class MCInst;
+class MCSubtargetInfo;
+class MCStreamer;
+class MCSymbol;
+
+class MCLFIRewriter {
+private:
+ MCContext &Ctx;
+ bool Enabled = true;
+
+protected:
+ std::unique_ptr<MCInstrInfo> InstInfo;
+ std::unique_ptr<MCRegisterInfo> RegInfo;
+
+public:
+ MCLFIRewriter(MCContext &Ctx, std::unique_ptr<MCRegisterInfo> &&RI,
+ std::unique_ptr<MCInstrInfo> &&II)
+ : Ctx(Ctx), InstInfo(std::move(II)), RegInfo(std::move(RI)) {}
+
+ LLVM_ABI void error(const MCInst &Inst, const char Msg[]);
+
+ LLVM_ABI void disable();
+ LLVM_ABI void enable();
+ LLVM_ABI bool isEnabled();
+
+ LLVM_ABI bool isCall(const MCInst &Inst) const;
+ LLVM_ABI bool isBranch(const MCInst &Inst) const;
+ LLVM_ABI bool isIndirectBranch(const MCInst &Inst) const;
+ LLVM_ABI bool isReturn(const MCInst &Inst) const;
+
+ LLVM_ABI bool mayLoad(const MCInst &Inst) const;
+ LLVM_ABI bool mayStore(const MCInst &Inst) const;
+
+ LLVM_ABI bool mayModifyRegister(const MCInst &Inst, MCRegister Reg) const;
+
+ virtual ~MCLFIRewriter() = default;
+ virtual bool rewriteInst(const MCInst &Inst, MCStreamer &Out,
+ const MCSubtargetInfo &STI) = 0;
+
+ // Called when a label is emitted. Used for optimizations that require
+ // information about jump targets, such as guard elimination.
+ virtual void onLabel(const MCSymbol *Symbol) {}
+};
+
+} // namespace llvm
+#endif
diff --git a/llvm/include/llvm/MC/MCParser/MCAsmParserExtension.h b/llvm/include/llvm/MC/MCParser/MCAsmParserExtension.h
index 66fd28827065b..eb9a995c0a2be 100644
--- a/llvm/include/llvm/MC/MCParser/MCAsmParserExtension.h
+++ b/llvm/include/llvm/MC/MCParser/MCAsmParserExtension.h
@@ -11,6 +11,7 @@
#include "llvm/ADT/STLFunctionalExtras.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/MC/MCLFIRewriter.h"
#include "llvm/MC/MCParser/MCAsmParser.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/SMLoc.h"
@@ -120,13 +121,14 @@ class LLVM_ABI MCAsmParserExtension {
/// @}
};
-MCAsmParserExtension *createDarwinAsmParser();
-MCAsmParserExtension *createELFAsmParser();
-MCAsmParserExtension *createCOFFAsmParser();
-MCAsmParserExtension *createCOFFMasmParser();
-MCAsmParserExtension *createGOFFAsmParser();
-MCAsmParserExtension *createXCOFFAsmParser();
-MCAsmParserExtension *createWasmAsmParser();
+LLVM_ABI MCAsmParserExtension *createDarwinAsmParser();
+LLVM_ABI MCAsmParserExtension *createELFAsmParser();
+LLVM_ABI MCAsmParserExtension *createCOFFAsmParser();
+LLVM_ABI MCAsmParserExtension *createCOFFMasmParser();
+LLVM_ABI MCAsmParserExtension *createGOFFAsmParser();
+LLVM_ABI MCAsmParserExtension *createXCOFFAsmParser();
+LLVM_ABI MCAsmParserExtension *createWasmAsmParser();
+LLVM_ABI MCAsmParserExtension *createLFIAsmParser(MCLFIRewriter *Exp);
} // end namespace llvm
diff --git a/llvm/include/llvm/MC/MCStreamer.h b/llvm/include/llvm/MC/MCStreamer.h
index a60a3dd21859f..339d10bd2fc30 100644
--- a/llvm/include/llvm/MC/MCStreamer.h
+++ b/llvm/include/llvm/MC/MCStreamer.h
@@ -19,6 +19,7 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/MC/MCDirectives.h"
#include "llvm/MC/MCDwarf.h"
+#include "llvm/MC/MCLFIRewriter.h"
#include "llvm/MC/MCLinkerOptimizationHint.h"
#include "llvm/MC/MCPseudoProbe.h"
#include "llvm/MC/MCSection.h"
@@ -291,6 +292,8 @@ class LLVM_ABI MCStreamer {
/// Returns true if the .cv_loc directive is in the right section.
bool checkCVLocSection(unsigned FuncId, unsigned FileNo, SMLoc Loc);
+ std::unique_ptr<MCLFIRewriter> LFIRewriter;
+
public:
MCStreamer(const MCStreamer &) = delete;
MCStreamer &operator=(const MCStreamer &) = delete;
@@ -308,6 +311,10 @@ class LLVM_ABI MCStreamer {
return StartTokLocPtr ? *StartTokLocPtr : SMLoc();
}
+ void setLFIRewriter(MCLFIRewriter *Exp) { LFIRewriter.reset(Exp); }
+
+ MCLFIRewriter *getLFIRewriter() { return LFIRewriter.get(); }
+
/// State management
///
virtual void reset();
diff --git a/llvm/include/llvm/MC/TargetRegistry.h b/llvm/include/llvm/MC/TargetRegistry.h
index 4451dfa72a5f4..46c4076ba4aeb 100644
--- a/llvm/include/llvm/MC/TargetRegistry.h
+++ b/llvm/include/llvm/MC/TargetRegistry.h
@@ -46,6 +46,7 @@ class MCDisassembler;
class MCInstPrinter;
class MCInstrAnalysis;
class MCInstrInfo;
+class MCLFIRewriter;
class MCObjectWriter;
class MCRegisterInfo;
class MCRelocationInfo;
@@ -237,6 +238,11 @@ class Target {
mca::InstrumentManager *(*)(const MCSubtargetInfo &STI,
const MCInstrInfo &MCII);
+ using MCLFIRewriterCtorTy =
+ MCLFIRewriter *(*)(MCStreamer & S,
+ std::unique_ptr<MCRegisterInfo> &&RegInfo,
+ std::unique_ptr<MCInstrInfo> &&InstInfo);
+
private:
/// Next - The next registered target in the linked list, maintained by the
/// TargetRegistry.
@@ -351,6 +357,10 @@ class Target {
/// InstrumentManager, if registered (default = nullptr).
InstrumentManagerCtorTy InstrumentManagerCtorFn = nullptr;
+ // MCLFIRewriterCtorFn - Construction function for this target's
+ // MCLFIRewriter, if registered (default = nullptr).
+ MCLFIRewriterCtorTy MCLFIRewriterCtorFn = nullptr;
+
public:
Target() = default;
@@ -566,6 +576,13 @@ class Target {
return nullptr;
}
+ void createMCLFIRewriter(MCStreamer &S,
+ std::unique_ptr<MCRegisterInfo> &&RegInfo,
+ std::unique_ptr<MCInstrInfo> &&InstInfo) const {
+ if (MCLFIRewriterCtorFn)
+ MCLFIRewriterCtorFn(S, std::move(RegInfo), std::move(InstInfo));
+ }
+
/// createMCRelocationInfo - Create a target specific MCRelocationInfo.
///
/// \param TT The target triple.
@@ -1021,6 +1038,10 @@ struct TargetRegistry {
T.InstrumentManagerCtorFn = Fn;
}
+ static void RegisterMCLFIRewriter(Target &T, Target::MCLFIRewriterCtorTy Fn) {
+ T.MCLFIRewriterCtorFn = Fn;
+ }
+
/// @}
};
diff --git a/llvm/lib/MC/CMakeLists.txt b/llvm/lib/MC/CMakeLists.txt
index 1388f130bb806..7a9e26af415c6 100644
--- a/llvm/lib/MC/CMakeLists.txt
+++ b/llvm/lib/MC/CMakeLists.txt
@@ -31,6 +31,8 @@ add_llvm_component_library(LLVMMC
MCInstrAnalysis.cpp
MCInstrDesc.cpp
MCInstrInfo.cpp
+ MCLFI.cpp
+ MCLFIRewriter.cpp
MCLabel.cpp
MCLinkerOptimizationHint.cpp
MCMachOStreamer.cpp
diff --git a/llvm/lib/MC/MCAsmStreamer.cpp b/llvm/lib/MC/MCAsmStreamer.cpp
index d9a22bc2716fd..6e9dc5d11822d 100644
--- a/llvm/lib/MC/MCAsmStreamer.cpp
+++ b/llvm/lib/MC/MCAsmStreamer.cpp
@@ -19,6 +19,7 @@
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCInstPrinter.h"
+#include "llvm/MC/MCLFIRewriter.h"
#include "llvm/MC/MCObjectFileInfo.h"
#include "llvm/MC/MCObjectWriter.h"
#include "llvm/MC/MCPseudoProbe.h"
@@ -2494,6 +2495,10 @@ void MCAsmStreamer::AddEncodingComment(const MCInst &Inst,
void MCAsmStreamer::emitInstruction(const MCInst &Inst,
const MCSubtargetInfo &STI) {
+ if (LFIRewriter && LFIRewriter->isEnabled() &&
+ LFIRewriter->rewriteInst(Inst, *this, STI))
+ return;
+
if (CurFrag) {
MCSection *Sec = getCurrentSectionOnly();
Sec->setHasInstructions(true);
diff --git a/llvm/lib/MC/MCLFI.cpp b/llvm/lib/MC/MCLFI.cpp
new file mode 100644
index 0000000000000..6082edac1a781
--- /dev/null
+++ b/llvm/lib/MC/MCLFI.cpp
@@ -0,0 +1,75 @@
+//===- lib/MC/MCLFI.cpp - LFI-specific MC implementation ------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+// This file was written by the LFI and Native Client authors.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/MC/MCLFI.h"
+#include "llvm/BinaryFormat/ELF.h"
+#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCLFIRewriter.h"
+#include "llvm/MC/MCSectionELF.h"
+#include "llvm/MC/MCStreamer.h"
+#include "llvm/MC/TargetRegistry.h"
+#include "llvm/Support/Alignment.h"
+#include "llvm/TargetParser/Triple.h"
+
+static const char NoteNamespace[] = "LFI";
+
+namespace llvm {
+
+cl::opt<bool> FlagEnableRewriting("lfi-enable-rewriter",
+ cl::desc("Don't enable rewriting for LFI."),
+ cl::init(true));
+
+void initializeLFIMCStreamer(MCStreamer &Streamer, MCContext &Ctx,
+ const Triple &TheTriple) {
+ assert(TheTriple.isLFI());
+ const char *NoteName;
+ const char *NoteArch;
+ switch (TheTriple.getArch()) {
+ case Triple::aarch64:
+ NoteName = ".note.LFI.ABI.aarch64";
+ NoteArch = "aarch64";
+ break;
+ default:
+ report_fatal_error("Unsupported architecture for LFI");
+ }
+
+ std::string Error; // empty
+ const Target *TheTarget = TargetRegistry::lookupTarget(TheTriple, Error);
+
+ // Create the Target specific MCLFIRewriter.
+ assert(TheTarget != nullptr);
+ if (FlagEnableRewriting) {
+ TheTarget->createMCLFIRewriter(
+ Streamer,
+ std::unique_ptr<MCRegisterInfo>(TheTarget->createMCRegInfo(TheTriple)),
+ std::unique_ptr<MCInstrInfo>(TheTarget->createMCInstrInfo()));
+ }
+
+ // Emit an ELF Note section in its own COMDAT group which identifies LFI
+ // object files.
+ MCSectionELF *Note = Ctx.getELFSection(NoteName, ELF::SHT_NOTE,
+ ELF::SHF_ALLOC | ELF::SHF_GROUP, 0,
+ NoteName, /*IsComdat=*/true);
+
+ Streamer.pushSection();
+ Streamer.switchSection(Note);
+ Streamer.emitIntValue(strlen(NoteNamespace) + 1, 4);
+ Streamer.emitIntValue(strlen(NoteArch) + 1, 4);
+ Streamer.emitIntValue(ELF::NT_VERSION, 4);
+ Streamer.emitBytes(NoteNamespace);
+ Streamer.emitIntValue(0, 1); // NUL terminator
+ Streamer.emitValueToAlignment(Align(4));
+ Streamer.emitBytes(NoteArch);
+ Streamer.emitIntValue(0, 1); // NUL terminator
+ Streamer.emitValueToAlignment(Align(4));
+ Streamer.popSection();
+}
+
+} // namespace llvm
diff --git a/llvm/lib/MC/MCLFIRewriter.cpp b/llvm/lib/MC/MCLFIRewriter.cpp
new file mode 100644
index 0000000000000..5295a5c3e3771
--- /dev/null
+++ b/llvm/lib/MC/MCLFIRewriter.cpp
@@ -0,0 +1,61 @@
+//===- MCLFIRewriter.cpp ----------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+// This file was written by the LFI and Native Client authors.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the MCLFIRewriter class. This is a base
+// class that encapsulates the rewriting logic for MCInsts.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/MC/MCLFIRewriter.h"
+#include "llvm/MC/MCInst.h"
+#include "llvm/MC/MCInstrInfo.h"
+#include "llvm/MC/MCRegisterInfo.h"
+
+namespace llvm {
+
+void MCLFIRewriter::error(const MCInst &Inst, const char Msg[]) {
+ Ctx.reportError(Inst.getLoc(), Msg);
+}
+
+void MCLFIRewriter::disable() { Enabled = false; }
+
+void MCLFIRewriter::enable() { Enabled = true; }
+
+bool MCLFIRewriter::isEnabled() { return Enabled; }
+
+bool MCLFIRewriter::isCall(const MCInst &Inst) const {
+ return InstInfo->get(Inst.getOpcode()).isCall();
+}
+
+bool MCLFIRewriter::isBranch(const MCInst &Inst) const {
+ return InstInfo->get(Inst.getOpcode()).isBranch();
+}
+
+bool MCLFIRewriter::isIndirectBranch(const MCInst &Inst) const {
+ return InstInfo->get(Inst.getOpcode()).isIndirectBranch();
+}
+
+bool MCLFIRewriter::isReturn(const MCInst &Inst) const {
+ return InstInfo->get(Inst.getOpcode()).isReturn();
+}
+
+bool MCLFIRewriter::mayLoad(const MCInst &Inst) const {
+ return InstInfo->get(Inst.getOpcode()).mayLoad();
+}
+
+bool MCLFIRewriter::mayStore(const MCInst &Inst) const {
+ return InstInfo->get(Inst.getOpcode()).mayStore();
+}
+
+bool MCLFIRewriter::mayModifyRegister(const MCInst &Inst,
+ MCRegister Reg) const {
+ return InstInfo->get(Inst.getOpcode()).hasDefOfPhysReg(Inst, Reg, *RegInfo);
+}
+} // namespace llvm
diff --git a/llvm/lib/MC/MCObjectStreamer.cpp b/llvm/lib/MC/MCObjectStreamer.cpp
index 453d4d20d9727..f9d2bfc73069a 100644
--- a/llvm/lib/MC/MCObjectStreamer.cpp
+++ b/llvm/lib/MC/MCObjectStreamer.cpp
@@ -15,6 +15,7 @@
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCDwarf.h"
#include "llvm/MC/MCExpr.h"
+#include "llvm/MC/MCLFIRewriter.h"
#include "llvm/MC/MCObjectFileInfo.h"
#include "llvm/MC/MCObjectWriter.h"
#include "llvm/MC/MCSFrame.h"
@@ -398,6 +399,10 @@ bool MCObjectStreamer::mayHaveInstructions(MCSection &Sec) const {
void MCObjectStreamer::emitInstruction(const MCInst &Inst,
const MCSubtargetInfo &STI) {
+ if (LFIRewriter && LFIRewriter->isEnabled() &&
+ LFIRewriter->rewriteInst(Inst, *this, STI))
+ return;
+
MCStreamer::emitInstruction(Inst, STI);
MCSection *Sec = getCurrentSectionOnly();
diff --git a/llvm/lib/MC/MCParser/AsmParser.cpp b/llvm/lib/MC/MCParser/AsmParser.cpp
index 3277994701b78..fdce7999f492e 100644
--- a/llvm/lib/MC/MCParser/AsmParser.cpp
+++ b/llvm/lib/MC/MCParser/AsmParser.cpp
@@ -120,6 +120,7 @@ class AsmParser : public MCAsmParser {
SourceMgr::DiagHandlerTy SavedDiagHandler;
void *SavedDiagContext;
std::unique_ptr<MCAsmParserExtension> PlatformParser;
+ std::unique_ptr<MCAsmParserExtension> LFIParser;
SMLoc StartTokLoc;
std::optional<SMLoc> CFIStartProcLoc;
@@ -745,8 +746,8 @@ extern cl::opt<unsigned> AsmMacroMaxNestingDepth;
AsmParser::AsmParser(SourceMgr &SM, MCContext &Ctx, MCStreamer &Out,
const MCAsmInfo &MAI, unsigned CB = 0)
- : MCAsmParser(Ctx, Out, SM, MAI), CurBuffer(CB ? CB : SM.getMainFileID()),
- MacrosEnabledFlag(true) {
+ : MCAsmParser(Ctx, Out, SM, MAI), LFIParser(nullptr),
+ CurBuffer(CB ? CB : SM.getMainFileID()), MacrosEnabledFlag(true) {
HadError = false;
// Save the old handler.
SavedDiagHandler = SrcMgr.getDiagHandler();
@@ -788,6 +789,10 @@ AsmParser::AsmParser(SourceMgr &SM, MCContext &Ctx, MCStreamer &Out,
}
PlatformParser->Initialize(*this);
+ if (Out.getLFIRewriter()) {
+ LFIParser.reset(createLFIAsmParser(Out.getLFIRewriter()));
+ LFIParser->Initialize(*this);
+ }
initializeDirectiveKindMap();
initializeCVDefRangeTypeMap();
}
diff --git a/llvm/lib/MC/MCParser/CMakeLists.txt b/llvm/lib/MC/MCParser/CMakeLists.txt
index 008a50e9da660..c911874fc6540 100644
--- a/llvm/lib/MC/MCParser/CMakeLists.txt
+++ b/llvm/lib/MC/MCParser/CMakeLists.txt
@@ -6,6 +6,7 @@ add_llvm_component_library(LLVMMCParser
GOFFAsmParser.cpp
DarwinAsmParser.cpp
ELFAsmParser.cpp
+ LFIAsmParser.cpp
MCAsmParser.cpp
MCAsmParserExtension.cpp
MCTargetAsmParser.cpp
diff --git a/llvm/lib/MC/MCParser/LFIAsmParser.cpp b/llvm/lib/MC/MCParser/LFIAsmParser.cpp
new file mode 100644
index 0000000000000..4601052e0d65f
--- /dev/null
+++ b/llvm/lib/MC/MCParser/LFIAsmParser.cpp
@@ -0,0 +1,69 @@
+//===- LFIAsmParser.cpp - LFI Assembly Parser -----------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file was written by the LFI and Native Client authors.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/MC/MCLFIRewriter.h"
+#include "llvm/MC/MCParser/MCAsmParserExtension.h"
+#include "llvm/MC/MCStreamer.h"
+
+using namespace llvm;
+
+class LFIAsmParser : public MCAsmParserExtension {
+ MCLFIRewriter *Rewriter;
+ template <bool (LFIAsmParser::*HandlerMethod)(StringRef, SMLoc)>
+ void addDirectiveHandler(StringRef Directive) {
+ MCAsmParser::ExtensionDirectiveHandler Handler =
+ std::make_pair(this, HandleDirective<LFIAsmParser, HandlerMethod>);
+
+ getParser().addDirectiveHandler(Directive, Handler);
+ }
+
+public:
+ LFIAsmParser(MCLFIRewriter *Exp) : Rewriter(Exp) {}
+ void Initialize(MCAsmParser &Parser) override {
+ // Call the base implementation.
+ MCAsmParserExtension::Initialize(Parser);
+ addDirectiveHandler<&LFIAsmParser::parseRewriteDisable>(
+ ".lfi_rewrite_disable");
+ addDirectiveHandler<&LFIAsmParser::parseRewriteEnable>(
+ ".lfi_rewrite_enable");
+ }
+
+ /// ::= {.lfi_rewrite_disable}
+ bool parseRewriteDisable(StringRef Directive, SMLoc Loc) {
+ getParser().checkForValidSection();
+ if (getLexer().isNot(AsmToken::EndOfStatement))
+ return TokError("unexpected token");
+ Lex();
+
+ Rewriter->disable();
+
+ return false;
+ }
+
+ /// ::= {.lfi_rewrite_enable}
+ bool parseRewriteEnable(StringRef Directive, SMLoc Loc) {
+ getParser().checkForValidSection();
+ if (getLexer().isNot(AsmToken::EndOfStatement))
+ return TokError("unexpected token");
+ Lex();
+
+ Rewriter->enable();
+
+ return false;
+ }
+};
+
+namespace llvm {
+MCAsmParserExtension *createLFIAsmParser(MCLFIRewriter *Exp) {
+ return new LFIAsmParser(Exp);
+}
+} // namespace llvm
diff --git a/llvm/lib/MC/MCStreamer.cpp b/llvm/lib/MC/MCStreamer.cpp
index 5c7ebcf6b66e4..33c9a05bec114 100644
--- a/llvm/lib/MC/MCStreamer.cpp
+++ b/llvm/lib/MC/MCStreamer.cpp
@@ -399,6 +399,9 @@ void MCStreamer::emitLabel(MCSymbol *Symbol, SMLoc Loc) {
Symbol->setFragment(&getCurrentSectionOnly()->getDummyFragment());
+ if (LFIRewriter)
+ LFIRewriter->onLabel(Symbol);
+
MCTargetStreamer *TS = getTargetStreamer();
if (TS)
TS->emitLabel(Symbol);
diff --git a/llvm/tools/llvm-mc/llvm-mc.cpp b/llvm/tools/llvm-mc/llvm-mc.cpp
index baf3b5536138b..b1f73433b1bb3 100644
--- a/llvm/tools/llvm-mc/llvm-mc.cpp
+++ b/llvm/tools/llvm-mc/llvm-mc.cpp
@@ -21,6 +21,7 @@
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCInstPrinter.h"
#include "llvm/MC/MCInstrInfo.h"
+#include "llvm/MC/MCLFI.h"
#include "llvm/MC/MCObjectFileInfo.h"
#include "llvm/MC/MCObjectWriter.h"
#include "llvm/MC/MCParser/AsmLexer.h"
@@ -626,6 +627,12 @@ int main(int argc, char **argv) {
Str.reset(TheTarget->createAsmStreamer(Ctx, std::move(FOut), std::move(IP),
std::move(CE), std::move(MAB)));
+ Triple T(TripleName);
+ if (T.isLFI()) {
+ Str->initSections(NoExecStack, *STI);
+ initializeLFIMCStreamer(*Str.get(), Ctx, T);
+ }
+
} else if (FileType == OFT_Null) {
Str.reset(TheTarget->createNullStreamer(Ctx));
} else {
@@ -646,6 +653,13 @@ int main(int argc, char **argv) {
if (NoExecStack)
Str->switchSection(
Ctx.getAsmInfo()->getStackSection(Ctx, /*Exec=*/false));
+
+ Triple T(TripleName);
+ if (T.isLFI()) {
+ Str->initSections(NoExecStack, *STI);
+ initializeLFIMCStreamer(*Str.get(), Ctx, T);
+ }
+
Str->emitVersionForTarget(TheTriple, VersionTuple(), nullptr,
VersionTuple());
}
>From 32ea5c00d8823844002cb01626d7280d6670141b Mon Sep 17 00:00:00 2001
From: Zachary Yedidia <zyedidia at gmail.com>
Date: Mon, 26 Jan 2026 17:18:48 -0500
Subject: [PATCH 2/8] [LFI] Small fixes based on code review
- Use `unique_ptr` for `setLFIRewriter`.
- Fix `lfi-enable-rewriter` flag description.
- No need to explicitly initialize LFIRewriter to null.
---
llvm/include/llvm/MC/MCStreamer.h | 4 +++-
llvm/lib/MC/MCLFI.cpp | 2 +-
llvm/lib/MC/MCParser/AsmParser.cpp | 4 ++--
llvm/tools/llvm-mc/llvm-mc.cpp | 1 -
4 files changed, 6 insertions(+), 5 deletions(-)
diff --git a/llvm/include/llvm/MC/MCStreamer.h b/llvm/include/llvm/MC/MCStreamer.h
index 339d10bd2fc30..9c0386dbacdad 100644
--- a/llvm/include/llvm/MC/MCStreamer.h
+++ b/llvm/include/llvm/MC/MCStreamer.h
@@ -311,7 +311,9 @@ class LLVM_ABI MCStreamer {
return StartTokLocPtr ? *StartTokLocPtr : SMLoc();
}
- void setLFIRewriter(MCLFIRewriter *Exp) { LFIRewriter.reset(Exp); }
+ void setLFIRewriter(std::unique_ptr<MCLFIRewriter> Rewriter) {
+ LFIRewriter = std::move(Rewriter);
+ }
MCLFIRewriter *getLFIRewriter() { return LFIRewriter.get(); }
diff --git a/llvm/lib/MC/MCLFI.cpp b/llvm/lib/MC/MCLFI.cpp
index 6082edac1a781..af89d9bf3dc85 100644
--- a/llvm/lib/MC/MCLFI.cpp
+++ b/llvm/lib/MC/MCLFI.cpp
@@ -23,7 +23,7 @@ static const char NoteNamespace[] = "LFI";
namespace llvm {
cl::opt<bool> FlagEnableRewriting("lfi-enable-rewriter",
- cl::desc("Don't enable rewriting for LFI."),
+ cl::desc("Enable rewriting for LFI."),
cl::init(true));
void initializeLFIMCStreamer(MCStreamer &Streamer, MCContext &Ctx,
diff --git a/llvm/lib/MC/MCParser/AsmParser.cpp b/llvm/lib/MC/MCParser/AsmParser.cpp
index fdce7999f492e..3452708bcec8a 100644
--- a/llvm/lib/MC/MCParser/AsmParser.cpp
+++ b/llvm/lib/MC/MCParser/AsmParser.cpp
@@ -746,8 +746,8 @@ extern cl::opt<unsigned> AsmMacroMaxNestingDepth;
AsmParser::AsmParser(SourceMgr &SM, MCContext &Ctx, MCStreamer &Out,
const MCAsmInfo &MAI, unsigned CB = 0)
- : MCAsmParser(Ctx, Out, SM, MAI), LFIParser(nullptr),
- CurBuffer(CB ? CB : SM.getMainFileID()), MacrosEnabledFlag(true) {
+ : MCAsmParser(Ctx, Out, SM, MAI), CurBuffer(CB ? CB : SM.getMainFileID()),
+ MacrosEnabledFlag(true) {
HadError = false;
// Save the old handler.
SavedDiagHandler = SrcMgr.getDiagHandler();
diff --git a/llvm/tools/llvm-mc/llvm-mc.cpp b/llvm/tools/llvm-mc/llvm-mc.cpp
index b1f73433b1bb3..6542612b5768c 100644
--- a/llvm/tools/llvm-mc/llvm-mc.cpp
+++ b/llvm/tools/llvm-mc/llvm-mc.cpp
@@ -632,7 +632,6 @@ int main(int argc, char **argv) {
Str->initSections(NoExecStack, *STI);
initializeLFIMCStreamer(*Str.get(), Ctx, T);
}
-
} else if (FileType == OFT_Null) {
Str.reset(TheTarget->createNullStreamer(Ctx));
} else {
>From 56c05d533d2a1f1355b7a96daeb6eab73517649c Mon Sep 17 00:00:00 2001
From: Zachary Yedidia <zyedidia at gmail.com>
Date: Mon, 26 Jan 2026 17:28:22 -0500
Subject: [PATCH 3/8] [LFI] initializeMCLFIStreamer in createMCObjectStreamer
- Still needs manual initialization for use with createAsmStreamer.
---
clang/tools/driver/cc1as_main.cpp | 3 ---
llvm/lib/MC/TargetRegistry.cpp | 3 +++
llvm/tools/llvm-mc/llvm-mc.cpp | 6 ------
3 files changed, 3 insertions(+), 9 deletions(-)
diff --git a/clang/tools/driver/cc1as_main.cpp b/clang/tools/driver/cc1as_main.cpp
index 6cbccbc3d7408..ccc48a77891d7 100644
--- a/clang/tools/driver/cc1as_main.cpp
+++ b/clang/tools/driver/cc1as_main.cpp
@@ -28,7 +28,6 @@
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCInstPrinter.h"
#include "llvm/MC/MCInstrInfo.h"
-#include "llvm/MC/MCLFI.h"
#include "llvm/MC/MCObjectFileInfo.h"
#include "llvm/MC/MCObjectWriter.h"
#include "llvm/MC/MCParser/MCAsmParser.h"
@@ -594,8 +593,6 @@ static bool ExecuteAssemblerImpl(AssemblerInvocation &Opts,
Triple T(Opts.Triple);
Str.reset(TheTarget->createMCObjectStreamer(
T, Ctx, std::move(MAB), std::move(OW), std::move(CE), *STI));
- if (T.isLFI())
- initializeLFIMCStreamer(*Str.get(), Ctx, T);
if (T.isOSBinFormatMachO() && T.isOSDarwin()) {
Triple *TVT = Opts.DarwinTargetVariantTriple
? &*Opts.DarwinTargetVariantTriple
diff --git a/llvm/lib/MC/TargetRegistry.cpp b/llvm/lib/MC/TargetRegistry.cpp
index 9263dda65a8b0..db743ef9bdcb6 100644
--- a/llvm/lib/MC/TargetRegistry.cpp
+++ b/llvm/lib/MC/TargetRegistry.cpp
@@ -13,6 +13,7 @@
#include "llvm/MC/MCCodeEmitter.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCInstPrinter.h"
+#include "llvm/MC/MCLFI.h"
#include "llvm/MC/MCObjectStreamer.h"
#include "llvm/MC/MCObjectWriter.h"
#include "llvm/Support/raw_ostream.h"
@@ -76,6 +77,8 @@ MCStreamer *Target::createMCObjectStreamer(
}
if (ObjectTargetStreamerCtorFn)
ObjectTargetStreamerCtorFn(*S, STI);
+ if (T.isLFI())
+ initializeLFIMCStreamer(*S, Ctx, T);
return S;
}
diff --git a/llvm/tools/llvm-mc/llvm-mc.cpp b/llvm/tools/llvm-mc/llvm-mc.cpp
index 6542612b5768c..ea2c8c3b6427c 100644
--- a/llvm/tools/llvm-mc/llvm-mc.cpp
+++ b/llvm/tools/llvm-mc/llvm-mc.cpp
@@ -653,12 +653,6 @@ int main(int argc, char **argv) {
Str->switchSection(
Ctx.getAsmInfo()->getStackSection(Ctx, /*Exec=*/false));
- Triple T(TripleName);
- if (T.isLFI()) {
- Str->initSections(NoExecStack, *STI);
- initializeLFIMCStreamer(*Str.get(), Ctx, T);
- }
-
Str->emitVersionForTarget(TheTriple, VersionTuple(), nullptr,
VersionTuple());
}
>From 99cb10a0370044e469be5874f9cfe4bd10b3acd0 Mon Sep 17 00:00:00 2001
From: Zachary Yedidia <zyedidia at gmail.com>
Date: Tue, 27 Jan 2026 13:19:48 -0500
Subject: [PATCH 4/8] [LFI] Rely on rewriteInst to track Enabled
---
llvm/include/llvm/MC/MCLFIRewriter.h | 3 +--
llvm/lib/MC/MCAsmStreamer.cpp | 3 +--
llvm/lib/MC/MCLFIRewriter.cpp | 2 --
llvm/lib/MC/MCObjectStreamer.cpp | 3 +--
4 files changed, 3 insertions(+), 8 deletions(-)
diff --git a/llvm/include/llvm/MC/MCLFIRewriter.h b/llvm/include/llvm/MC/MCLFIRewriter.h
index 06e1d03b21efe..3736eeac2c10d 100644
--- a/llvm/include/llvm/MC/MCLFIRewriter.h
+++ b/llvm/include/llvm/MC/MCLFIRewriter.h
@@ -30,9 +30,9 @@ class MCSymbol;
class MCLFIRewriter {
private:
MCContext &Ctx;
- bool Enabled = true;
protected:
+ bool Enabled = true;
std::unique_ptr<MCInstrInfo> InstInfo;
std::unique_ptr<MCRegisterInfo> RegInfo;
@@ -45,7 +45,6 @@ class MCLFIRewriter {
LLVM_ABI void disable();
LLVM_ABI void enable();
- LLVM_ABI bool isEnabled();
LLVM_ABI bool isCall(const MCInst &Inst) const;
LLVM_ABI bool isBranch(const MCInst &Inst) const;
diff --git a/llvm/lib/MC/MCAsmStreamer.cpp b/llvm/lib/MC/MCAsmStreamer.cpp
index 6e9dc5d11822d..1a50ae43cd9c9 100644
--- a/llvm/lib/MC/MCAsmStreamer.cpp
+++ b/llvm/lib/MC/MCAsmStreamer.cpp
@@ -2495,8 +2495,7 @@ void MCAsmStreamer::AddEncodingComment(const MCInst &Inst,
void MCAsmStreamer::emitInstruction(const MCInst &Inst,
const MCSubtargetInfo &STI) {
- if (LFIRewriter && LFIRewriter->isEnabled() &&
- LFIRewriter->rewriteInst(Inst, *this, STI))
+ if (LFIRewriter && LFIRewriter->rewriteInst(Inst, *this, STI))
return;
if (CurFrag) {
diff --git a/llvm/lib/MC/MCLFIRewriter.cpp b/llvm/lib/MC/MCLFIRewriter.cpp
index 5295a5c3e3771..261afe1db23ba 100644
--- a/llvm/lib/MC/MCLFIRewriter.cpp
+++ b/llvm/lib/MC/MCLFIRewriter.cpp
@@ -28,8 +28,6 @@ void MCLFIRewriter::disable() { Enabled = false; }
void MCLFIRewriter::enable() { Enabled = true; }
-bool MCLFIRewriter::isEnabled() { return Enabled; }
-
bool MCLFIRewriter::isCall(const MCInst &Inst) const {
return InstInfo->get(Inst.getOpcode()).isCall();
}
diff --git a/llvm/lib/MC/MCObjectStreamer.cpp b/llvm/lib/MC/MCObjectStreamer.cpp
index f9d2bfc73069a..58aa7945d7393 100644
--- a/llvm/lib/MC/MCObjectStreamer.cpp
+++ b/llvm/lib/MC/MCObjectStreamer.cpp
@@ -399,8 +399,7 @@ bool MCObjectStreamer::mayHaveInstructions(MCSection &Sec) const {
void MCObjectStreamer::emitInstruction(const MCInst &Inst,
const MCSubtargetInfo &STI) {
- if (LFIRewriter && LFIRewriter->isEnabled() &&
- LFIRewriter->rewriteInst(Inst, *this, STI))
+ if (LFIRewriter && LFIRewriter->rewriteInst(Inst, *this, STI))
return;
MCStreamer::emitInstruction(Inst, STI);
>From 7a9a71e3a35f811dc37121069757dee38a83f10d Mon Sep 17 00:00:00 2001
From: Zachary Yedidia <zyedidia at gmail.com>
Date: Wed, 28 Jan 2026 13:30:29 -0500
Subject: [PATCH 5/8] [LFI] Some additional minor cleanup
We could go further and remove the helpers in MCLFIRewriter.cpp entirely
and just use InstrDesc directly from inside each rewriter.
---
llvm/include/llvm/MC/MCLFI.h | 2 --
llvm/include/llvm/MC/MCLFIRewriter.h | 6 ++----
llvm/lib/MC/MCLFI.cpp | 4 +---
llvm/lib/MC/MCLFIRewriter.cpp | 6 ------
llvm/lib/MC/MCParser/LFIAsmParser.cpp | 4 ----
llvm/tools/llvm-mc/llvm-mc.cpp | 1 -
6 files changed, 3 insertions(+), 20 deletions(-)
diff --git a/llvm/include/llvm/MC/MCLFI.h b/llvm/include/llvm/MC/MCLFI.h
index 6598453952642..269fe9dd9911d 100644
--- a/llvm/include/llvm/MC/MCLFI.h
+++ b/llvm/include/llvm/MC/MCLFI.h
@@ -4,8 +4,6 @@
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
-// This file was written by the LFI and Native Client authors.
-//
//===----------------------------------------------------------------------===//
#include "llvm/Support/CommandLine.h"
diff --git a/llvm/include/llvm/MC/MCLFIRewriter.h b/llvm/include/llvm/MC/MCLFIRewriter.h
index 3736eeac2c10d..bf90c761942fa 100644
--- a/llvm/include/llvm/MC/MCLFIRewriter.h
+++ b/llvm/include/llvm/MC/MCLFIRewriter.h
@@ -4,8 +4,6 @@
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
-// This file was written by the LFI and Native Client authors.
-//
//===----------------------------------------------------------------------===//
//
// This file declares the MCLFIRewriter class. This is an abstract
@@ -43,8 +41,8 @@ class MCLFIRewriter {
LLVM_ABI void error(const MCInst &Inst, const char Msg[]);
- LLVM_ABI void disable();
- LLVM_ABI void enable();
+ void disable() { Enabled = false; }
+ void enable() { Enabled = true; }
LLVM_ABI bool isCall(const MCInst &Inst) const;
LLVM_ABI bool isBranch(const MCInst &Inst) const;
diff --git a/llvm/lib/MC/MCLFI.cpp b/llvm/lib/MC/MCLFI.cpp
index af89d9bf3dc85..0a7f61bdaf05a 100644
--- a/llvm/lib/MC/MCLFI.cpp
+++ b/llvm/lib/MC/MCLFI.cpp
@@ -4,8 +4,6 @@
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
-// This file was written by the LFI and Native Client authors.
-//
//===----------------------------------------------------------------------===//
#include "llvm/MC/MCLFI.h"
@@ -37,7 +35,7 @@ void initializeLFIMCStreamer(MCStreamer &Streamer, MCContext &Ctx,
NoteArch = "aarch64";
break;
default:
- report_fatal_error("Unsupported architecture for LFI");
+ reportFatalUsageError("Unsupported architecture for LFI");
}
std::string Error; // empty
diff --git a/llvm/lib/MC/MCLFIRewriter.cpp b/llvm/lib/MC/MCLFIRewriter.cpp
index 261afe1db23ba..c7f551fa22148 100644
--- a/llvm/lib/MC/MCLFIRewriter.cpp
+++ b/llvm/lib/MC/MCLFIRewriter.cpp
@@ -4,8 +4,6 @@
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
-// This file was written by the LFI and Native Client authors.
-//
//===----------------------------------------------------------------------===//
//
// This file implements the MCLFIRewriter class. This is a base
@@ -24,10 +22,6 @@ void MCLFIRewriter::error(const MCInst &Inst, const char Msg[]) {
Ctx.reportError(Inst.getLoc(), Msg);
}
-void MCLFIRewriter::disable() { Enabled = false; }
-
-void MCLFIRewriter::enable() { Enabled = true; }
-
bool MCLFIRewriter::isCall(const MCInst &Inst) const {
return InstInfo->get(Inst.getOpcode()).isCall();
}
diff --git a/llvm/lib/MC/MCParser/LFIAsmParser.cpp b/llvm/lib/MC/MCParser/LFIAsmParser.cpp
index 4601052e0d65f..887c2bc44d886 100644
--- a/llvm/lib/MC/MCParser/LFIAsmParser.cpp
+++ b/llvm/lib/MC/MCParser/LFIAsmParser.cpp
@@ -5,10 +5,6 @@
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
-//
-// This file was written by the LFI and Native Client authors.
-//
-//===----------------------------------------------------------------------===//
#include "llvm/MC/MCLFIRewriter.h"
#include "llvm/MC/MCParser/MCAsmParserExtension.h"
diff --git a/llvm/tools/llvm-mc/llvm-mc.cpp b/llvm/tools/llvm-mc/llvm-mc.cpp
index ea2c8c3b6427c..df7f813d1139e 100644
--- a/llvm/tools/llvm-mc/llvm-mc.cpp
+++ b/llvm/tools/llvm-mc/llvm-mc.cpp
@@ -652,7 +652,6 @@ int main(int argc, char **argv) {
if (NoExecStack)
Str->switchSection(
Ctx.getAsmInfo()->getStackSection(Ctx, /*Exec=*/false));
-
Str->emitVersionForTarget(TheTriple, VersionTuple(), nullptr,
VersionTuple());
}
>From 7c15a5e216f5031a56f9a652b799314917fe383d Mon Sep 17 00:00:00 2001
From: Zachary Yedidia <zyedidia at gmail.com>
Date: Thu, 19 Feb 2026 16:40:20 -0500
Subject: [PATCH 6/8] Update comment headers based on CodingStandards
---
llvm/include/llvm/MC/MCLFI.h | 7 ++++++-
llvm/include/llvm/MC/MCLFIRewriter.h | 11 ++++++-----
llvm/lib/MC/MCLFI.cpp | 7 ++++++-
llvm/lib/MC/MCLFIRewriter.cpp | 11 ++++++-----
llvm/lib/MC/MCParser/LFIAsmParser.cpp | 7 ++++++-
5 files changed, 30 insertions(+), 13 deletions(-)
diff --git a/llvm/include/llvm/MC/MCLFI.h b/llvm/include/llvm/MC/MCLFI.h
index 269fe9dd9911d..6ceeb5b5051c3 100644
--- a/llvm/include/llvm/MC/MCLFI.h
+++ b/llvm/include/llvm/MC/MCLFI.h
@@ -1,10 +1,15 @@
-//===- MCLFI.h - LFI-specific code for MC -----------------------*- C++ -*-===//
+//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
+///
+/// \file
+/// LFI-specific code for MC.
+///
+//===----------------------------------------------------------------------===//
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Compiler.h"
diff --git a/llvm/include/llvm/MC/MCLFIRewriter.h b/llvm/include/llvm/MC/MCLFIRewriter.h
index bf90c761942fa..90f8a9b0e0c09 100644
--- a/llvm/include/llvm/MC/MCLFIRewriter.h
+++ b/llvm/include/llvm/MC/MCLFIRewriter.h
@@ -1,14 +1,15 @@
-//===- llvm/MC/MCLFIRewriter.h ----------------------------------*- C++ -*-===//
+//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
-//
-// This file declares the MCLFIRewriter class. This is an abstract
-// class that encapsulates the rewriting logic for MCInsts.
-//
+///
+/// \file
+/// This file declares the MCLFIRewriter class, an abstract class that
+/// encapsulates the rewriting logic for MCInsts.
+///
//===----------------------------------------------------------------------===//
#ifndef LLVM_MC_MCLFIREWRITER_H
diff --git a/llvm/lib/MC/MCLFI.cpp b/llvm/lib/MC/MCLFI.cpp
index 0a7f61bdaf05a..0092f867a8caa 100644
--- a/llvm/lib/MC/MCLFI.cpp
+++ b/llvm/lib/MC/MCLFI.cpp
@@ -1,10 +1,15 @@
-//===- lib/MC/MCLFI.cpp - LFI-specific MC implementation ------------------===//
+//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
+///
+/// \file
+/// LFI-specific MC implementation.
+///
+//===----------------------------------------------------------------------===//
#include "llvm/MC/MCLFI.h"
#include "llvm/BinaryFormat/ELF.h"
diff --git a/llvm/lib/MC/MCLFIRewriter.cpp b/llvm/lib/MC/MCLFIRewriter.cpp
index c7f551fa22148..0ffbc02689aa2 100644
--- a/llvm/lib/MC/MCLFIRewriter.cpp
+++ b/llvm/lib/MC/MCLFIRewriter.cpp
@@ -1,14 +1,15 @@
-//===- MCLFIRewriter.cpp ----------------------------------------*- C++ -*-===//
+//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
-//
-// This file implements the MCLFIRewriter class. This is a base
-// class that encapsulates the rewriting logic for MCInsts.
-//
+///
+/// \file
+/// This file implements the MCLFIRewriter class, a base class that
+/// encapsulates the rewriting logic for MCInsts.
+///
//===----------------------------------------------------------------------===//
#include "llvm/MC/MCLFIRewriter.h"
diff --git a/llvm/lib/MC/MCParser/LFIAsmParser.cpp b/llvm/lib/MC/MCParser/LFIAsmParser.cpp
index 887c2bc44d886..138b4500c50e1 100644
--- a/llvm/lib/MC/MCParser/LFIAsmParser.cpp
+++ b/llvm/lib/MC/MCParser/LFIAsmParser.cpp
@@ -1,10 +1,15 @@
-//===- LFIAsmParser.cpp - LFI Assembly Parser -----------------------------===//
+//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
+///
+/// \file
+/// LFI assembly parser.
+///
+//===----------------------------------------------------------------------===//
#include "llvm/MC/MCLFIRewriter.h"
#include "llvm/MC/MCParser/MCAsmParserExtension.h"
>From 2b996415a7d5a42b207bb9c9fbe9f69aeb35e52a Mon Sep 17 00:00:00 2001
From: Zachary Yedidia <zyedidia at gmail.com>
Date: Thu, 19 Feb 2026 16:41:20 -0500
Subject: [PATCH 7/8] Remove LLVM_ABI annotations
These will be added as part of a separate PR.
---
.../llvm/MC/MCParser/MCAsmParserExtension.h | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/llvm/include/llvm/MC/MCParser/MCAsmParserExtension.h b/llvm/include/llvm/MC/MCParser/MCAsmParserExtension.h
index eb9a995c0a2be..a32982ea315a8 100644
--- a/llvm/include/llvm/MC/MCParser/MCAsmParserExtension.h
+++ b/llvm/include/llvm/MC/MCParser/MCAsmParserExtension.h
@@ -121,14 +121,14 @@ class LLVM_ABI MCAsmParserExtension {
/// @}
};
-LLVM_ABI MCAsmParserExtension *createDarwinAsmParser();
-LLVM_ABI MCAsmParserExtension *createELFAsmParser();
-LLVM_ABI MCAsmParserExtension *createCOFFAsmParser();
-LLVM_ABI MCAsmParserExtension *createCOFFMasmParser();
-LLVM_ABI MCAsmParserExtension *createGOFFAsmParser();
-LLVM_ABI MCAsmParserExtension *createXCOFFAsmParser();
-LLVM_ABI MCAsmParserExtension *createWasmAsmParser();
-LLVM_ABI MCAsmParserExtension *createLFIAsmParser(MCLFIRewriter *Exp);
+MCAsmParserExtension *createDarwinAsmParser();
+MCAsmParserExtension *createELFAsmParser();
+MCAsmParserExtension *createCOFFAsmParser();
+MCAsmParserExtension *createCOFFMasmParser();
+MCAsmParserExtension *createGOFFAsmParser();
+MCAsmParserExtension *createXCOFFAsmParser();
+MCAsmParserExtension *createWasmAsmParser();
+MCAsmParserExtension *createLFIAsmParser(MCLFIRewriter *Exp);
} // end namespace llvm
>From 4a27cef6b7489ed63c2c8b19453c6227f9e6de71 Mon Sep 17 00:00:00 2001
From: Zachary Yedidia <zyedidia at gmail.com>
Date: Thu, 19 Feb 2026 16:47:53 -0500
Subject: [PATCH 8/8] Document .lfi_rewrite_enable/.lfi_rewrite_disable
---
llvm/docs/LFI.rst | 27 +++++++++++++++++++++++++++
1 file changed, 27 insertions(+)
diff --git a/llvm/docs/LFI.rst b/llvm/docs/LFI.rst
index 3c1cc96b2178d..65d8b70f17e0b 100644
--- a/llvm/docs/LFI.rst
+++ b/llvm/docs/LFI.rst
@@ -398,6 +398,33 @@ In certain cases, guards may be hoisted outside of loops.
| | |
+-----------------------+-------------------------------+
+Assembler Directives
+====================
+
+The LFI assembler supports the following directives for controlling the
+rewriter.
+
+``.lfi_rewrite_disable``
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+Disables LFI assembly rewrites for all subsequent instructions, until
+``.lfi_rewrite_enable`` is used. This can be useful for hand-written assembly
+that is already safe and should not be modified by the rewriter.
+
+``.lfi_rewrite_enable``
+~~~~~~~~~~~~~~~~~~~~~~~
+
+Re-enables LFI assembly rewrites after a previous ``.lfi_rewrite_disable``.
+
+Example:
+
+.. code-block:: gas
+
+ .lfi_rewrite_disable
+ // No rewrites applied here.
+ ldr x0, [x27, w1, uxtw]
+ .lfi_rewrite_enable
+
References
++++++++++
More information about the cfe-commits
mailing list