https://github.com/LittleMeepo created 
https://github.com/llvm/llvm-project/pull/235308

Ordinary bitcode embedding options are already ignored when compiling with LTO. 
Fat LTO uses an AssembleJobAction, whose integrated assembler argument 
collection forwarded these options without checking the job's LTO mode. This 
enables ordinary embedding before the FatLTO embedding pass and fails with "Can 
only embed the module once".

Pass the job's LTO state to CollectArgsForIntegratedAssembler and suppress 
bitcode embedding options there when LTO is enabled. Preserve standalone 
assembler behavior by passing false from ClangAs::ConstructJob.

Add driver coverage for default, Full, and Thin LTO with fat objects.

Fixes #88041.

>From 5eedbc6753b7ac6e0824a6e75807fc4efe4249a9 Mon Sep 17 00:00:00 2001
From: Fangcao Wang <[email protected]>
Date: Sat, 24 Oct 2026 21:53:29 +0800
Subject: [PATCH] [Clang][Driver] Ignore -fembed-bitcode for fat LTO

Ordinary bitcode embedding options are already ignored when compiling with
LTO. Fat LTO uses an AssembleJobAction, whose integrated assembler argument
collection forwarded these options without checking the job's LTO mode.
This enables ordinary embedding before the FatLTO embedding pass and fails
with "Can only embed the module once".

Pass the job's LTO state to CollectArgsForIntegratedAssembler and suppress
bitcode embedding options there when LTO is enabled. Preserve standalone
assembler behavior by passing false from ClangAs::ConstructJob.

Add driver coverage for default, Full, and Thin LTO with fat objects.

Fixes #88041.
---
 clang/lib/Driver/ToolChains/Clang.cpp | 14 ++++++++------
 clang/test/Driver/embed-bitcode.c     | 12 ++++++++++++
 2 files changed, 20 insertions(+), 6 deletions(-)

diff --git a/clang/lib/Driver/ToolChains/Clang.cpp 
b/clang/lib/Driver/ToolChains/Clang.cpp
index 5a1c8531812bd3..52429772f306c8 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -2602,7 +2602,8 @@ static void AddARMImplicitITArgs(const ArgList &Args, 
ArgStringList &CmdArgs,
 static void CollectArgsForIntegratedAssembler(Compilation &C,
                                               const ArgList &Args,
                                               ArgStringList &CmdArgs,
-                                              const Driver &D) {
+                                              const Driver &D,
+                                              bool IsUsingLTO) {
   // Default to -mno-relax-all.
   //
   // Note: RISC-V requires an indirect jump for offsets larger than 1MiB. This
@@ -2953,9 +2954,9 @@ static void CollectArgsForIntegratedAssembler(Compilation 
&C,
     CmdArgs.push_back(Feature);
   }
 
-  // forward -fembed-bitcode to assmebler
-  if (C.getDriver().embedBitcodeEnabled() ||
-      C.getDriver().embedBitcodeMarkerOnly())
+  // LTO handles bitcode emission, including embedding it in fat objects.
+  if (!IsUsingLTO && (C.getDriver().embedBitcodeEnabled() ||
+                      C.getDriver().embedBitcodeMarkerOnly()))
     Args.AddLastArg(CmdArgs, options::OPT_fembed_bitcode_EQ);
 
   if (const char *AsSecureLogFile = getenv("AS_SECURE_LOG_FILE")) {
@@ -5546,7 +5547,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction 
&JA,
   } else if (isa<AssembleJobAction>(JA)) {
     CmdArgs.push_back("-emit-obj");
 
-    CollectArgsForIntegratedAssembler(C, Args, CmdArgs, D);
+    CollectArgsForIntegratedAssembler(C, Args, CmdArgs, D, IsUsingLTO);
 
     // Also ignore explicit -force_cpusubtype_ALL option.
     (void)Args.hasArg(options::OPT_force__cpusubtype__ALL);
@@ -9553,7 +9554,8 @@ void ClangAs::ConstructJob(Compilation &C, const 
JobAction &JA,
   Args.ClaimAllArgs(options::OPT_W_Group);
 
   CollectArgsForIntegratedAssembler(C, Args, CmdArgs,
-                                    getToolChain().getDriver());
+                                    getToolChain().getDriver(),
+                                    /*IsUsingLTO=*/false);
 
   // Forward -Xclangas arguments to -cc1as
   for (auto Arg : Args.filtered(options::OPT_Xclangas)) {
diff --git a/clang/test/Driver/embed-bitcode.c 
b/clang/test/Driver/embed-bitcode.c
index a2987dc4e22732..98bb7692033904 100644
--- a/clang/test/Driver/embed-bitcode.c
+++ b/clang/test/Driver/embed-bitcode.c
@@ -34,6 +34,18 @@
 // CHECK-LTO-NOT: warning: argument unused during compilation: 
'-fembed-bitcode'
 // CHECK-LTO-NOT: -cc1
 // CHECK-LTO-NOT: -fembed-bitcode=all
+
+// RUN: %clang --target=x86_64-unknown-linux-gnu -c %s -flto -ffat-lto-objects 
-fembed-bitcode -### 2>&1 \
+// RUN:   | FileCheck %s --check-prefix=CHECK-FAT-LTO 
--implicit-check-not=-fembed-bitcode
+// RUN: %clang --target=x86_64-unknown-linux-gnu -c %s -flto=full 
-ffat-lto-objects -fembed-bitcode -### 2>&1 \
+// RUN:   | FileCheck %s --check-prefix=CHECK-FAT-LTO 
--implicit-check-not=-fembed-bitcode
+// RUN: %clang --target=x86_64-unknown-linux-gnu -c %s -flto=thin 
-ffat-lto-objects -fembed-bitcode -### 2>&1 \
+// RUN:   | FileCheck %s --check-prefix=CHECK-FAT-LTO 
--implicit-check-not=-fembed-bitcode
+// CHECK-FAT-LTO: "-cc1"
+// CHECK-FAT-LTO-SAME: "-emit-obj"
+// CHECK-FAT-LTO-SAME: "-flto={{full|thin}}"
+// CHECK-FAT-LTO-SAME: "-ffat-lto-objects"
+
 // RUN: touch %t.o
 // RUN: %clang  -target armv7-apple-darwin -miphoneos-version-min=6.0 %t.o 
-fembed-bitcode  -fembed-bitcode-marker -mlinker-version=277  2>&1 -### | 
FileCheck %s -check-prefix=CHECK-LTO-MARKER-277
 // RUN: %clang  -target armv7-apple-darwin -miphoneos-version-min=6.0 %t.o 
-fembed-bitcode  -fembed-bitcode-marker -mlinker-version=278  2>&1 -### | 
FileCheck %s -check-prefix=CHECK-LTO-MARKER-278

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

Reply via email to