diff --git a/llvm/lib/Transforms/IPO/LowerTypeTests.cpp b/llvm/lib/Transforms/IPO/LowerTypeTests.cpp index d855647095550..d615c10c23030 100644 --- a/llvm/lib/Transforms/IPO/LowerTypeTests.cpp +++ b/llvm/lib/Transforms/IPO/LowerTypeTests.cpp @@ -1715,8 +1715,22 @@ void LowerTypeTestsModule::buildBitSetsFromFunctionsNative( F->getValueType(), 0, F->getLinkage(), "", CombinedGlobalElemPtr, &M); FAlias->setVisibility(F->getVisibility()); FAlias->takeName(F); - if (FAlias->hasName()) + if (FAlias->hasName()) { F->setName(FAlias->getName() + ".cfi"); + // For COFF we should also rename the comdat if this function also + // happens to be the key function. Even if the comdat name changes, this + // should still be fine since comdat and symbol resolution happens + // before LTO, so all symbols which would prevail have been selected. + if (F->hasComdat() && ObjectFormat == Triple::COFF && + F->getComdat()->getName() == FAlias->getName()) { + Comdat *OldComdat = F->getComdat(); + Comdat *NewComdat = M.getOrInsertComdat(F->getName()); + for (GlobalObject &GO : M.global_objects()) { + if (GO.getComdat() == OldComdat) + GO.setComdat(NewComdat); + } + } + } replaceCfiUses(F, FAlias, IsJumpTableCanonical); if (!F->hasLocalLinkage()) F->setVisibility(GlobalVariable::HiddenVisibility); diff --git a/llvm/test/Transforms/LowerTypeTests/cfi-coff-comdat-rename.ll b/llvm/test/Transforms/LowerTypeTests/cfi-coff-comdat-rename.ll new file mode 100644 index 0000000000000..aa56a3abf00fc --- /dev/null +++ b/llvm/test/Transforms/LowerTypeTests/cfi-coff-comdat-rename.ll @@ -0,0 +1,35 @@ +; RUN: opt -S -passes=lowertypetests %s | FileCheck %s + +;; This is a check to assert we don't crash with: +;; +;; LLVM ERROR: Associative COMDAT symbol '...' does not exist. +;; +;; So this just needs to exit normally. +; RUN: opt -S -passes=lowertypetests %s | llc -asm-verbose=false + +target datalayout = "e-p:64:64" +target triple = "x86_64-pc-windows-msvc" + +@a = global [2 x ptr] [ptr @f1, ptr @f2] + +; CHECK: $f1.cfi = comdat any +$f1 = comdat any + +; CHECK: @f1.cfi() comdat !type !0 +define void @f1() comdat !type !0 { + ret void +} + +; CHECK: @f2.cfi() comdat($f1.cfi) !type !0 +define void @f2() comdat($f1) !type !0 { + ret void +} + +declare i1 @llvm.type.test(ptr %ptr, metadata %bitset) nounwind readnone + +define i1 @foo(ptr %p) { + %x = call i1 @llvm.type.test(ptr %p, metadata !"typeid1") + ret i1 %x +} + +!0 = !{i32 0, !"typeid1"}