1; REQUIRES: x86, shell 2 3;; Keep __profd_foo in a nodeduplicate comdat, despite a comdat of the same name 4;; in a previous object file. 5 6;; Regular LTO 7 8; RUN: rm -rf %t && split-file %s %t 9; RUN: llvm-as %t/a.ll -o %t/a.bc 10; RUN: llvm-as %t/b.ll -o %t/b.bc 11; RUN: llvm-as %t/c.ll -o %t/c.bc 12 13; RUN: ld.lld --save-temps -u foo %t/a.bc --start-lib %t/b.bc --end-lib -o %t/ab 14; RUN: FileCheck %s --check-prefix=RESOL_AB < %t/ab.resolution.txt 15; RUN: llvm-readelf -x .data %t/ab | FileCheck %s --check-prefix=DATA 16 17; RESOL_AB: -r={{.*}}b.bc,__profc_foo,pl{{$}} 18 19;; .data contains a.bc:data. b.bc:data and c.bc:data are discarded. 20; DATA: 0x[[#%x,]] 01000000 00000000 ........ 21 22;; __profc_foo from c.bc is non-prevailing and thus discarded. 23; RUN: ld.lld --save-temps -u foo -u c %t/a.bc --start-lib %t/b.bc %t/c.bc --end-lib -o %t/abc 24; RUN: FileCheck %s --check-prefix=RESOL_ABC < %t/abc.resolution.txt 25; RUN: llvm-readelf -x .data %t/abc | FileCheck %s --check-prefix=DATA 26 27; RESOL_ABC: -r={{.*}}b.bc,__profc_foo,pl{{$}} 28; RESOL_ABC: -r={{.*}}c.bc,__profc_foo,{{$}} 29 30;; ThinLTO 31 32; RUN: rm -rf %t && split-file %s %t 33; RUN: opt --module-summary %t/a.ll -o %t/a.bc 34; RUN: opt --module-summary %t/b.ll -o %t/b.bc 35; RUN: opt --module-summary %t/c.ll -o %t/c.bc 36 37; RUN: ld.lld --thinlto-index-only --save-temps -u foo %t/a.bc %t/b.bc -o %t/ab 38; RUN: FileCheck %s --check-prefix=RESOL_AB < %t/ab.resolution.txt 39; RUN: (llvm-dis < %t/b.bc && llvm-dis < %t/b.bc.thinlto.bc) | FileCheck %s --check-prefix=IR_AB 40; RUN: ld.lld -u foo %t/a.bc %t/b.bc -o %t/ab 41; RUN: llvm-readelf -x .data %t/ab | FileCheck %s --check-prefix=DATA 42 43; RUN: ld.lld --thinlto-index-only --save-temps -u foo %t/a.bc --start-lib %t/b.bc --end-lib -o %t/ab 44; RUN: FileCheck %s --check-prefix=RESOL_AB < %t/ab.resolution.txt 45; RUN: (llvm-dis < %t/b.bc && llvm-dis < %t/b.bc.thinlto.bc) | FileCheck %s --check-prefix=IR_AB 46; RUN: ld.lld -u foo %t/a.bc --start-lib %t/b.bc --end-lib -o %t/ab 47; RUN: llvm-readelf -x .data %t/ab | FileCheck %s --check-prefix=DATA 48 49; RUN: ld.lld --thinlto-index-only --save-temps -u foo -u c %t/a.bc --start-lib %t/b.bc %t/c.bc --end-lib -o %t/abc 50; RUN: FileCheck %s --check-prefix=RESOL_ABC < %t/abc.resolution.txt 51; RUN: (llvm-dis < %t/b.bc && llvm-dis < %t/b.bc.thinlto.bc) | FileCheck %s --check-prefix=IR_ABC 52; RUN: ld.lld -u foo %t/a.bc --start-lib %t/b.bc %t/c.bc --end-lib -o %t/abc 53; RUN: llvm-readelf -x .data %t/abc | FileCheck %s --check-prefix=DATA 54 55; IR_AB-DAG: gv: (name: "__profd_foo", {{.*}} guid = [[PROFD:[0-9]+]] 56; IR_AB-DAG: gv: (name: "__profc_foo", {{.*}} guid = [[PROFC:[0-9]+]] 57 58;; Check extra attributes. b.bc:__profc_foo is prevailing, so it can be internalized. 59; IR_AB-DAG: gv: (guid: [[PROFD]], summaries: (variable: (module: ^0, flags: (linkage: private, visibility: default, notEligibleToImport: 0, live: 0, dsoLocal: 1, canAutoHide: 0, importType: definition), varFlags: (readonly: 0, writeonly: 0, constant: 0), 60; IR_AB-DAG: gv: (guid: [[PROFC]], summaries: (variable: (module: ^0, flags: (linkage: internal, visibility: hidden, notEligibleToImport: 0, live: 1, dsoLocal: 1, canAutoHide: 0, importType: definition), varFlags: (readonly: 0, writeonly: 0, constant: 0)))) 61 62; IR_ABC-DAG: gv: (name: "__profd_foo", {{.*}} guid = [[PROFD:[0-9]+]] 63; IR_ABC-DAG: gv: (name: "__profc_foo", {{.*}} guid = [[PROFC:[0-9]+]] 64 65;; b.bc:__profc_foo prevails c.bc:__profc_foo, so it is exported and therefore not internalized. 66; IR_ABC-DAG: gv: (guid: [[PROFD]], summaries: (variable: (module: ^0, flags: (linkage: private, visibility: default, notEligibleToImport: 0, live: 0, dsoLocal: 1, canAutoHide: 0, importType: definition), varFlags: (readonly: 0, writeonly: 0, constant: 0), 67; IR_ABC-DAG: gv: (guid: [[PROFC]], summaries: (variable: (module: ^0, flags: (linkage: weak, visibility: hidden, notEligibleToImport: 0, live: 1, dsoLocal: 1, canAutoHide: 0, importType: definition), varFlags: (readonly: 0, writeonly: 0, constant: 0)))) 68 69;--- a.ll 70target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" 71target triple = "x86_64-unknown-linux-gnu" 72 73$__profc_foo = comdat nodeduplicate 74@__profc_foo = private global i64 1, comdat, align 8 75@__profd_foo = private global ptr @__profc_foo, comdat($__profc_foo), align 8 76 77declare void @b() 78 79define i64 @foo() { 80 %v = load i64, ptr @__profc_foo 81 %inc = add i64 1, %v 82 store i64 %inc, ptr @__profc_foo 83 ret i64 %inc 84} 85 86define void @_start() { 87 call void @b() 88 ret void 89} 90 91;--- b.ll 92target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" 93target triple = "x86_64-unknown-linux-gnu" 94 95$__profc_foo = comdat nodeduplicate 96@__profc_foo = weak hidden global i64 2, comdat, align 8 97@__profd_foo = private global ptr @__profc_foo, comdat($__profc_foo) 98 99define weak i64 @foo() { 100 %v = load i64, ptr @__profc_foo 101 %inc = add i64 1, %v 102 store i64 %inc, ptr @__profc_foo 103 ret i64 %inc 104} 105 106define void @b() { 107 ret void 108} 109 110;--- c.ll 111target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" 112target triple = "x86_64-unknown-linux-gnu" 113 114$__profc_foo = comdat nodeduplicate 115@__profc_foo = weak hidden global i64 3, comdat, align 8 116@__profd_foo = private global ptr @__profc_foo, comdat($__profc_foo) 117 118define weak i64 @foo() { 119 %v = load i64, ptr @__profc_foo 120 %inc = add i64 1, %v 121 store i64 %inc, ptr @__profc_foo 122 ret i64 %inc 123} 124 125define void @c() { 126 ret void 127} 128