Index: lib/IR/Module.cpp =================================================================== --- lib/IR/Module.cpp +++ lib/IR/Module.cpp @@ -494,7 +494,7 @@ } void Module::setPICLevel(PICLevel::Level PL) { - addModuleFlag(ModFlagBehavior::Error, "PIC Level", PL); + addModuleFlag(ModFlagBehavior::Warning, "PIC Level", PL); } PIELevel::Level Module::getPIELevel() const { Index: lib/Linker/IRMover.cpp =================================================================== --- lib/Linker/IRMover.cpp +++ lib/Linker/IRMover.cpp @@ -1173,6 +1173,26 @@ return DstTriple.str(); } +static void mergePICLevel(std::unique_ptr &SrcM, Module &DstM) { + auto *SrcMD = cast_or_null( + SrcM->getModuleFlag("PIC Level")); + auto *DstMD = cast_or_null( + DstM.getModuleFlag("PIC Level")); + if (!SrcMD || !DstMD) + return; + PICLevel::Level SrcL = SrcM->getPICLevel(); + PICLevel::Level DstL = DstM.getPICLevel(); + if (SrcL == DstL) + return; + if (SrcL == PICLevel::Small) + return DstM.setPICLevel(PICLevel::Small); + if (DstL == PICLevel::Small) + return SrcM->setPICLevel(PICLevel::Small); + if (SrcL < DstL) + return DstM.setPICLevel(SrcL); + return SrcM->setPICLevel(DstL); +} + Error IRLinker::run() { // Ensure metadata materialized before value mapping. if (SrcM->getMaterializer()) @@ -1245,6 +1265,8 @@ // are properly remapped. linkNamedMDNodes(); + mergePICLevel(SrcM, DstM); + // Merge the module flags into the DstM module. return linkModuleFlagsMetadata(); } Index: test/Linker/Inputs/module-flags-pic-2-b.ll =================================================================== --- test/Linker/Inputs/module-flags-pic-2-b.ll +++ test/Linker/Inputs/module-flags-pic-2-b.ll @@ -1,3 +1,3 @@ -!0 = !{ i32 1, !"PIC Level", i32 2 } +!0 = !{ i32 2, !"PIC Level", i32 2 } !llvm.module.flags = !{!0} Index: test/Linker/module-flags-pic-1-a.ll =================================================================== --- test/Linker/module-flags-pic-1-a.ll +++ test/Linker/module-flags-pic-1-a.ll @@ -2,8 +2,8 @@ ; test linking modules with specified and default PIC levels -!0 = !{ i32 1, !"PIC Level", i32 1 } +!0 = !{ i32 2, !"PIC Level", i32 1 } !llvm.module.flags = !{!0} ; CHECK: !llvm.module.flags = !{!0} -; CHECK: !0 = !{i32 1, !"PIC Level", i32 1} +; CHECK: !0 = !{i32 2, !"PIC Level", i32 1} Index: test/Linker/module-flags-pic-2-a.ll =================================================================== --- test/Linker/module-flags-pic-2-a.ll +++ test/Linker/module-flags-pic-2-a.ll @@ -1,10 +1,15 @@ -; RUN: not llvm-link %s %p/Inputs/module-flags-pic-2-b.ll -S -o - 2> %t -; RUN: FileCheck --check-prefix=CHECK-ERRORS < %t %s +; RUN: llvm-link %s %p/Inputs/module-flags-pic-2-b.ll -S -o - 2> %t | FileCheck %s \ +; RUN: --check-prefix=MERGE +; RUN: FileCheck < %t %s ; test linking modules with two different PIC levels -!0 = !{ i32 1, !"PIC Level", i32 1 } +!0 = !{ i32 2, !"PIC Level", i32 1 } !llvm.module.flags = !{!0} -; CHECK-ERRORS: ERROR: linking module flags 'PIC Level': IDs have conflicting values +; MERGE: source_filename = "llvm-link" +; MERGE: !llvm.module.flags = !{!0} +; MERGE: !0 = !{i32 2, !"PIC Level", i32 1} + +; CHECK: WARNING: linking module flags 'PIC Level': IDs have conflicting values