xref: /llvm-project/llvm/test/ThinLTO/X86/workload.ll (revision ed10fba1b274b81e1f119eab7a074a273df9ec32)
1; Test workload based importing via -thinlto-workload-def
2;
3; Set up
4; RUN: rm -rf %t
5; RUN: mkdir -p %t
6; RUN: split-file %s %t
7;
8; RUN: opt -module-summary %t/m1.ll -o %t/m1.bc
9; RUN: opt -module-summary %t/m2.ll -o %t/m2.bc
10; RUN: opt -module-summary %t/m3.ll -o %t/m3.bc
11; RUN: rm -rf %t_baseline
12; RUN: rm -rf %t_exp
13; RUN: mkdir -p %t_baseline
14; RUN: mkdir -p %t_exp
15;
16; Normal run. m1 shouldn't get m2_f1 because it's not referenced from there.
17;
18; RUN: llvm-lto2 run %t/m1.bc %t/m2.bc %t/m3.bc \
19; RUN:  -o %t_baseline/result.o -save-temps \
20; RUN:  -r %t/m1.bc,m1_f1,plx \
21; RUN:  -r %t/m1.bc,interposable_f,p \
22; RUN:  -r %t/m1.bc,noninterposable_f \
23; RUN:  -r %t/m1.bc,m1_variant \
24; RUN:  -r %t/m1.bc,m2_f1_alias \
25; RUN:  -r %t/m2.bc,m2_f1,plx \
26; RUN:  -r %t/m2.bc,m2_f1_alias,plx \
27; RUN:  -r %t/m2.bc,interposable_f \
28; RUN:  -r %t/m2.bc,noninterposable_f,p \
29; RUN:  -r %t/m2.bc,m2_variant \
30; RUN:  -r %t/m3.bc,m1_f1 \
31; RUN:  -r %t/m3.bc,m3_f1,plx
32; RUN: llvm-dis %t_baseline/result.o.1.3.import.bc -o - | FileCheck %s --check-prefix=NOPROF
33;
34; NOPROF-NOT: m2_f1()
35;
36; The run with workload definitions - same other options.
37;
38; RUN: echo '{ \
39; RUN:    "m1_f1": ["m1_f1", "m2_f1", "m2_f1_alias", "interposable_f", "noninterposable_f"], \
40; RUN:    "m2_f1": ["m1_f1", "m1_f2", "interposable_f"] \
41; RUN:  }' > %t_exp/workload_defs.json
42;
43; RUN: llvm-lto2 run %t/m1.bc %t/m2.bc %t/m3.bc \
44; RUN:  -o %t_exp/result.o -save-temps \
45; RUN:  -thinlto-workload-def=%t_exp/workload_defs.json \
46; RUN:  -r %t/m1.bc,m1_f1,plx \
47; RUN:  -r %t/m1.bc,interposable_f,p \
48; RUN:  -r %t/m1.bc,noninterposable_f \
49; RUN:  -r %t/m1.bc,m1_variant \
50; RUN:  -r %t/m1.bc,m2_f1_alias \
51; RUN:  -r %t/m2.bc,m2_f1,plx \
52; RUN:  -r %t/m2.bc,m2_f1_alias,plx \
53; RUN:  -r %t/m2.bc,interposable_f \
54; RUN:  -r %t/m2.bc,noninterposable_f,p \
55; RUN:  -r %t/m2.bc,m2_variant \
56; RUN:  -r %t/m3.bc,m1_f1 \
57; RUN:  -r %t/m3.bc,m3_f1,plx
58; RUN: llvm-dis %t_exp/result.o.1.3.import.bc -o - | FileCheck %s --check-prefix=FIRST
59; RUN: llvm-dis %t_exp/result.o.2.3.import.bc -o - | FileCheck %s --check-prefix=SECOND
60; RUN: llvm-dis %t_exp/result.o.3.3.import.bc -o - | FileCheck %s --check-prefix=THIRD
61;
62; The third module is bitwse-identical to the "normal" run, as the workload
63; defintion doesn't mention it.
64;
65; RUN: diff %t_baseline/result.o.3.3.import.bc %t_exp/result.o.3.3.import.bc
66;
67; This time, we expect m1 to have m2_f1 and the m2 variant of both interposable_f
68; and noninterposable_f
69;
70; FIRST-LABEL:  @m1_f1
71; FIRST-LABEL:  @m1_f2.llvm.0
72;
73; @interposable_f is prevailing in m1, so it won't be imported
74; FIRST-LABEL:  define void @interposable_f
75; FIRST-NEXT:   call void @m1_variant
76;
77; FIRST-LABEL:  @m2_f1
78;
79; @noninterposable_f is prevailing in m2 so it will be imported from there.
80; FIRST-LABEL:  define available_externally void @noninterposable_f
81; FIRST-NEXT:   call void @m2_variant
82;
83; FIRST-LABEL:  define available_externally void @m2_f1_alias
84;
85; For the second module we expect to get the functions imported from m1: m1_f1
86; and m1_f2. interposable_f will also come from m1 because that's where its
87; prevailing variant is.
88; SECOND-LABEL: @m2_f1
89;
90; SECOND-LABEL: define weak_odr void @noninterposable_f
91; SECOND-NEXT:  call void @m2_variant()
92; SECOND-LABEL: @m1_f1
93; SECOND-LABEL: define available_externally hidden void @m1_f2.llvm.0
94;
95; we import @interposable_f from m1, the prevailing variant.
96; SECOND-LABEL: define available_externally void @interposable_f
97; SECOND-NEXT:  call void @m1_variant
98;
99; The third module remains unchanged. The more robust test is the `diff` test
100; in the run lines above.
101; THIRD-LABEL: define available_externally void @m1_f1
102
103;--- m1.ll
104target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
105target triple = "x86_64-pc-linux-gnu"
106
107declare void @m1_variant()
108declare void @m2_f1_alias()
109
110define dso_local void @m1_f1() {
111  call void @m1_f2()
112  call void @noninterposable_f()
113  ret void
114}
115
116define internal void @m1_f2() {
117  call void @interposable_f()
118  ret void
119}
120
121define external void @interposable_f() {
122  call void @m1_variant()
123  ret void
124}
125
126define linkonce_odr void @noninterposable_f() {
127  call void @m1_variant()
128  ret void
129}
130;--- m2.ll
131target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
132target triple = "x86_64-pc-linux-gnu"
133
134declare void @m2_variant()
135
136define dso_local void @m2_f1() {
137  call void @interposable_f()
138  call void @noninterposable_f()
139  ret void
140}
141
142@m2_f1_alias = alias void (...), ptr @m2_f1
143
144define weak void @interposable_f() {
145  call void @m2_variant()
146  ret void
147}
148
149define linkonce_odr void @noninterposable_f() {
150  call void @m2_variant()
151  ret void
152}
153;--- m3.ll
154target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
155target triple = "x86_64-pc-linux-gnu"
156
157declare void @m1_f1()
158
159define dso_local void @m3_f1() {
160  call void @m1_f1()
161  ret void
162}
163