Skip to content

Commit 9e6f797

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 can just change the comdat name since symbol resolution has already happened before LTO.
1 parent a6385a8 commit 9e6f797

File tree

2 files changed

+40
-1
lines changed

2 files changed

+40
-1
lines changed

llvm/lib/Transforms/IPO/LowerTypeTests.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1715,8 +1715,18 @@ void LowerTypeTestsModule::buildBitSetsFromFunctionsNative(
17151715
F->getValueType(), 0, F->getLinkage(), "", CombinedGlobalElemPtr, &M);
17161716
FAlias->setVisibility(F->getVisibility());
17171717
FAlias->takeName(F);
1718-
if (FAlias->hasName())
1718+
if (FAlias->hasName()) {
17191719
F->setName(FAlias->getName() + ".cfi");
1720+
// For COFF we should also rename the comdat if this function also
1721+
// happens to be the key function. Even if the comdat name changes, this
1722+
// should still be fine since comdat and symbol resolution happens
1723+
// before LTO, so all symbols which would prevail have been selected.
1724+
if (F->hasComdat() && ObjectFormat == Triple::COFF &&
1725+
F->getComdat()->getName() == FAlias->getName()) {
1726+
Comdat *NewComdat = M.getOrInsertComdat(F->getName());
1727+
F->setComdat(NewComdat);
1728+
}
1729+
}
17201730
replaceCfiUses(F, FAlias, IsJumpTableCanonical);
17211731
if (!F->hasLocalLinkage())
17221732
F->setVisibility(GlobalVariable::HiddenVisibility);
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
; RUN: opt -S -passes=lowertypetests %s | FileCheck %s
2+
3+
;; This is a check to assert we don't crash with:
4+
;;
5+
;; LLVM ERROR: Associative COMDAT symbol '...' does not exist.
6+
;;
7+
;; So this just needs to exit normally.
8+
; RUN: opt -S -passes=lowertypetests %s | llc -asm-verbose=false
9+
10+
target datalayout = "e-p:64:64"
11+
target triple = "x86_64-pc-windows-msvc"
12+
13+
@a = global ptr @f3
14+
15+
$f3 = comdat any
16+
17+
; CHECK: @f3.cfi() comdat !type !0
18+
define void @f3() comdat !type !0 {
19+
ret void
20+
}
21+
22+
declare i1 @llvm.type.test(ptr %ptr, metadata %bitset) nounwind readnone
23+
24+
define i1 @foo(ptr %p) {
25+
%x = call i1 @llvm.type.test(ptr %p, metadata !"typeid1")
26+
ret i1 %x
27+
}
28+
29+
!0 = !{i32 0, !"typeid1"}

0 commit comments

Comments
 (0)