https://github.com/fzakaria created 
https://github.com/llvm/llvm-project/pull/210087

Clang never instantiated RegisterMCTargetOptionsFlags, so LLVM's machine-code 
target options (`-mllvm`) were not reachable from clang.

This made certain flags such as `-large-eh-encoding` 
(MCTargetOptions::LargeEHEncoding) impossible to set in clang.

Register the flags in the cc1 codegen path and in the integrated assembler, 
then seed MCTargetOptions before applying clang's own settings with proper 
precendence for matching flags.

Value precedence: clang's driver flags stay authoritative. The seed runs first 
and clang's flag-derived assignments overwrite whatever they cover, so -mllvm 
only contributes Absent any -mllvm flags the seed equals a default-constructed 
MCTargetOptions, so existing behavior is unchanged.

This change would supersede https://github.com/llvm/llvm-project/pull/187583

>From cfbc73adcd1d2cb5957267d60439fb353237213d Mon Sep 17 00:00:00 2001
From: Farid Zakaria <[email protected]>
Date: Thu, 16 Jul 2026 08:51:07 -0700
Subject: [PATCH] [clang] Expose MC target options through -mllvm

Clang never instantiated RegisterMCTargetOptionsFlags, so LLVM's
machine-code target options (`-mllvm`) were not reachable from clang.

This made certain flags such as `-large-eh-encoding`
(MCTargetOptions::LargeEHEncoding) impossible to set in clang.

Register the flags in the cc1 codegen path and in the
integrated assembler, then seed MCTargetOptions before applying
clang's own settings with proper precendence for matching flags.

Value precedence: clang's driver flags stay authoritative. The seed runs
first and clang's flag-derived assignments overwrite whatever they cover,
so -mllvm only contributes Absent any -mllvm flags the seed equals a
default-constructed MCTargetOptions, so existing behavior is unchanged.
---
 clang/lib/CodeGen/BackendUtil.cpp            | 15 +++++++++++
 clang/test/CodeGen/mllvm-mc-target-options.c | 28 ++++++++++++++++++++
 clang/tools/driver/cc1as_main.cpp            | 14 +++++++++-
 3 files changed, 56 insertions(+), 1 deletion(-)
 create mode 100644 clang/test/CodeGen/mllvm-mc-target-options.c

diff --git a/clang/lib/CodeGen/BackendUtil.cpp 
b/clang/lib/CodeGen/BackendUtil.cpp
index 2b755fa916e55..4a3c3c579a367 100644
--- a/clang/lib/CodeGen/BackendUtil.cpp
+++ b/clang/lib/CodeGen/BackendUtil.cpp
@@ -39,6 +39,7 @@
 #include "llvm/IR/Verifier.h"
 #include "llvm/IRPrinter/IRPrintingPasses.h"
 #include "llvm/LTO/LTOBackend.h"
+#include "llvm/MC/MCTargetOptionsCommandFlags.h"
 #include "llvm/MC/TargetRegistry.h"
 #include "llvm/Object/OffloadBinary.h"
 #include "llvm/Passes/PassBuilder.h"
@@ -99,6 +100,13 @@
 using namespace clang;
 using namespace llvm;
 
+// Register LLVM's machine-code target-option command-line flags (e.g.
+// -large-eh-encoding) so they can be supplied through clang's -mllvm, 
mirroring
+// what the standalone LLVM tools (llc, llvm-mc) do. This also makes it safe 
for
+// initTargetOptions() to call mc::InitMCTargetOptionsFromFlags(), whose
+// accessors require the flags to have been registered.
+static llvm::mc::RegisterMCTargetOptionsFlags MCTargetOptionsFlags;
+
 #define HANDLE_EXTENSION(Ext)                                                  
\
   llvm::PassPluginLibraryInfo get##Ext##PluginInfo();
 #include "llvm/Support/Extension.def"
@@ -503,6 +511,13 @@ static bool initTargetOptions(const CompilerInstance &CI,
     break;
   }
 
+  // Seed the MC layer with any machine-code options supplied via -mllvm.
+  // Clang's own driver-derived settings below overwrite whatever they cover,
+  // so -mllvm only contributes MC options that have no dedicated clang flag.
+  // Absent any -mllvm flags this is equivalent to a default-constructed
+  // MCTargetOptions.
+  Options.MCOptions = llvm::mc::InitMCTargetOptionsFromFlags();
+
   Options.MCOptions.SplitDwarfFile = CodeGenOpts.SplitDwarfFile;
   Options.MCOptions.EmitDwarfUnwind = CodeGenOpts.getEmitDwarfUnwind();
   Options.MCOptions.EmitCompactUnwindNonCanonical =
diff --git a/clang/test/CodeGen/mllvm-mc-target-options.c 
b/clang/test/CodeGen/mllvm-mc-target-options.c
new file mode 100644
index 0000000000000..297a324754f69
--- /dev/null
+++ b/clang/test/CodeGen/mllvm-mc-target-options.c
@@ -0,0 +1,28 @@
+// REQUIRES: x86-registered-target
+//
+// Clang registers LLVM's machine-code target options (via
+// RegisterMCTargetOptionsFlags) so they can be set through -mllvm. An MC 
option
+// that has no dedicated clang flag takes effect directly; an MC option that 
also
+// has a clang flag is governed by the clang flag, which takes precedence over
+// -mllvm.
+
+// -asm-show-inst has no clang flag, so -mllvm controls it and the emitted
+// assembly gains <MCInst ...> comments.
+// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -S %s -o - \
+// RUN:   | FileCheck %s --check-prefix=NO-SHOW-INST
+// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -S -mllvm -asm-show-inst %s -o 
- \
+// RUN:   | FileCheck %s --check-prefix=SHOW-INST
+// NO-SHOW-INST-NOT: <MCInst
+// SHOW-INST: <MCInst
+
+// -x86-relax-relocations also has a clang flag (-mrelax-relocations), which 
wins
+// over -mllvm: with -mrelax-relocations=no the GOT load keeps its 
non-relaxable
+// relocation even though -mllvm -x86-relax-relocations requests relaxation.
+// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -mrelocation-model pic \
+// RUN:   -mrelax-relocations=no -mllvm -x86-relax-relocations -emit-obj %s -o 
%t
+// RUN: llvm-readobj -r %t | FileCheck %s --check-prefix=PRECEDENCE
+// PRECEDENCE:     R_X86_64_GOTPCREL foo
+// PRECEDENCE-NOT: R_X86_64_REX_GOTPCRELX foo
+
+extern int foo;
+int *f(void) { return &foo; }
diff --git a/clang/tools/driver/cc1as_main.cpp 
b/clang/tools/driver/cc1as_main.cpp
index 077cd69ce4e2c..0792a37b22609 100644
--- a/clang/tools/driver/cc1as_main.cpp
+++ b/clang/tools/driver/cc1as_main.cpp
@@ -37,6 +37,7 @@
 #include "llvm/MC/MCStreamer.h"
 #include "llvm/MC/MCSubtargetInfo.h"
 #include "llvm/MC/MCTargetOptions.h"
+#include "llvm/MC/MCTargetOptionsCommandFlags.h"
 #include "llvm/MC/TargetRegistry.h"
 #include "llvm/Option/Arg.h"
 #include "llvm/Option/ArgList.h"
@@ -64,6 +65,12 @@ using namespace clang::options;
 using namespace llvm;
 using namespace llvm::opt;
 
+// Register LLVM's machine-code target-option command-line flags (e.g.
+// -large-eh-encoding) so they can be supplied through -cc1as -mllvm, mirroring
+// what the standalone LLVM tools (llvm-mc) do. The parsed values are read back
+// via mc::InitMCTargetOptionsFromFlags() in ExecuteAssemblerImpl().
+static llvm::mc::RegisterMCTargetOptionsFlags MCTargetOptionsFlags;
+
 namespace {
 
 /// Helper class for representing a single invocation of the assembler.
@@ -463,7 +470,12 @@ static bool ExecuteAssemblerImpl(AssemblerInvocation &Opts,
   std::unique_ptr<MCRegisterInfo> MRI(TheTarget->createMCRegInfo(Opts.Triple));
   assert(MRI && "Unable to create target register info!");
 
-  MCTargetOptions MCOptions;
+  // Seed the MC layer with any machine-code options supplied via -mllvm (for
+  // example -large-eh-encoding). The cc1as flag-derived settings below 
overwrite
+  // whatever they cover, so -mllvm only contributes MC options that have no
+  // dedicated cc1as flag. Absent any -mllvm flags this is equivalent to a
+  // default-constructed MCTargetOptions.
+  MCTargetOptions MCOptions = mc::InitMCTargetOptionsFromFlags();
   MCOptions.MCRelaxAll = Opts.RelaxAll;
   MCOptions.EmitDwarfUnwind = Opts.EmitDwarfUnwind;
   MCOptions.EmitCompactUnwindNonCanonical = Opts.EmitCompactUnwindNonCanonical;

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

Reply via email to