Index: lib/Transforms/Utils/CloneModule.cpp =================================================================== --- lib/Transforms/Utils/CloneModule.cpp +++ lib/Transforms/Utils/CloneModule.cpp @@ -109,6 +109,9 @@ // for (Module::const_global_iterator I = M->global_begin(), E = M->global_end(); I != E; ++I) { + if (I->isDeclaration()) + continue; + GlobalVariable *GV = cast(VMap[&*I]); if (!ShouldCloneDefinition(&*I)) { // Skip after setting the correct linkage for an external reference. @@ -122,6 +125,9 @@ // Similarly, copy over function bodies now... // for (Module::const_iterator I = M->begin(), E = M->end(); I != E; ++I) { + if (I->isDeclaration()) + continue; + Function *F = cast(VMap[&*I]); if (!ShouldCloneDefinition(&*I)) { // Skip after setting the correct linkage for an external reference. @@ -130,18 +136,17 @@ F->setPersonalityFn(nullptr); continue; } - if (!I->isDeclaration()) { - Function::arg_iterator DestI = F->arg_begin(); - for (Function::const_arg_iterator J = I->arg_begin(); J != I->arg_end(); - ++J) { - DestI->setName(J->getName()); - VMap[&*J] = &*DestI++; - } - - SmallVector Returns; // Ignore returns cloned. - CloneFunctionInto(F, &*I, VMap, /*ModuleLevelChanges=*/true, Returns); + + Function::arg_iterator DestI = F->arg_begin(); + for (Function::const_arg_iterator J = I->arg_begin(); J != I->arg_end(); + ++J) { + DestI->setName(J->getName()); + VMap[&*J] = &*DestI++; } + SmallVector Returns; // Ignore returns cloned. + CloneFunctionInto(F, &*I, VMap, /*ModuleLevelChanges=*/true, Returns); + if (I->hasPersonalityFn()) F->setPersonalityFn(MapValue(I->getPersonalityFn(), VMap)); } Index: test/tools/llvm-split/extern_linkage.ll =================================================================== --- /dev/null +++ test/tools/llvm-split/extern_linkage.ll @@ -0,0 +1,20 @@ +; Test that extern_weak linkage is preserved. +; RUN: llvm-split -o %t %s +; RUN: llvm-dis -o - %t0 | FileCheck %s +; RUN: llvm-dis -o - %t1 | FileCheck %s + +define void @g() { +entry: + br i1 icmp ne (void (...)* @f, void (...)* null), label %if.then, label %if.end + +if.then: ; preds = %entry + tail call void (...) @f() + br label %if.end + +if.end: ; preds = %if.then, %entry + ret void +} + +; @f is an extern_weak declaration in both partitions +; CHECK: declare extern_weak void @f(...) +declare extern_weak void @f(...)