|
| 1 | +; REQUIRES: x86 |
| 2 | +; RUN: rm -rf %t; split-file %s %t |
| 3 | + |
| 4 | +;; Split-LTO bitcode files can have the same symbol (typeinfo) twice in the |
| 5 | +;; symbol table: First undefined in the main file, then defined in the index |
| 6 | +;; file. |
| 7 | +;; When used in --start-lib / --end-lib, ld64.lld creates lazy symbols |
| 8 | +;; for all non-undefined symbols in the bitcode file. |
| 9 | +;; In vtable.o below, the typeinfo __ZTI1S is present once as undefined and |
| 10 | +;; once as defined. The defined version is added as a added as a LazyObject |
| 11 | +;; symbol. |
| 12 | +;; When vtable.o gets loaded due to the __ZN1SC1Ev ref from vtable_use.o, |
| 13 | +;; the first __ZTI1S (undefined) used to cause vtable.o to be extracted |
| 14 | +;; a second time, which used to cause an assert. |
| 15 | +;; See PR59162 for details. |
| 16 | + |
| 17 | +; RUN: opt --thinlto-bc --thinlto-split-lto-unit -o %t/vtable.o %t/vtable.ll |
| 18 | +; RUN: opt --thinlto-bc --thinlto-split-lto-unit -o %t/vtable_use.o %t/vtable_use.ll |
| 19 | + |
| 20 | +; RUN: %lld -lc++ --start-lib %t/vtable.o --end-lib %t/vtable_use.o -o /dev/null |
| 21 | + |
| 22 | +;; Bitcode files created by: |
| 23 | +; % cat vtable.cc |
| 24 | +; struct S { |
| 25 | +; S(); |
| 26 | +; virtual void f(); |
| 27 | +; }; |
| 28 | +; S::S() {} |
| 29 | +; void S::f() {} |
| 30 | + |
| 31 | +; % cat vtable_use.cc |
| 32 | +; struct S { |
| 33 | +; S(); |
| 34 | +; virtual void f(); |
| 35 | +; }; |
| 36 | +; int main() { S s; } |
| 37 | + |
| 38 | +; % clang -c vtable_use.cc vtable.cc -emit-llvm -S -fno-exceptions -arch x86_64 -mmacos-version-min=11 -O1 |
| 39 | + |
| 40 | +; ...and then manually ading `, !type !8, type !9` based on `clang -S -emit-llvm -flto=thin` output, |
| 41 | +; because splitAndWriteThinLTOBitcode() in ThinLTOBitcodeWriter.cpp only splits bitcode |
| 42 | +; if type annotations are present. While at it, also removed unneccessary metadata. |
| 43 | +; (NB: The first comment creates vtable.ll while the latter generates vtable.s! vtable.s |
| 44 | +; contains a few things opt complains about, so we can't use the output of that directly.) |
| 45 | + |
| 46 | +;--- vtable.ll |
| 47 | +; ModuleID = 'vtable.cc' |
| 48 | +source_filename = "vtable.cc" |
| 49 | +target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" |
| 50 | +target triple = "x86_64-apple-macosx11.0.0" |
| 51 | + |
| 52 | +@_ZTV1S = unnamed_addr constant { [3 x ptr] } { [3 x ptr] [ptr null, ptr @_ZTI1S, ptr @_ZN1S1fEv] }, align 8 |
| 53 | +@_ZTVN10__cxxabiv117__class_type_infoE = external global ptr |
| 54 | +@_ZTS1S = constant [3 x i8] c"1S\00", align 1 |
| 55 | +@_ZTI1S = constant { ptr, ptr } { ptr getelementptr inbounds (ptr, ptr @_ZTVN10__cxxabiv117__class_type_infoE, i64 2), ptr @_ZTS1S }, align 8, !type !0, !type !1 |
| 56 | + |
| 57 | +; Function Attrs: mustprogress nofree norecurse nosync nounwind ssp willreturn memory(argmem: write) uwtable |
| 58 | +define void @_ZN1SC2Ev(ptr nocapture noundef nonnull writeonly align 8 dereferenceable(8) %this) unnamed_addr align 2 { |
| 59 | +entry: |
| 60 | + store ptr getelementptr inbounds ({ [3 x ptr] }, ptr @_ZTV1S, i64 0, inrange i32 0, i64 2), ptr %this, align 8 |
| 61 | + ret void |
| 62 | +} |
| 63 | + |
| 64 | +; Function Attrs: mustprogress nofree norecurse nosync nounwind ssp willreturn memory(argmem: write) uwtable |
| 65 | +define void @_ZN1SC1Ev(ptr nocapture noundef nonnull writeonly align 8 dereferenceable(8) %this) unnamed_addr align 2 { |
| 66 | +entry: |
| 67 | + store ptr getelementptr inbounds ({ [3 x ptr] }, ptr @_ZTV1S, i64 0, inrange i32 0, i64 2), ptr %this, align 8 |
| 68 | + ret void |
| 69 | +} |
| 70 | + |
| 71 | +; Function Attrs: mustprogress nofree norecurse nosync nounwind ssp willreturn memory(none) uwtable |
| 72 | +define void @_ZN1S1fEv(ptr nocapture nonnull align 8 %this) unnamed_addr align 2 { |
| 73 | +entry: |
| 74 | + ret void |
| 75 | +} |
| 76 | + |
| 77 | +!0 = !{i64 16, !"_ZTS1S"} |
| 78 | +!1 = !{i64 16, !"_ZTSM1SFvvE.virtual"} |
| 79 | + |
| 80 | +;--- vtable_use.ll |
| 81 | +; ModuleID = 'vtable_use.cc' |
| 82 | +source_filename = "vtable_use.cc" |
| 83 | +target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" |
| 84 | +target triple = "x86_64-apple-macosx11.0.0" |
| 85 | + |
| 86 | +%struct.S = type { ptr } |
| 87 | + |
| 88 | +; Function Attrs: mustprogress noinline norecurse nounwind optnone ssp uwtable |
| 89 | +define noundef i32 @main() { |
| 90 | +entry: |
| 91 | + %s = alloca %struct.S, align 8 |
| 92 | + call void @_ZN1SC1Ev(ptr noundef nonnull align 8 dereferenceable(8) %s) |
| 93 | + ret i32 0 |
| 94 | +} |
| 95 | + |
| 96 | +declare void @_ZN1SC1Ev(ptr noundef nonnull align 8 dereferenceable(8)) unnamed_addr |
0 commit comments