A function with discardable linkage cannot be discarded if its a member
of a COMDAT group without considering all the other COMDAT members as
well. This sort of thing is already handled by GlobalOpt/GlobalDCE.
This fixes PR21206.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@219335
91177308-0d34-0410-b5e6-
96231b3b80d8
if (!F->isDefTriviallyDead())
continue;
+
+ // It is unsafe to drop a function with discardable linkage from a COMDAT
+ // without also dropping the other members of the COMDAT.
+ // The inliner doesn't visit non-function entities which are in COMDAT
+ // groups so it is unsafe to do so *unless* the linkage is local.
+ if (!F->hasLocalLinkage() && F->hasComdat())
+ continue;
// Remove any call graph edges from the function to its callees.
CGN->removeAllCalledFunctions();
--- /dev/null
+; RUN: opt < %s -inline -S | FileCheck %s
+
+$c = comdat any
+; CHECK: $c = comdat any
+
+define linkonce_odr void @foo() comdat $c {
+ ret void
+}
+; CHECK: define linkonce_odr void @foo() comdat $c
+
+define linkonce_odr void @bar() comdat $c {
+ ret void
+}
+; CHECK: define linkonce_odr void @bar() comdat $c
+
+define void()* @zed() {
+ ret void()* @foo
+}