[TTI] getTypeBasedIntrinsicInstrCost - add basic handling for strided load/store...
[llvm-project.git] / llvm / test / ThinLTO / X86 / import_callee_declaration.ll
blob72550fa4d6f0b2f14712465461da7ecec3bb74c7
1 ; "-debug-only" requires asserts.
2 ; REQUIRES: asserts
3 ; RUN: rm -rf %t && split-file %s %t && cd %t
5 ; Generate per-module summaries.
6 ; RUN: opt -module-summary main.ll -o main.bc
7 ; RUN: opt -module-summary lib.ll -o lib.bc
9 ; Generate the combined summary and distributed indices.
11 ; - For function import, set 'import-instr-limit' to 7 and fall back to import
12 ;   function declarations.
13 ; - In main.ll, function 'main' calls 'small_func' and 'large_func'. Both callees
14 ;   are defined in lib.ll. 'small_func' has two indirect callees, one is smaller
15 ;   and the other one is larger. Both callees of 'small_func' are defined in lib.ll.
16 ; - Given the import limit, in main's combined summary, the import type of 'small_func'
17 ;   and 'small_indirect_callee' will be 'definition', and the import type of
18 ;   large* functions and their aliasees will be 'declaration'.
20 ; The test will disassemble combined summaries and check the import type is
21 ; correct. Right now postlink optimizer pipeline doesn't do anything (e.g.,
22 ; import the declaration or de-serialize summary attributes yet) so there is
23 ; nothing to test more than the summary content.
25 ; TODO: Extend this test case to test IR once postlink optimizer makes use of
26 ; the import type for declarations.
28 ; RUN: llvm-lto2 run \
29 ; RUN:   -debug-only=function-import \
30 ; RUN:   -import-instr-limit=7 \
31 ; RUN:   -import-instr-evolution-factor=1.0 \
32 ; RUN:   -import-declaration \
33 ; RUN:   -thinlto-distributed-indexes \
34 ; RUN:   -r=main.bc,main,px \
35 ; RUN:   -r=main.bc,small_func, \
36 ; RUN:   -r=main.bc,large_func, \
37 ; RUN:   -r=main.bc,read_write_global_vars, \
38 ; RUN:   -r=main.bc,external_func, \
39 ; RUN:   -r=lib.bc,callee,pl \
40 ; RUN:   -r=lib.bc,large_indirect_callee,px \
41 ; RUN:   -r=lib.bc,large_indirect_bar,px \
42 ; RUN:   -r=lib.bc,small_func,px \
43 ; RUN:   -r=lib.bc,large_func,px \
44 ; RUN:   -r=lib.bc,read_write_global_vars,px \
45 ; RUN:   -r=lib.bc,large_indirect_callee_alias,px \
46 ; RUN:   -r=lib.bc,large_indirect_bar_alias,px \
47 ; RUN:   -r=lib.bc,calleeAddrs,px -r=lib.bc,calleeAddrs2,px -o summary main.bc lib.bc 2>&1 | FileCheck %s --check-prefix=DUMP
49 ; RUN: llvm-lto -thinlto-action=thinlink -import-declaration -import-instr-limit=7 -import-instr-evolution-factor=1.0 -o combined.index.bc main.bc lib.bc
50 ; RUN: llvm-lto -thinlto-action=distributedindexes -debug-only=function-import -import-declaration -import-instr-limit=7 -import-instr-evolution-factor=1.0 -thinlto-index combined.index.bc main.bc lib.bc 2>&1 | FileCheck %s --check-prefix=DUMP
52 ; DUMP: - 2 function definitions and 4 function declarations imported from lib.bc
54 ; First disassemble per-module summary and find out the GUID for {large_func, large_indirect_callee}.
56 ; RUN: llvm-dis lib.bc -o - | FileCheck %s --check-prefix=LIB-DIS
57 ; LIB-DIS: module: (path: "lib.bc", hash: (0, 0, 0, 0, 0))
58 ; LIB-DIS: gv: (name: "large_func", summaries: {{.*}}) ; guid = 2418497564662708935
59 ; LIB-DIS: gv: (name: "large_indirect_bar_alias", summaries: {{.*}}, aliasee: [[LARGEINDIRECT_BAR:\^[0-9]+]]{{.*}}guid = 13590951773474913315
60 ; LIB-DIS: [[LARGEINDIRECT_BAR]] = gv: (name: "large_indirect_bar", summaries: {{.*}}) ; guid = 13770917885399536773
61 ; LIB-DIS: [[LARGEINDIRECT:\^[0-9]+]] = gv: (name: "large_indirect_callee", summaries: {{.*}}) ; guid = 14343440786664691134
62 ; LIB-DIS: gv: (name: "large_indirect_callee_alias", summaries: {{.*}}, aliasee: [[LARGEINDIRECT]]{{.*}}guid = 16730173943625350469
64 ; Secondly disassemble main's combined summary and verify the import type of
65 ; these two GUIDs are declaration.
67 ; RUN: llvm-dis main.bc.thinlto.bc -o - | FileCheck %s --check-prefix=MAIN-DIS
69 ; MAIN-DIS: [[LIBMOD:\^[0-9]+]] = module: (path: "lib.bc", hash: (0, 0, 0, 0, 0))
70 ; MAIN-DIS: gv: (guid: 2418497564662708935, summaries: (function: (module: [[LIBMOD]], flags: ({{.*}} importType: declaration), insts: 8, {{.*}})))
71 ; When alias is imported as a copy of the aliasee, but the aliasee is not being
72 ; imported by itself, the aliasee should be null.
73 ; MAIN-DIS: gv: (guid: 13590951773474913315, summaries: (alias: (module: [[LIBMOD]], flags: ({{.*}} importType: declaration), aliasee: null)))
74 ; MAIN-DIS: [[LARGEINDIRECT:\^[0-9]+]] = gv: (guid: 14343440786664691134, summaries: (function: (module: [[LIBMOD]], flags: ({{.*}} importType: declaration), insts: 8, {{.*}})))
75 ; MAIN-DIS: gv: (guid: 16730173943625350469, summaries: (alias: (module: [[LIBMOD]], flags: ({{.*}} importType: declaration), aliasee: [[LARGEINDIRECT]])))
77 ; RUN: opt -passes=function-import -import-all-index -summary-file=main.bc.thinlto.bc main.bc -o main-after-import.bc
78 ; RUN: llvm-dis -o - main-after-import.bc | FileCheck %s --check-prefix=MAIN-IMPORT
80 ; Tests that dso_local attribute is applied on a global var from its summary.
81 MAIN-IMPORT: @read_write_global_vars = external dso_local global [1 x ptr]
83 ; Run in-process ThinLTO and tests that
84 ; 1. `callee` remains internalized even if the symbols of its callers
85 ; (large_func, large_indirect_callee, large_indirect_bar) are exported as
86 ; declarations and visible to main module.
87 ; 2. the debugging logs from `function-import` pass are expected.
88 ; Set relocation model to static so the dso_local attribute from a summary is
89 ; applied on the global variable declaration.
91 ; RUN: llvm-lto2 run \
92 ; RUN:   -relocation-model=static \
93 ; RUN:   -debug-only=function-import \
94 ; RUN:   -save-temps \
95 ; RUN:   -thinlto-threads=1 \
96 ; RUN:   -import-instr-limit=7 \
97 ; RUN:   -import-instr-evolution-factor=1.0 \
98 ; RUN:   -import-declaration \
99 ; RUN:   -r=main.bc,main,px \
100 ; RUN:   -r=main.bc,small_func, \
101 ; RUN:   -r=main.bc,large_func, \
102 ; RUN:   -r=main.bc,read_write_global_vars, \
103 ; RUN:   -r=main.bc,external_func, \
104 ; RUN:   -r=lib.bc,callee,pl \
105 ; RUN:   -r=lib.bc,large_indirect_callee,px \
106 ; RUN:   -r=lib.bc,large_indirect_bar,px \
107 ; RUN:   -r=lib.bc,small_func,px \
108 ; RUN:   -r=lib.bc,large_func,px \
109 ; RUN:   -r=lib.bc,read_write_global_vars,px \
110 ; RUN:   -r=lib.bc,large_indirect_callee_alias,px \
111 ; RUN:   -r=lib.bc,large_indirect_bar_alias,px \
112 ; RUN:   -r=lib.bc,calleeAddrs,px -r=lib.bc,calleeAddrs2,px -o in-process main.bc lib.bc 2>&1 | FileCheck %s --check-prefix=IMPORTDUMP
114 ; TODO: Extend this test case to test IR once postlink optimizer makes use of
115 ; the import type for declarations.
116 ; IMPORTDUMP-DAG: Not importing function 11825436545918268459 callee from lib.cc
117 ; IMPORTDUMP-DAG: Is importing function declaration 14343440786664691134 large_indirect_callee from lib.cc
118 ; IMPORTDUMP-DAG: Is importing function definition 13568239288960714650 small_indirect_callee from lib.cc
119 ; IMPORTDUMP-DAG: Is importing function definition 6976996067367342685 small_func from lib.cc
120 ; IMPORTDUMP-DAG: Is importing function declaration 2418497564662708935 large_func from lib.cc
121 ; IMPORTDUMP-DAG: Is importing global declaration 7680325410415171624 calleeAddrs from lib.cc
122 ; IMPORTDUMP-DAG: Is importing alias declaration 16730173943625350469 large_indirect_callee_alias from lib.cc
123 ; IMPORTDUMP-DAG: Is importing alias declaration 13590951773474913315 large_indirect_bar_alias from lib.cc
124 ; IMPORTDUMP-DAG: Not importing function 13770917885399536773 large_indirect_bar
126 ; RUN: llvm-dis in-process.1.3.import.bc -o - | FileCheck %s --check-prefix=IMPORT
128 ; RUN: llvm-dis in-process.2.2.internalize.bc -o - | FileCheck %s --check-prefix=INTERNALIZE
130 ; IMPORT-DAG: define available_externally void @small_func
131 ; IMPORT-DAG: define available_externally hidden void @small_indirect_callee
132 ; IMPORT-DAG: declare void @large_func
133 ; Tests that dso_local attribute is applied on a global var from its summary.
134 ; IMPORT-DAG: @read_write_global_vars = external dso_local global [1 x ptr]
135 ; IMPORT-NOT: large_indirect_callee
136 ; IMPORT-NOT: large_indirect_callee_alias
137 ; IMPORT-NOT: large_indirect_bar
138 ; IMPORT-NOT: large_indirect_bar_alias
140 ; INTERNALIZE: define internal void @callee()
142 ;--- main.ll
143 target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
144 target triple = "x86_64-unknown-linux-gnu"
146 @read_write_global_vars = external global [1 x ptr]
148 define i32 @main() {
149   call void @small_func()
150   call void @large_func()
151   %num = call ptr @external_func(ptr @read_write_global_vars)
152   store ptr %num, ptr getelementptr inbounds ([1 x ptr], ptr @read_write_global_vars, i64 0, i64 0)
153   %res1 = call i32 @external_func(ptr @read_write_global_vars)
154   ret i32 0
157 declare void @small_func()
159 ; large_func without attributes
160 declare void @large_func()
162 declare ptr @external_func(ptr)
164 ;--- lib.ll
165 source_filename = "lib.cc"
166 target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
167 target triple = "x86_64-unknown-linux-gnu"
169 ; Both large_indirect_callee and large_indirect_callee_alias are referenced
170 ; and visible to main.ll.
171 @calleeAddrs = global [3 x ptr] [ptr @large_indirect_callee, ptr @small_indirect_callee, ptr @large_indirect_callee_alias]
173 ; large_indirect_bar_alias is visible to main.ll but its aliasee isn't.
174 @calleeAddrs2 = global [1 x ptr] [ptr @large_indirect_bar_alias]
176 ; @read_write_global_vars is not read-only nor write-only (in main.ll). It's not
177 ; a constant global var and has references, so it's not importable as a definition.
178 @read_write_global_vars = dso_local global [1 x ptr] [ptr @large_indirect_callee]
180 define void @callee() #1 {
181   ret void
184 define void @large_indirect_callee()#2 {
185   call void @callee()
186   call void @callee()
187   call void @callee()
188   call void @callee()
189   call void @callee()
190   call void @callee()
191   call void @callee()
192   ret void
195 define void @large_indirect_bar()#2 {
196   call void @callee()
197   call void @callee()
198   call void @callee()
199   call void @callee()
200   call void @callee()
201   call void @callee()
202   call void @callee()
203   ret void
206 define internal void @small_indirect_callee() #0 {
207 entry:
208   %0 = load ptr, ptr @calleeAddrs2
209   call void %0(), !prof !3
210   ret void
213 @large_indirect_callee_alias = alias void(), ptr @large_indirect_callee
215 @large_indirect_bar_alias = alias void(), ptr @large_indirect_bar
217 define void @small_func() {
218 entry:
219   %0 = load ptr, ptr @calleeAddrs
220   call void %0(), !prof !0
221   %1 = load ptr, ptr getelementptr inbounds ([3 x ptr], ptr @calleeAddrs, i64 0, i64 1)
222   call void %1(), !prof !1
223   %2 = load ptr, ptr getelementptr inbounds ([3 x ptr], ptr @calleeAddrs, i64 0, i64 2)
224   call void %2(), !prof !2
225   ret void
228 define void @large_func() #0 {
229 entry:
230   call void @callee()
231   call void @callee()
232   call void @callee()
233   call void @callee()
234   call void @callee()
235   call void @callee()
236   call void @callee()
237   ret void
240 attributes #0 = { nounwind norecurse }
242 attributes #1 = { noinline }
244 attributes #2 = { norecurse }
246 !0 = !{!"VP", i32 0, i64 1, i64 14343440786664691134, i64 1}
247 !1 = !{!"VP", i32 0, i64 1, i64 13568239288960714650, i64 1}
248 !2 = !{!"VP", i32 0, i64 1, i64 16730173943625350469, i64 1}
249 !3 = !{!"VP", i32 0, i64 1, i64 13590951773474913315, i64 1}