Skip to content

Commit 3e834cc

Browse files
Merge pull request #85106 from kateinoigakukun/yt/fix-dead-stub-comdat-wasm
[wasm][IRGen] Stop attaching COMDATs to dead stub methods
2 parents 9cd81d2 + 50298bd commit 3e834cc

File tree

3 files changed

+54
-5
lines changed

3 files changed

+54
-5
lines changed

include/swift/IRGen/Linking.h

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1886,7 +1886,7 @@ class ApplyIRLinkage {
18861886
IRLinkage IRL;
18871887
public:
18881888
ApplyIRLinkage(IRLinkage IRL) : IRL(IRL) {}
1889-
void to(llvm::GlobalValue *GV, bool definition = true) const {
1889+
void to(llvm::GlobalValue *GV, bool nonAliasedDefinition = true) const {
18901890
llvm::Module *M = GV->getParent();
18911891
const llvm::Triple Triple(M->getTargetTriple());
18921892

@@ -1899,9 +1899,16 @@ class ApplyIRLinkage {
18991899
if (Triple.isOSBinFormatELF())
19001900
return;
19011901

1902-
// COMDATs cannot be applied to declarations. If we have a definition,
1903-
// apply the COMDAT.
1904-
if (definition)
1902+
// COMDATs cannot be applied to declarations. Also, definitions that are
1903+
// exported through aliases should not have COMDATs, because the alias
1904+
// itself might represent an externally visible symbol but such symbols
1905+
// are discarded from the symtab when other object files have a COMDAT
1906+
// group with the same signature.
1907+
//
1908+
// If we have a non-aliased definition with ODR-based linkage, attach it
1909+
// to a COMDAT group so that duplicate definitions across object files
1910+
// can be merged by the linker.
1911+
if (nonAliasedDefinition)
19051912
if (IRL.Linkage == llvm::GlobalValue::LinkOnceODRLinkage ||
19061913
IRL.Linkage == llvm::GlobalValue::WeakODRLinkage)
19071914
if (Triple.supportsCOMDAT())

lib/IRGen/GenDecl.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2201,7 +2201,7 @@ void IRGenModule::emitVTableStubs() {
22012201
&Module);
22022202
ApplyIRLinkage(canLinkOnce ? IRLinkage::InternalLinkOnceODR
22032203
: IRLinkage::Internal)
2204-
.to(stub);
2204+
.to(stub, /* nonAliasedDefinition */ false);
22052205
stub->setAttributes(constructInitialAttributes());
22062206
stub->setCallingConv(DefaultCC);
22072207
auto *entry = llvm::BasicBlock::Create(getLLVMContext(), "entry", stub);
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: split-file --leading-lines %s %t
3+
4+
// Note: IRGen uses internal linkage instead of linkonce_odr only for COFF for dead stub methods.
5+
// UNSUPPORTED: OS=windows-msvc
6+
7+
// Ensure that swift_dead_method_stub is emitted without comdat linkage
8+
// RUN: %target-swift-frontend -target %target-swift-5.1-abi-triple -parse-as-library -O -module-name A -c -primary-file %t/A.swift %t/B.swift -emit-ir -o - | %FileCheck %s -check-prefix CHECK
9+
// RUN: %target-swift-frontend -target %target-swift-5.1-abi-triple -parse-as-library -O -module-name A -c %t/A.swift -primary-file %t/B.swift -emit-ir -o - | %FileCheck %s -check-prefix CHECK
10+
11+
// CHECK-LABEL: define {{(linkonce_odr )?}}hidden void @_swift_dead_method_stub(
12+
// CHECK-NOT: comdat
13+
// CHECK: {
14+
15+
16+
// Ensure that link-time deduplication for swift_dead_method_stub works correctly
17+
// RUN: %target-swift-frontend -target %target-swift-5.1-abi-triple -parse-as-library -O -module-name A -c -primary-file %t/A.swift %t/B.swift -o %t/A.swift.o
18+
// RUN: %target-swift-frontend -target %target-swift-5.1-abi-triple -parse-as-library -O -module-name A -c %t/A.swift -primary-file %t/B.swift -o %t/B.swift.o
19+
// RUN: %target-build-swift -target %target-swift-5.1-abi-triple %t/B.swift.o %t/A.swift.o -o %t/a.out
20+
21+
//--- A.swift
22+
23+
// Define an open class with a dead vtable entry
24+
class C1 {
25+
private func dead() {}
26+
}
27+
28+
//--- B.swift
29+
30+
class C2: C1 {
31+
// Define another dead vtable entry to ensure that this object file
32+
// also should have dead vtable stub definition
33+
private func beef() {}
34+
}
35+
36+
@main
37+
struct Entry {
38+
static func main() {
39+
_ = C2()
40+
}
41+
}
42+

0 commit comments

Comments
 (0)