Skip to content

Commit 18593ca

Browse files
committed
[llvm][CFI] Do not canonicalize COFF functions in a comdat
COFF requires that a function exists with the same name as a comdat. Not having this key function results in `LLVM ERROR: Associative COMDAT symbol '...' does not exist.` CFI by default will attempt to canonicalize a function by appending `.cfi` to its name which allows external references to refer to the new canonical alias, but it does not change the comdat name. We cannot change the comdat name in case the same comdat is used by other TUs outside this LTO unit. To prevent this, we can just not canonicalize COFF comdat'd functions.
1 parent a6385a8 commit 18593ca

File tree

2 files changed

+42
-0
lines changed

2 files changed

+42
-0
lines changed

llvm/lib/Transforms/IPO/LowerTypeTests.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,18 @@ void ByteArrayBuilder::allocate(const std::set<uint64_t> &Bits,
246246
bool lowertypetests::isJumpTableCanonical(Function *F) {
247247
if (F->isDeclarationForLinker())
248248
return false;
249+
250+
// Do not canonicalize a comdat'd COFF function because this could end up
251+
// renaming the comdat key function without renaming the comdat key. We cannot
252+
// rename the key in this LTO unit because other TUs may reference the
253+
// original key name. To prevent this, just ignore canonicalization for
254+
// comdat'd COFF functions.
255+
if (F->hasComdat()) {
256+
Triple TargetTriple(F->getParent()->getTargetTriple());
257+
if (TargetTriple.isOSBinFormatCOFF())
258+
return false;
259+
}
260+
249261
auto *CI = mdconst::extract_or_null<ConstantInt>(
250262
F->getParent()->getModuleFlag("CFI Canonical Jump Tables"));
251263
if (!CI || !CI->isZero())
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
; RUN: opt -S -passes=lowertypetests %s -mtriple=x86_64-pc-windows-msvc | llc -asm-verbose=false | FileCheck %s --check-prefixes=COFF,CHECK
2+
; RUN: opt -S -passes=lowertypetests %s -mtriple=x86_64-unknown-linux-gnu | llc -asm-verbose=false | FileCheck %s --check-prefixes=ELF,CHECK
3+
4+
target datalayout = "e-p:64:64"
5+
6+
; COFF-LABEL: f3:
7+
; ELF-LABEL: f3.cfi:
8+
9+
; CHECK-LABEL: a:
10+
; COFF: .quad .L.cfi.jumptable
11+
; ELF: .quad f3
12+
13+
; ELF: .set f3, .L.cfi.jumptable
14+
15+
@a = global ptr @f3
16+
17+
$f3 = comdat any
18+
19+
define void @f3() comdat !type !0 {
20+
ret void
21+
}
22+
23+
declare i1 @llvm.type.test(ptr %ptr, metadata %bitset) nounwind readnone
24+
25+
define i1 @foo(ptr %p) {
26+
%x = call i1 @llvm.type.test(ptr %p, metadata !"typeid1")
27+
ret i1 %x
28+
}
29+
30+
!0 = !{i32 0, !"typeid1"}

0 commit comments

Comments
 (0)