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 <[email protected]>
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 <[email protected]>
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 <[email protected]>
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 <[email protected]>
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 <[email protected]>
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 <[email protected]>
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 <[email protected]>
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 <[email protected]>
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
 ++++++++++
 

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to