Index: llvm/lib/Linker/IRMover.cpp =================================================================== --- llvm/lib/Linker/IRMover.cpp +++ llvm/lib/Linker/IRMover.cpp @@ -1260,15 +1260,56 @@ Flags[ID].first = SrcOp; }; + // Check the input bitcode is swift generated bitcode. + auto isSwiftBitCode = [&](Module &M) { + SmallVector ModuleFlags; + M.getModuleFlagsMetadata(ModuleFlags); + for (const auto &MFE: ModuleFlags) { + if (MFE.Behavior == Module::Require) + continue; + StringRef Key = MFE.Key->getString(); + if (Key == "Swift Version") + return true; + } + return false; + }; + // If either flag has override behavior, handle it first. if (DstBehaviorValue == Module::Override) { // Diagnose inconsistent flags which both have override behavior. if (SrcBehaviorValue == Module::Override && - SrcOp->getOperand(2) != DstOp->getOperand(2)) + SrcOp->getOperand(2) != DstOp->getOperand(2)) { + if (ID->getString().equals("Objective-C Garbage Collection")) { + + // Merge the value of metadata "Objective-C Garbage Collection" + // into one value by shifting. The purpose of this change is + // to support LTO in Swift and Objective-C mixed project. + + auto Int32Ty = Type::getInt32Ty(DstM.getContext()); + auto SrcMD = dyn_cast(SrcOp->getOperand(2)); + auto DstMD = dyn_cast(DstOp->getOperand(2)); + assert(SrcMD && DstMD); + unsigned SrcVal = SrcMD->getValue()->getUniqueInteger().getZExtValue(); + unsigned DstVal = DstMD->getValue()->getUniqueInteger().getZExtValue(); + if ((isSwiftBitCode(*SrcM) && + (SrcVal & 0xffffffc0) == SrcVal && + DstVal < 64) || + (isSwiftBitCode(DstM) && + (DstVal & 0xffffffc0) == DstVal && + SrcVal < 64)) { + unsigned ResVal = SrcVal | DstVal; + SrcOp->replaceOperandWith(2, + ConstantAsMetadata::get(ConstantInt::get(Int32Ty,ResVal))); + DstOp->replaceOperandWith(2, + ConstantAsMetadata::get(ConstantInt::get(Int32Ty,ResVal))); + continue; + } + } return stringErr("linking module flags '" + ID->getString() + "': IDs have conflicting override values in '" + SrcM->getModuleIdentifier() + "' and '" + DstM.getModuleIdentifier() + "'"); + } continue; } else if (SrcBehaviorValue == Module::Override) { // Update the destination flag to that of the source. Index: llvm/test/Linker/Inputs/empty-objc.ll =================================================================== --- /dev/null +++ llvm/test/Linker/Inputs/empty-objc.ll @@ -0,0 +1,14 @@ +target triple = "x86_64-apple-macosx10.15.0" + +!llvm.module.flags = !{!0, !1, !2, !3, !4, !5, !6, !7} +!llvm.ident = !{!8} + +!0 = !{i32 2, !"SDK Version", [2 x i32] [i32 10, i32 15]} +!1 = !{i32 1, !"Objective-C Version", i32 2} +!2 = !{i32 1, !"Objective-C Image Info Version", i32 0} +!3 = !{i32 1, !"Objective-C Image Info Section", !"__DATA,__objc_imageinfo,regular,no_dead_strip"} +!4 = !{i32 4, !"Objective-C Garbage Collection", i32 2} +!5 = !{i32 1, !"Objective-C Class Properties", i32 64} +!6 = !{i32 1, !"wchar_size", i32 4} +!7 = !{i32 7, !"PIC Level", i32 2} +!8 = !{!"Apple clang version 11.0.0 (clang-1100.0.33.12)"} Index: llvm/test/Linker/empty-swift.ll =================================================================== --- /dev/null +++ llvm/test/Linker/empty-swift.ll @@ -0,0 +1,37 @@ +; RUN: llvm-link %s %p/Inputs/empty-objc.ll -S | FileCheck %s + +; It tests whether Swift bitcode can be successfully with Objecitive-C bitcode. + +target triple = "x86_64-apple-macosx10.15.0" + +@__swift_reflection_version = linkonce_odr hidden constant i16 3 +@llvm.used = appending global [1 x i8*] [i8* bitcast (i16* @__swift_reflection_version to i8*)], section "llvm.metadata", align 8 + +define i32 @main(i32 %0, i8** %1) #0 { + %3 = bitcast i8** %1 to i8* + ret i32 0 +} + +attributes #0 = { "frame-pointer"="all" "target-cpu"="penryn" "target-features"="+cx16,+fxsr,+mmx,+sahf,+sse,+sse2,+sse3,+sse4.1,+ssse3,+x87" } + +!llvm.module.flags = !{!0, !1, !2, !3, !4, !5, !6, !7, !8} +!swift.module.flags = !{!9} +!llvm.linker.options = !{!10, !11, !12} +!llvm.asan.globals = !{!13} + +!0 = !{i32 2, !"SDK Version", [2 x i32] [i32 10, i32 15]} +!1 = !{i32 1, !"Objective-C Version", i32 2} +!2 = !{i32 1, !"Objective-C Image Info Version", i32 0} +!3 = !{i32 1, !"Objective-C Image Info Section", !"__DATA,__objc_imageinfo,regular,no_dead_strip"} +!4 = !{i32 4, !"Objective-C Garbage Collection", i32 83953408} +!5 = !{i32 1, !"Objective-C Class Properties", i32 64} +!6 = !{i32 1, !"wchar_size", i32 4} +!7 = !{i32 7, !"PIC Level", i32 2} +!8 = !{i32 1, !"Swift Version", i32 7} +!9 = !{!"standard-library", i1 false} +!10 = !{!"-lswiftSwiftOnoneSupport"} +!11 = !{!"-lswiftCore"} +!12 = !{!"-lobjc"} +!13 = !{[1 x i8*]* @llvm.used, null, null, i1 false, i1 true} + +; CHECK: !{{[0-9]}} = distinct !{i32 4, !"Objective-C Garbage Collection", i32 83953410}