[clang] a0cacb6 - Fix conflict value for metadata "Objective-C Garbage Collection" in the mix of swift and Objective-C bitcode

Jin Lin via cfe-commits cfe-commits at lists.llvm.org
Wed Mar 11 13:26:29 PDT 2020


Author: Jin Lin
Date: 2020-03-11T13:26:06-07:00
New Revision: a0cacb60549f2346f7addf9205cd32720afc8fb4

URL: https://github.com/llvm/llvm-project/commit/a0cacb60549f2346f7addf9205cd32720afc8fb4
DIFF: https://github.com/llvm/llvm-project/commit/a0cacb60549f2346f7addf9205cd32720afc8fb4.diff

LOG: Fix conflict value for metadata "Objective-C Garbage Collection" in the mix of swift and Objective-C bitcode

Summary:
The change is to fix conflict value for metadata "Objective-C Garbage Collection" in the mix of swift and Objective-C bitcode.
The purpose is to provide the support of LTO for swift and Objective-C mixed project.

Reviewers: rjmccall, ahatanak, steven_wu

Reviewed By: rjmccall, steven_wu

Subscribers: manmanren, mehdi_amini, hiraditya, dexonsmith, llvm-commits, jinlin

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D71219

Added: 
    llvm/test/Bitcode/upgrade-garbage-collection-for-objc.ll
    llvm/test/Bitcode/upgrade-garbage-collection-for-swift.ll
    llvm/test/Linker/Inputs/empty-objc.ll
    llvm/test/Linker/empty-swift.ll
    llvm/test/Object/objc-swift-mixed-imageinfo-macho.ll

Modified: 
    clang/lib/CodeGen/CGObjCMac.cpp
    clang/test/CodeGenObjC/image-info.m
    llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
    llvm/lib/IR/AutoUpgrade.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp
index 0ab4fd8e224c..44c14a745a98 100644
--- a/clang/lib/CodeGen/CGObjCMac.cpp
+++ b/clang/lib/CodeGen/CGObjCMac.cpp
@@ -5159,15 +5159,18 @@ void CGObjCCommonMac::EmitImageInfo() {
   Mod.addModuleFlag(llvm::Module::Error, "Objective-C Image Info Section",
                     llvm::MDString::get(VMContext, Section));
 
+  auto Int8Ty = llvm::Type::getInt8Ty(VMContext);
   if (CGM.getLangOpts().getGC() == LangOptions::NonGC) {
     // Non-GC overrides those files which specify GC.
-    Mod.addModuleFlag(llvm::Module::Override,
-                      "Objective-C Garbage Collection", (uint32_t)0);
+    Mod.addModuleFlag(llvm::Module::Error,
+                      "Objective-C Garbage Collection",
+                      llvm::ConstantInt::get(Int8Ty,0));
   } else {
     // Add the ObjC garbage collection value.
     Mod.addModuleFlag(llvm::Module::Error,
                       "Objective-C Garbage Collection",
-                      eImageInfo_GarbageCollected);
+                      llvm::ConstantInt::get(Int8Ty,
+                        (uint8_t)eImageInfo_GarbageCollected));
 
     if (CGM.getLangOpts().getGC() == LangOptions::GCOnly) {
       // Add the ObjC GC Only value.
@@ -5178,7 +5181,7 @@ void CGObjCCommonMac::EmitImageInfo() {
       llvm::Metadata *Ops[2] = {
           llvm::MDString::get(VMContext, "Objective-C Garbage Collection"),
           llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(
-              llvm::Type::getInt32Ty(VMContext), eImageInfo_GarbageCollected))};
+              Int8Ty, eImageInfo_GarbageCollected))};
       Mod.addModuleFlag(llvm::Module::Require, "Objective-C GC Only",
                         llvm::MDNode::get(VMContext, Ops));
     }

diff  --git a/clang/test/CodeGenObjC/image-info.m b/clang/test/CodeGenObjC/image-info.m
index 37156ed039e4..2b9af900354b 100644
--- a/clang/test/CodeGenObjC/image-info.m
+++ b/clang/test/CodeGenObjC/image-info.m
@@ -8,10 +8,10 @@
 // CHECK-FRAGILE:      !{{[0-9]+}} = !{i32 1, !"Objective-C Version", i32 1}
 // CHECK-FRAGILE-NEXT: !{{[0-9]+}} = !{i32 1, !"Objective-C Image Info Version", i32 0}
 // CHECK-FRAGILE-NEXT: !{{[0-9]+}} = !{i32 1, !"Objective-C Image Info Section", !"__OBJC,__image_info,regular"}
-// CHECK-FRAGILE-NEXT: !{{[0-9]+}} = !{i32 4, !"Objective-C Garbage Collection", i32 0}
+// CHECK-FRAGILE-NEXT: !{{[0-9]+}} = !{i32 1, !"Objective-C Garbage Collection", i8 0}
 
 // CHECK-NONFRAGILE:      !llvm.module.flags = !{{{.*}}}
 // CHECK-NONFRAGILE:      !{{[0-9]+}} = !{i32 1, !"Objective-C Version", i32 2}
 // CHECK-NONFRAGILE-NEXT: !{{[0-9]+}} = !{i32 1, !"Objective-C Image Info Version", i32 0}
 // CHECK-NONFRAGILE-NEXT: !{{[0-9]+}} = !{i32 1, !"Objective-C Image Info Section", !"__DATA,__objc_imageinfo,regular,no_dead_strip"}
-// CHECK-NONFRAGILE-NEXT: !{{[0-9]+}} = !{i32 4, !"Objective-C Garbage Collection", i32 0}
+// CHECK-NONFRAGILE-NEXT: !{{[0-9]+}} = !{i32 1, !"Objective-C Garbage Collection", i8 0}

diff  --git a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
index d36d04e42cbe..2ce285c85672 100644
--- a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
+++ b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
@@ -84,6 +84,15 @@ static void GetObjCImageInfo(Module &M, unsigned &Version, unsigned &Flags,
     } else if (Key == "Objective-C Image Info Section") {
       Section = cast<MDString>(MFE.Val)->getString();
     }
+    // Backend generates L_OBJC_IMAGE_INFO from Swift ABI version + major + minor +
+    // "Objective-C Garbage Collection".
+    else if (Key == "Swift ABI Version") {
+      Flags |= (mdconst::extract<ConstantInt>(MFE.Val)->getZExtValue()) << 8;
+    } else if (Key == "Swift Major Version") {
+      Flags |= (mdconst::extract<ConstantInt>(MFE.Val)->getZExtValue()) << 24;
+    } else if (Key == "Swift Minor Version") {
+      Flags |= (mdconst::extract<ConstantInt>(MFE.Val)->getZExtValue()) << 16;
+    }
   }
 }
 

diff  --git a/llvm/lib/IR/AutoUpgrade.cpp b/llvm/lib/IR/AutoUpgrade.cpp
index 28bc5a48ff5c..408c28a9bae7 100644
--- a/llvm/lib/IR/AutoUpgrade.cpp
+++ b/llvm/lib/IR/AutoUpgrade.cpp
@@ -4022,6 +4022,12 @@ bool llvm::UpgradeModuleFlags(Module &M) {
     return false;
 
   bool HasObjCFlag = false, HasClassProperties = false, Changed = false;
+  bool HasSwiftVersionFlag = false;
+  uint8_t SwiftMajorVersion, SwiftMinorVersion;
+  uint32_t SwiftABIVersion;
+  auto Int8Ty = Type::getInt8Ty(M.getContext());
+  auto Int32Ty = Type::getInt32Ty(M.getContext());
+
   for (unsigned I = 0, E = ModFlags->getNumOperands(); I != E; ++I) {
     MDNode *Op = ModFlags->getOperand(I);
     if (Op->getNumOperands() != 3)
@@ -4067,6 +4073,31 @@ bool llvm::UpgradeModuleFlags(Module &M) {
         }
       }
     }
+
+    // IRUpgrader turns a i32 type "Objective-C Garbage Collection" into i8 value.
+    // If the higher bits are set, it adds new module flag for swift info.
+    if (ID->getString() == "Objective-C Garbage Collection") {
+      auto Md = dyn_cast<ConstantAsMetadata>(Op->getOperand(2));
+      if (Md) {
+        assert(Md->getValue() && "Expected non-empty metadata");
+        auto Type = Md->getValue()->getType();
+        if (Type == Int8Ty)
+          continue;
+        unsigned Val = Md->getValue()->getUniqueInteger().getZExtValue();
+        if ((Val & 0xff) != Val) {
+          HasSwiftVersionFlag = true;
+          SwiftABIVersion = (Val & 0xff00) >> 8;
+          SwiftMajorVersion = (Val & 0xff000000) >> 24;
+          SwiftMinorVersion = (Val & 0xff0000) >> 16;
+        }
+        Metadata *Ops[3] = {
+          ConstantAsMetadata::get(ConstantInt::get(Int32Ty,Module::Error)),
+          Op->getOperand(1),
+          ConstantAsMetadata::get(ConstantInt::get(Int8Ty,Val & 0xff))};
+        ModFlags->setOperand(I, MDNode::get(M.getContext(), Ops));
+        Changed = true;
+      }
+    }
   }
 
   // "Objective-C Class Properties" is recently added for Objective-C. We
@@ -4080,6 +4111,16 @@ bool llvm::UpgradeModuleFlags(Module &M) {
     Changed = true;
   }
 
+  if (HasSwiftVersionFlag) {
+    M.addModuleFlag(Module::Error, "Swift ABI Version",
+                    SwiftABIVersion);
+    M.addModuleFlag(Module::Error, "Swift Major Version",
+                    ConstantInt::get(Int8Ty, SwiftMajorVersion));
+    M.addModuleFlag(Module::Error, "Swift Minor Version",
+                    ConstantInt::get(Int8Ty, SwiftMinorVersion));
+    Changed = true;
+  }
+
   return Changed;
 }
 

diff  --git a/llvm/test/Bitcode/upgrade-garbage-collection-for-objc.ll b/llvm/test/Bitcode/upgrade-garbage-collection-for-objc.ll
new file mode 100644
index 000000000000..2783dbdb2a76
--- /dev/null
+++ b/llvm/test/Bitcode/upgrade-garbage-collection-for-objc.ll
@@ -0,0 +1,21 @@
+; RUN: llvm-as %s -o - | llvm-dis - | FileCheck %s
+
+; The IRUpgrader turns a i32 type "Objective-C Garbage Collection"
+; into i8 value.
+
+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 1, !"Objective-C Garbage Collection", i32 0}
+!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)"}
+
+; CHECK: !{{[0-9]+}} = !{i32 1, !"Objective-C Garbage Collection", i8 0}

diff  --git a/llvm/test/Bitcode/upgrade-garbage-collection-for-swift.ll b/llvm/test/Bitcode/upgrade-garbage-collection-for-swift.ll
new file mode 100644
index 000000000000..7cb3b5e93b39
--- /dev/null
+++ b/llvm/test/Bitcode/upgrade-garbage-collection-for-swift.ll
@@ -0,0 +1,41 @@
+; RUN: llvm-as %s -o - | llvm-dis - | FileCheck %s
+
+; The IRUpgrader turns a i32 type "Objective-C Garbage Collection"
+; into i8 value. If the higher bits are set, it adds the module flag for swift info.
+
+target triple = "x86_64-apple-macosx10.15.0"
+
+ at __swift_reflection_version = linkonce_odr hidden constant i16 3
+ at 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]+}} = !{i32 1, !"Objective-C Garbage Collection", i8 0}
+; CHECK: !{{[0-9]+}} = !{i32 1, !"Swift ABI Version", i32 7}
+; CHECK: !{{[0-9]+}} = !{i32 1, !"Swift Major Version", i8 5}
+; CHECK: !{{[0-9]+}} = !{i32 1, !"Swift Minor Version", i8 1}

diff  --git a/llvm/test/Linker/Inputs/empty-objc.ll b/llvm/test/Linker/Inputs/empty-objc.ll
new file mode 100644
index 000000000000..77ccf950a847
--- /dev/null
+++ b/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 1, !"Objective-C Garbage Collection", i32 0}
+!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)"}

diff  --git a/llvm/test/Linker/empty-swift.ll b/llvm/test/Linker/empty-swift.ll
new file mode 100644
index 000000000000..9b5ce1e106de
--- /dev/null
+++ b/llvm/test/Linker/empty-swift.ll
@@ -0,0 +1,42 @@
+; RUN: llvm-link %s %p/Inputs/empty-objc.ll -S | FileCheck %s
+
+; It tests whether Swift bitcode can be successfully linked with Objecitive-C bitcode.
+; During the process, the IRUpgrader turns a i32 type "Objective-C Garbage Collection"
+; into i8 value. If the higher bits are set, it adds the module flag for swift info.
+
+target triple = "x86_64-apple-macosx10.15.0"
+
+ at __swift_reflection_version = linkonce_odr hidden constant i16 3
+ at 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]+}} = !{i32 1, !"Objective-C Garbage Collection", i8 0}
+; CHECK: !{{[0-9]+}} = !{i32 1, !"Swift ABI Version", i32 7}
+; CHECK: !{{[0-9]+}} = !{i32 1, !"Swift Major Version", i8 5}
+; CHECK: !{{[0-9]+}} = !{i32 1, !"Swift Minor Version", i8 1}

diff  --git a/llvm/test/Object/objc-swift-mixed-imageinfo-macho.ll b/llvm/test/Object/objc-swift-mixed-imageinfo-macho.ll
new file mode 100644
index 000000000000..d2518f46cc27
--- /dev/null
+++ b/llvm/test/Object/objc-swift-mixed-imageinfo-macho.ll
@@ -0,0 +1,46 @@
+; RUN: llc -mtriple x86_64-apple-ios -filetype asm -o - %s | FileCheck %s
+; REQUIRES: x86-registered-target
+
+; It checks whether the backend generates IMAGE_INFO from Swift ABI version + major + minor + "Objective-C Garbage Collection".
+
+target triple = "x86_64-apple-macosx10.15.0"
+
+ at llvm.used = appending global [1 x i8*] [i8* bitcast (i16* @__swift_reflection_version to i8*)], section "llvm.metadata", align 8
+ at __swift_reflection_version = linkonce_odr hidden constant i16 3
+
+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" }
+
+!swift.module.flags = !{!0}
+!llvm.linker.options = !{!1, !2, !3}
+!llvm.asan.globals = !{!4}
+!llvm.module.flags = !{!5, !6, !7, !8, !9, !10, !11, !12, !13, !14, !15, !16}
+!llvm.ident = !{!17}
+
+!0 = !{!"standard-library", i1 false}
+!1 = !{!"-lswiftSwiftOnoneSupport"}
+!2 = !{!"-lswiftCore"}
+!3 = !{!"-lobjc"}
+!4 = !{[1 x i8*]* @llvm.used, null, null, i1 false, i1 true}
+!5 = !{i32 2, !"SDK Version", [2 x i32] [i32 10, i32 15]}
+!6 = !{i32 1, !"Objective-C Version", i32 2}
+!7 = !{i32 1, !"Objective-C Image Info Version", i32 0}
+!8 = !{i32 1, !"Objective-C Image Info Section", !"__DATA,__objc_imageinfo,regular,no_dead_strip"}
+!9 = !{i32 1, !"Objective-C Garbage Collection", i8 0}
+!10 = !{i32 1, !"Objective-C Class Properties", i32 64}
+!11 = !{i32 1, !"wchar_size", i32 4}
+!12 = !{i32 7, !"PIC Level", i32 2}
+!13 = !{i32 1, !"Swift Version", i32 7}
+!14 = !{i32 1, !"Swift ABI Version", i32 7}
+!15 = !{i32 1, !"Swift Major Version", i8 5}
+!16 = !{i32 1, !"Swift Minor Version", i8 1}
+!17 = !{!"Apple clang version 11.0.0 (clang-1100.0.33.12)"}
+
+; CHECK: .section	__DATA,__objc_imageinfo,regular,no_dead_strip
+; CHECK: L_OBJC_IMAGE_INFO:
+; CHECK:   .long 0
+; CHECK:   .long 83953472


        


More information about the cfe-commits mailing list