Skip to content

Commit 0bc0cc2

Browse files
committed
[llvm][EmbedBitcodePass] Prevent modifying the module with ThinLTO
Since ThinLTOBitcodeWriterPass handles many things for CFI and WPD, like updating vtable linkage, we need to prevent those changes from persisting in the non-LTO object code we will compile under FatLTO. The only non-invasive way to do that is to clone the module when serializing the module in ThinLTOBitcodeWriterPass. We may be able to avoid cloning in the future with additional infrastructure to restore the IR to its original state. Fixes #139440
1 parent d287d80 commit 0bc0cc2

File tree

2 files changed

+9
-4
lines changed

2 files changed

+9
-4
lines changed

llvm/lib/Transforms/IPO/EmbedBitcodePass.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "llvm/Support/raw_ostream.h"
1717
#include "llvm/TargetParser/Triple.h"
1818
#include "llvm/Transforms/IPO/ThinLTOBitcodeWriter.h"
19+
#include "llvm/Transforms/Utils/Cloning.h"
1920
#include "llvm/Transforms/Utils/ModuleUtils.h"
2021

2122
#include <string>
@@ -33,8 +34,11 @@ PreservedAnalyses EmbedBitcodePass::run(Module &M, ModuleAnalysisManager &AM) {
3334

3435
std::string Data;
3536
raw_string_ostream OS(Data);
37+
// Clone the module with with Thin LTO, since ThinLTOBitcodeWriterPass changes
38+
// vtable linkage that would break the non-lto object code for FatLTO.
3639
if (IsThinLTO)
37-
ThinLTOBitcodeWriterPass(OS, /*ThinLinkOS=*/nullptr).run(M, AM);
40+
ThinLTOBitcodeWriterPass(OS, /*ThinLinkOS=*/nullptr)
41+
.run(*llvm::CloneModule(M), AM);
3842
else
3943
BitcodeWriterPass(OS, /*ShouldPreserveUseListOrder=*/false, EmitLTOSummary)
4044
.run(M, AM);

llvm/test/Transforms/EmbedBitcode/embed-wpd.ll

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
; RUN: opt --mtriple x86_64-unknown-linux-gnu < %s -passes="embed-bitcode<thinlto>" -S | FileCheck %s
22

3-
; CHECK-NOT: $_ZTV3Foo = comdat any
3+
; CHECK: $_ZTV3Foo = comdat any
44
$_ZTV3Foo = comdat any
55

66
$_ZTI3Foo = comdat any
77

8-
; CHECK: @_ZTV3Foo = external hidden unnamed_addr constant { [5 x ptr] }, align 8
9-
; CHECK: @_ZTI3Foo = linkonce_odr hidden constant { ptr, ptr, ptr } { ptr getelementptr inbounds (ptr, ptr @_ZTVN10__cxxabiv120__si_class_type_infoE, i64 2), ptr @_ZTS3Foo, ptr @_ZTISt13runtime_error }, comdat, align 8
8+
;; ThinLTOBitcodeWriter will remove the vtable for Foo, and make it an external symbol
9+
; CHECK: @_ZTV3Foo = linkonce_odr hidden unnamed_addr constant { [5 x ptr] } { [5 x ptr] [ptr null, ptr @_ZTI3Foo, ptr @_ZN3FooD2Ev, ptr @_ZN3FooD0Ev, ptr @_ZNKSt13runtime_error4whatEv] }, comdat, align 8, !type !0, !type !1, !type !2, !type !3, !type !4, !type !5
10+
; CHECK-NOT: @foo = external unnamed_addr constant { [5 x ptr] }, align 8
1011
; CHECK: @llvm.embedded.object = private constant {{.*}}, section ".llvm.lto", align 1
1112
; CHECK: @llvm.compiler.used = appending global [1 x ptr] [ptr @llvm.embedded.object], section "llvm.metadata"
1213
@_ZTV3Foo = linkonce_odr hidden unnamed_addr constant { [5 x ptr] } { [5 x ptr] [ptr null, ptr @_ZTI3Foo, ptr @_ZN3FooD2Ev, ptr @_ZN3FooD0Ev, ptr @_ZNKSt13runtime_error4whatEv] }, comdat, align 8, !type !0, !type !1, !type !2, !type !3, !type !4, !type !5

0 commit comments

Comments
 (0)