Skip to content

Commit a0cacb6

Browse files
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
1 parent d2f3e5f commit a0cacb6

File tree

9 files changed

+223
-6
lines changed

9 files changed

+223
-6
lines changed

clang/lib/CodeGen/CGObjCMac.cpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5159,15 +5159,18 @@ void CGObjCCommonMac::EmitImageInfo() {
51595159
Mod.addModuleFlag(llvm::Module::Error, "Objective-C Image Info Section",
51605160
llvm::MDString::get(VMContext, Section));
51615161

5162+
auto Int8Ty = llvm::Type::getInt8Ty(VMContext);
51625163
if (CGM.getLangOpts().getGC() == LangOptions::NonGC) {
51635164
// Non-GC overrides those files which specify GC.
5164-
Mod.addModuleFlag(llvm::Module::Override,
5165-
"Objective-C Garbage Collection", (uint32_t)0);
5165+
Mod.addModuleFlag(llvm::Module::Error,
5166+
"Objective-C Garbage Collection",
5167+
llvm::ConstantInt::get(Int8Ty,0));
51665168
} else {
51675169
// Add the ObjC garbage collection value.
51685170
Mod.addModuleFlag(llvm::Module::Error,
51695171
"Objective-C Garbage Collection",
5170-
eImageInfo_GarbageCollected);
5172+
llvm::ConstantInt::get(Int8Ty,
5173+
(uint8_t)eImageInfo_GarbageCollected));
51715174

51725175
if (CGM.getLangOpts().getGC() == LangOptions::GCOnly) {
51735176
// Add the ObjC GC Only value.
@@ -5178,7 +5181,7 @@ void CGObjCCommonMac::EmitImageInfo() {
51785181
llvm::Metadata *Ops[2] = {
51795182
llvm::MDString::get(VMContext, "Objective-C Garbage Collection"),
51805183
llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(
5181-
llvm::Type::getInt32Ty(VMContext), eImageInfo_GarbageCollected))};
5184+
Int8Ty, eImageInfo_GarbageCollected))};
51825185
Mod.addModuleFlag(llvm::Module::Require, "Objective-C GC Only",
51835186
llvm::MDNode::get(VMContext, Ops));
51845187
}

clang/test/CodeGenObjC/image-info.m

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@
88
// CHECK-FRAGILE: !{{[0-9]+}} = !{i32 1, !"Objective-C Version", i32 1}
99
// CHECK-FRAGILE-NEXT: !{{[0-9]+}} = !{i32 1, !"Objective-C Image Info Version", i32 0}
1010
// CHECK-FRAGILE-NEXT: !{{[0-9]+}} = !{i32 1, !"Objective-C Image Info Section", !"__OBJC,__image_info,regular"}
11-
// CHECK-FRAGILE-NEXT: !{{[0-9]+}} = !{i32 4, !"Objective-C Garbage Collection", i32 0}
11+
// CHECK-FRAGILE-NEXT: !{{[0-9]+}} = !{i32 1, !"Objective-C Garbage Collection", i8 0}
1212

1313
// CHECK-NONFRAGILE: !llvm.module.flags = !{{{.*}}}
1414
// CHECK-NONFRAGILE: !{{[0-9]+}} = !{i32 1, !"Objective-C Version", i32 2}
1515
// CHECK-NONFRAGILE-NEXT: !{{[0-9]+}} = !{i32 1, !"Objective-C Image Info Version", i32 0}
1616
// CHECK-NONFRAGILE-NEXT: !{{[0-9]+}} = !{i32 1, !"Objective-C Image Info Section", !"__DATA,__objc_imageinfo,regular,no_dead_strip"}
17-
// CHECK-NONFRAGILE-NEXT: !{{[0-9]+}} = !{i32 4, !"Objective-C Garbage Collection", i32 0}
17+
// CHECK-NONFRAGILE-NEXT: !{{[0-9]+}} = !{i32 1, !"Objective-C Garbage Collection", i8 0}

llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,15 @@ static void GetObjCImageInfo(Module &M, unsigned &Version, unsigned &Flags,
8484
} else if (Key == "Objective-C Image Info Section") {
8585
Section = cast<MDString>(MFE.Val)->getString();
8686
}
87+
// Backend generates L_OBJC_IMAGE_INFO from Swift ABI version + major + minor +
88+
// "Objective-C Garbage Collection".
89+
else if (Key == "Swift ABI Version") {
90+
Flags |= (mdconst::extract<ConstantInt>(MFE.Val)->getZExtValue()) << 8;
91+
} else if (Key == "Swift Major Version") {
92+
Flags |= (mdconst::extract<ConstantInt>(MFE.Val)->getZExtValue()) << 24;
93+
} else if (Key == "Swift Minor Version") {
94+
Flags |= (mdconst::extract<ConstantInt>(MFE.Val)->getZExtValue()) << 16;
95+
}
8796
}
8897
}
8998

llvm/lib/IR/AutoUpgrade.cpp

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4022,6 +4022,12 @@ bool llvm::UpgradeModuleFlags(Module &M) {
40224022
return false;
40234023

40244024
bool HasObjCFlag = false, HasClassProperties = false, Changed = false;
4025+
bool HasSwiftVersionFlag = false;
4026+
uint8_t SwiftMajorVersion, SwiftMinorVersion;
4027+
uint32_t SwiftABIVersion;
4028+
auto Int8Ty = Type::getInt8Ty(M.getContext());
4029+
auto Int32Ty = Type::getInt32Ty(M.getContext());
4030+
40254031
for (unsigned I = 0, E = ModFlags->getNumOperands(); I != E; ++I) {
40264032
MDNode *Op = ModFlags->getOperand(I);
40274033
if (Op->getNumOperands() != 3)
@@ -4067,6 +4073,31 @@ bool llvm::UpgradeModuleFlags(Module &M) {
40674073
}
40684074
}
40694075
}
4076+
4077+
// IRUpgrader turns a i32 type "Objective-C Garbage Collection" into i8 value.
4078+
// If the higher bits are set, it adds new module flag for swift info.
4079+
if (ID->getString() == "Objective-C Garbage Collection") {
4080+
auto Md = dyn_cast<ConstantAsMetadata>(Op->getOperand(2));
4081+
if (Md) {
4082+
assert(Md->getValue() && "Expected non-empty metadata");
4083+
auto Type = Md->getValue()->getType();
4084+
if (Type == Int8Ty)
4085+
continue;
4086+
unsigned Val = Md->getValue()->getUniqueInteger().getZExtValue();
4087+
if ((Val & 0xff) != Val) {
4088+
HasSwiftVersionFlag = true;
4089+
SwiftABIVersion = (Val & 0xff00) >> 8;
4090+
SwiftMajorVersion = (Val & 0xff000000) >> 24;
4091+
SwiftMinorVersion = (Val & 0xff0000) >> 16;
4092+
}
4093+
Metadata *Ops[3] = {
4094+
ConstantAsMetadata::get(ConstantInt::get(Int32Ty,Module::Error)),
4095+
Op->getOperand(1),
4096+
ConstantAsMetadata::get(ConstantInt::get(Int8Ty,Val & 0xff))};
4097+
ModFlags->setOperand(I, MDNode::get(M.getContext(), Ops));
4098+
Changed = true;
4099+
}
4100+
}
40704101
}
40714102

40724103
// "Objective-C Class Properties" is recently added for Objective-C. We
@@ -4080,6 +4111,16 @@ bool llvm::UpgradeModuleFlags(Module &M) {
40804111
Changed = true;
40814112
}
40824113

4114+
if (HasSwiftVersionFlag) {
4115+
M.addModuleFlag(Module::Error, "Swift ABI Version",
4116+
SwiftABIVersion);
4117+
M.addModuleFlag(Module::Error, "Swift Major Version",
4118+
ConstantInt::get(Int8Ty, SwiftMajorVersion));
4119+
M.addModuleFlag(Module::Error, "Swift Minor Version",
4120+
ConstantInt::get(Int8Ty, SwiftMinorVersion));
4121+
Changed = true;
4122+
}
4123+
40834124
return Changed;
40844125
}
40854126

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
; RUN: llvm-as %s -o - | llvm-dis - | FileCheck %s
2+
3+
; The IRUpgrader turns a i32 type "Objective-C Garbage Collection"
4+
; into i8 value.
5+
6+
target triple = "x86_64-apple-macosx10.15.0"
7+
8+
!llvm.module.flags = !{!0, !1, !2, !3, !4, !5, !6, !7}
9+
!llvm.ident = !{!8}
10+
11+
!0 = !{i32 2, !"SDK Version", [2 x i32] [i32 10, i32 15]}
12+
!1 = !{i32 1, !"Objective-C Version", i32 2}
13+
!2 = !{i32 1, !"Objective-C Image Info Version", i32 0}
14+
!3 = !{i32 1, !"Objective-C Image Info Section", !"__DATA,__objc_imageinfo,regular,no_dead_strip"}
15+
!4 = !{i32 1, !"Objective-C Garbage Collection", i32 0}
16+
!5 = !{i32 1, !"Objective-C Class Properties", i32 64}
17+
!6 = !{i32 1, !"wchar_size", i32 4}
18+
!7 = !{i32 7, !"PIC Level", i32 2}
19+
!8 = !{!"Apple clang version 11.0.0 (clang-1100.0.33.12)"}
20+
21+
; CHECK: !{{[0-9]+}} = !{i32 1, !"Objective-C Garbage Collection", i8 0}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
; RUN: llvm-as %s -o - | llvm-dis - | FileCheck %s
2+
3+
; The IRUpgrader turns a i32 type "Objective-C Garbage Collection"
4+
; into i8 value. If the higher bits are set, it adds the module flag for swift info.
5+
6+
target triple = "x86_64-apple-macosx10.15.0"
7+
8+
@__swift_reflection_version = linkonce_odr hidden constant i16 3
9+
@llvm.used = appending global [1 x i8*] [i8* bitcast (i16* @__swift_reflection_version to i8*)], section "llvm.metadata", align 8
10+
11+
define i32 @main(i32 %0, i8** %1) #0 {
12+
%3 = bitcast i8** %1 to i8*
13+
ret i32 0
14+
}
15+
16+
attributes #0 = { "frame-pointer"="all" "target-cpu"="penryn" "target-features"="+cx16,+fxsr,+mmx,+sahf,+sse,+sse2,+sse3,+sse4.1,+ssse3,+x87" }
17+
18+
!llvm.module.flags = !{!0, !1, !2, !3, !4, !5, !6, !7, !8}
19+
!swift.module.flags = !{!9}
20+
!llvm.linker.options = !{!10, !11, !12}
21+
!llvm.asan.globals = !{!13}
22+
23+
!0 = !{i32 2, !"SDK Version", [2 x i32] [i32 10, i32 15]}
24+
!1 = !{i32 1, !"Objective-C Version", i32 2}
25+
!2 = !{i32 1, !"Objective-C Image Info Version", i32 0}
26+
!3 = !{i32 1, !"Objective-C Image Info Section", !"__DATA,__objc_imageinfo,regular,no_dead_strip"}
27+
!4 = !{i32 4, !"Objective-C Garbage Collection", i32 83953408}
28+
!5 = !{i32 1, !"Objective-C Class Properties", i32 64}
29+
!6 = !{i32 1, !"wchar_size", i32 4}
30+
!7 = !{i32 7, !"PIC Level", i32 2}
31+
!8 = !{i32 1, !"Swift Version", i32 7}
32+
!9 = !{!"standard-library", i1 false}
33+
!10 = !{!"-lswiftSwiftOnoneSupport"}
34+
!11 = !{!"-lswiftCore"}
35+
!12 = !{!"-lobjc"}
36+
!13 = !{[1 x i8*]* @llvm.used, null, null, i1 false, i1 true}
37+
38+
; CHECK: !{{[0-9]+}} = !{i32 1, !"Objective-C Garbage Collection", i8 0}
39+
; CHECK: !{{[0-9]+}} = !{i32 1, !"Swift ABI Version", i32 7}
40+
; CHECK: !{{[0-9]+}} = !{i32 1, !"Swift Major Version", i8 5}
41+
; CHECK: !{{[0-9]+}} = !{i32 1, !"Swift Minor Version", i8 1}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
target triple = "x86_64-apple-macosx10.15.0"
2+
3+
!llvm.module.flags = !{!0, !1, !2, !3, !4, !5, !6, !7}
4+
!llvm.ident = !{!8}
5+
6+
!0 = !{i32 2, !"SDK Version", [2 x i32] [i32 10, i32 15]}
7+
!1 = !{i32 1, !"Objective-C Version", i32 2}
8+
!2 = !{i32 1, !"Objective-C Image Info Version", i32 0}
9+
!3 = !{i32 1, !"Objective-C Image Info Section", !"__DATA,__objc_imageinfo,regular,no_dead_strip"}
10+
!4 = !{i32 1, !"Objective-C Garbage Collection", i32 0}
11+
!5 = !{i32 1, !"Objective-C Class Properties", i32 64}
12+
!6 = !{i32 1, !"wchar_size", i32 4}
13+
!7 = !{i32 7, !"PIC Level", i32 2}
14+
!8 = !{!"Apple clang version 11.0.0 (clang-1100.0.33.12)"}

llvm/test/Linker/empty-swift.ll

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
; RUN: llvm-link %s %p/Inputs/empty-objc.ll -S | FileCheck %s
2+
3+
; It tests whether Swift bitcode can be successfully linked with Objecitive-C bitcode.
4+
; During the process, the IRUpgrader turns a i32 type "Objective-C Garbage Collection"
5+
; into i8 value. If the higher bits are set, it adds the module flag for swift info.
6+
7+
target triple = "x86_64-apple-macosx10.15.0"
8+
9+
@__swift_reflection_version = linkonce_odr hidden constant i16 3
10+
@llvm.used = appending global [1 x i8*] [i8* bitcast (i16* @__swift_reflection_version to i8*)], section "llvm.metadata", align 8
11+
12+
define i32 @main(i32 %0, i8** %1) #0 {
13+
%3 = bitcast i8** %1 to i8*
14+
ret i32 0
15+
}
16+
17+
attributes #0 = { "frame-pointer"="all" "target-cpu"="penryn" "target-features"="+cx16,+fxsr,+mmx,+sahf,+sse,+sse2,+sse3,+sse4.1,+ssse3,+x87" }
18+
19+
!llvm.module.flags = !{!0, !1, !2, !3, !4, !5, !6, !7, !8}
20+
!swift.module.flags = !{!9}
21+
!llvm.linker.options = !{!10, !11, !12}
22+
!llvm.asan.globals = !{!13}
23+
24+
!0 = !{i32 2, !"SDK Version", [2 x i32] [i32 10, i32 15]}
25+
!1 = !{i32 1, !"Objective-C Version", i32 2}
26+
!2 = !{i32 1, !"Objective-C Image Info Version", i32 0}
27+
!3 = !{i32 1, !"Objective-C Image Info Section", !"__DATA,__objc_imageinfo,regular,no_dead_strip"}
28+
!4 = !{i32 4, !"Objective-C Garbage Collection", i32 83953408}
29+
!5 = !{i32 1, !"Objective-C Class Properties", i32 64}
30+
!6 = !{i32 1, !"wchar_size", i32 4}
31+
!7 = !{i32 7, !"PIC Level", i32 2}
32+
!8 = !{i32 1, !"Swift Version", i32 7}
33+
!9 = !{!"standard-library", i1 false}
34+
!10 = !{!"-lswiftSwiftOnoneSupport"}
35+
!11 = !{!"-lswiftCore"}
36+
!12 = !{!"-lobjc"}
37+
!13 = !{[1 x i8*]* @llvm.used, null, null, i1 false, i1 true}
38+
39+
; CHECK: !{{[0-9]+}} = !{i32 1, !"Objective-C Garbage Collection", i8 0}
40+
; CHECK: !{{[0-9]+}} = !{i32 1, !"Swift ABI Version", i32 7}
41+
; CHECK: !{{[0-9]+}} = !{i32 1, !"Swift Major Version", i8 5}
42+
; CHECK: !{{[0-9]+}} = !{i32 1, !"Swift Minor Version", i8 1}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
; RUN: llc -mtriple x86_64-apple-ios -filetype asm -o - %s | FileCheck %s
2+
; REQUIRES: x86-registered-target
3+
4+
; It checks whether the backend generates IMAGE_INFO from Swift ABI version + major + minor + "Objective-C Garbage Collection".
5+
6+
target triple = "x86_64-apple-macosx10.15.0"
7+
8+
@llvm.used = appending global [1 x i8*] [i8* bitcast (i16* @__swift_reflection_version to i8*)], section "llvm.metadata", align 8
9+
@__swift_reflection_version = linkonce_odr hidden constant i16 3
10+
11+
define i32 @main(i32 %0, i8** %1) #0 {
12+
%3 = bitcast i8** %1 to i8*
13+
ret i32 0
14+
}
15+
16+
attributes #0 = { "frame-pointer"="all" "target-cpu"="penryn" "target-features"="+cx16,+fxsr,+mmx,+sahf,+sse,+sse2,+sse3,+sse4.1,+ssse3,+x87" }
17+
18+
!swift.module.flags = !{!0}
19+
!llvm.linker.options = !{!1, !2, !3}
20+
!llvm.asan.globals = !{!4}
21+
!llvm.module.flags = !{!5, !6, !7, !8, !9, !10, !11, !12, !13, !14, !15, !16}
22+
!llvm.ident = !{!17}
23+
24+
!0 = !{!"standard-library", i1 false}
25+
!1 = !{!"-lswiftSwiftOnoneSupport"}
26+
!2 = !{!"-lswiftCore"}
27+
!3 = !{!"-lobjc"}
28+
!4 = !{[1 x i8*]* @llvm.used, null, null, i1 false, i1 true}
29+
!5 = !{i32 2, !"SDK Version", [2 x i32] [i32 10, i32 15]}
30+
!6 = !{i32 1, !"Objective-C Version", i32 2}
31+
!7 = !{i32 1, !"Objective-C Image Info Version", i32 0}
32+
!8 = !{i32 1, !"Objective-C Image Info Section", !"__DATA,__objc_imageinfo,regular,no_dead_strip"}
33+
!9 = !{i32 1, !"Objective-C Garbage Collection", i8 0}
34+
!10 = !{i32 1, !"Objective-C Class Properties", i32 64}
35+
!11 = !{i32 1, !"wchar_size", i32 4}
36+
!12 = !{i32 7, !"PIC Level", i32 2}
37+
!13 = !{i32 1, !"Swift Version", i32 7}
38+
!14 = !{i32 1, !"Swift ABI Version", i32 7}
39+
!15 = !{i32 1, !"Swift Major Version", i8 5}
40+
!16 = !{i32 1, !"Swift Minor Version", i8 1}
41+
!17 = !{!"Apple clang version 11.0.0 (clang-1100.0.33.12)"}
42+
43+
; CHECK: .section __DATA,__objc_imageinfo,regular,no_dead_strip
44+
; CHECK: L_OBJC_IMAGE_INFO:
45+
; CHECK: .long 0
46+
; CHECK: .long 83953472

0 commit comments

Comments
 (0)