• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1; RUN: opt < %s -inline -S | FileCheck %s
2target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128"
3
4define i32 @noattr_callee(i32 %i) {
5  ret i32 %i
6}
7
8define i32 @sanitize_address_callee(i32 %i) sanitize_address {
9  ret i32 %i
10}
11
12define i32 @sanitize_thread_callee(i32 %i) sanitize_thread {
13  ret i32 %i
14}
15
16define i32 @sanitize_memory_callee(i32 %i) sanitize_memory {
17  ret i32 %i
18}
19
20define i32 @safestack_callee(i32 %i) safestack {
21  ret i32 %i
22}
23
24define i32 @alwaysinline_callee(i32 %i) alwaysinline {
25  ret i32 %i
26}
27
28define i32 @alwaysinline_sanitize_address_callee(i32 %i) alwaysinline sanitize_address {
29  ret i32 %i
30}
31
32define i32 @alwaysinline_sanitize_thread_callee(i32 %i) alwaysinline sanitize_thread {
33  ret i32 %i
34}
35
36define i32 @alwaysinline_sanitize_memory_callee(i32 %i) alwaysinline sanitize_memory {
37  ret i32 %i
38}
39
40define i32 @alwaysinline_safestack_callee(i32 %i) alwaysinline safestack {
41  ret i32 %i
42}
43
44
45; Check that:
46;  * noattr callee is inlined into noattr caller,
47;  * sanitize_(address|memory|thread) callee is not inlined into noattr caller,
48;  * alwaysinline callee is always inlined no matter what sanitize_* attributes are present.
49
50define i32 @test_no_sanitize_address(i32 %arg) {
51  %x1 = call i32 @noattr_callee(i32 %arg)
52  %x2 = call i32 @sanitize_address_callee(i32 %x1)
53  %x3 = call i32 @alwaysinline_callee(i32 %x2)
54  %x4 = call i32 @alwaysinline_sanitize_address_callee(i32 %x3)
55  ret i32 %x4
56; CHECK-LABEL: @test_no_sanitize_address(
57; CHECK-NEXT: @sanitize_address_callee
58; CHECK-NEXT: ret i32
59}
60
61define i32 @test_no_sanitize_memory(i32 %arg) {
62  %x1 = call i32 @noattr_callee(i32 %arg)
63  %x2 = call i32 @sanitize_memory_callee(i32 %x1)
64  %x3 = call i32 @alwaysinline_callee(i32 %x2)
65  %x4 = call i32 @alwaysinline_sanitize_memory_callee(i32 %x3)
66  ret i32 %x4
67; CHECK-LABEL: @test_no_sanitize_memory(
68; CHECK-NEXT: @sanitize_memory_callee
69; CHECK-NEXT: ret i32
70}
71
72define i32 @test_no_sanitize_thread(i32 %arg) {
73  %x1 = call i32 @noattr_callee(i32 %arg)
74  %x2 = call i32 @sanitize_thread_callee(i32 %x1)
75  %x3 = call i32 @alwaysinline_callee(i32 %x2)
76  %x4 = call i32 @alwaysinline_sanitize_thread_callee(i32 %x3)
77  ret i32 %x4
78; CHECK-LABEL: @test_no_sanitize_thread(
79; CHECK-NEXT: @sanitize_thread_callee
80; CHECK-NEXT: ret i32
81}
82
83
84; Check that:
85;  * noattr callee is not inlined into sanitize_(address|memory|thread) caller,
86;  * sanitize_(address|memory|thread) callee is inlined into the caller with the same attribute,
87;  * alwaysinline callee is always inlined no matter what sanitize_* attributes are present.
88
89define i32 @test_sanitize_address(i32 %arg) sanitize_address {
90  %x1 = call i32 @noattr_callee(i32 %arg)
91  %x2 = call i32 @sanitize_address_callee(i32 %x1)
92  %x3 = call i32 @alwaysinline_callee(i32 %x2)
93  %x4 = call i32 @alwaysinline_sanitize_address_callee(i32 %x3)
94  ret i32 %x4
95; CHECK-LABEL: @test_sanitize_address(
96; CHECK-NEXT: @noattr_callee
97; CHECK-NEXT: ret i32
98}
99
100define i32 @test_sanitize_memory(i32 %arg) sanitize_memory {
101  %x1 = call i32 @noattr_callee(i32 %arg)
102  %x2 = call i32 @sanitize_memory_callee(i32 %x1)
103  %x3 = call i32 @alwaysinline_callee(i32 %x2)
104  %x4 = call i32 @alwaysinline_sanitize_memory_callee(i32 %x3)
105  ret i32 %x4
106; CHECK-LABEL: @test_sanitize_memory(
107; CHECK-NEXT: @noattr_callee
108; CHECK-NEXT: ret i32
109}
110
111define i32 @test_sanitize_thread(i32 %arg) sanitize_thread {
112  %x1 = call i32 @noattr_callee(i32 %arg)
113  %x2 = call i32 @sanitize_thread_callee(i32 %x1)
114  %x3 = call i32 @alwaysinline_callee(i32 %x2)
115  %x4 = call i32 @alwaysinline_sanitize_thread_callee(i32 %x3)
116  ret i32 %x4
117; CHECK-LABEL: @test_sanitize_thread(
118; CHECK-NEXT: @noattr_callee
119; CHECK-NEXT: ret i32
120}
121
122define i32 @test_safestack(i32 %arg) safestack {
123  %x1 = call i32 @noattr_callee(i32 %arg)
124  %x2 = call i32 @safestack_callee(i32 %x1)
125  %x3 = call i32 @alwaysinline_callee(i32 %x2)
126  %x4 = call i32 @alwaysinline_safestack_callee(i32 %x3)
127  ret i32 %x4
128; CHECK-LABEL: @test_safestack(
129; CHECK-NEXT: @noattr_callee
130; CHECK-NEXT: ret i32
131}
132
133; Check that a function doesn't get inlined if target-cpu strings don't match
134; exactly.
135define i32 @test_target_cpu_callee0(i32 %i) "target-cpu"="corei7" {
136  ret i32 %i
137}
138
139define i32 @test_target_cpu0(i32 %i) "target-cpu"="corei7" {
140  %1 = call i32 @test_target_cpu_callee0(i32 %i)
141  ret i32 %1
142; CHECK-LABEL: @test_target_cpu0(
143; CHECK-NOT: @test_target_cpu_callee0
144}
145
146define i32 @test_target_cpu_callee1(i32 %i) "target-cpu"="x86-64" {
147  ret i32 %i
148}
149
150define i32 @test_target_cpu1(i32 %i) "target-cpu"="corei7" {
151  %1 = call i32 @test_target_cpu_callee1(i32 %i)
152  ret i32 %1
153; CHECK-LABEL: @test_target_cpu1(
154; CHECK-NEXT: @test_target_cpu_callee1
155; CHECK-NEXT: ret i32
156}
157
158; Check that a function doesn't get inlined if target-features strings don't
159; match exactly.
160define i32 @test_target_features_callee0(i32 %i)  "target-features"="+sse4.2" {
161  ret i32 %i
162}
163
164define i32 @test_target_features0(i32 %i) "target-features"="+sse4.2" {
165  %1 = call i32 @test_target_features_callee0(i32 %i)
166  ret i32 %1
167; CHECK-LABEL: @test_target_features0(
168; CHECK-NOT: @test_target_features_callee0
169}
170
171define i32 @test_target_features_callee1(i32 %i) "target-features"="+avx2" {
172  ret i32 %i
173}
174
175define i32 @test_target_features1(i32 %i) "target-features"="+sse4.2" {
176  %1 = call i32 @test_target_features_callee1(i32 %i)
177  ret i32 %1
178; CHECK-LABEL: @test_target_features1(
179; CHECK-NEXT: @test_target_features_callee1
180; CHECK-NEXT: ret i32
181}
182
183define i32 @less-precise-fpmad_callee0(i32 %i) "less-precise-fpmad"="false" {
184  ret i32 %i
185; CHECK: @less-precise-fpmad_callee0(i32 %i) [[FPMAD_FALSE:#[0-9]+]] {
186; CHECK-NEXT: ret i32
187}
188
189define i32 @less-precise-fpmad_callee1(i32 %i) "less-precise-fpmad"="true" {
190  ret i32 %i
191; CHECK: @less-precise-fpmad_callee1(i32 %i) [[FPMAD_TRUE:#[0-9]+]] {
192; CHECK-NEXT: ret i32
193}
194
195define i32 @test_less-precise-fpmad0(i32 %i) "less-precise-fpmad"="false" {
196  %1 = call i32 @less-precise-fpmad_callee0(i32 %i)
197  ret i32 %1
198; CHECK: @test_less-precise-fpmad0(i32 %i) [[FPMAD_FALSE]] {
199; CHECK-NEXT: ret i32
200}
201
202define i32 @test_less-precise-fpmad1(i32 %i) "less-precise-fpmad"="false" {
203  %1 = call i32 @less-precise-fpmad_callee1(i32 %i)
204  ret i32 %1
205; CHECK: @test_less-precise-fpmad1(i32 %i) [[FPMAD_FALSE]] {
206; CHECK-NEXT: ret i32
207}
208
209define i32 @test_less-precise-fpmad2(i32 %i) "less-precise-fpmad"="true" {
210  %1 = call i32 @less-precise-fpmad_callee0(i32 %i)
211  ret i32 %1
212; CHECK: @test_less-precise-fpmad2(i32 %i) [[FPMAD_FALSE]] {
213; CHECK-NEXT: ret i32
214}
215
216define i32 @test_less-precise-fpmad3(i32 %i) "less-precise-fpmad"="true" {
217  %1 = call i32 @less-precise-fpmad_callee1(i32 %i)
218  ret i32 %1
219; CHECK: @test_less-precise-fpmad3(i32 %i) [[FPMAD_TRUE]] {
220; CHECK-NEXT: ret i32
221}
222
223define i32 @no-implicit-float_callee0(i32 %i) {
224  ret i32 %i
225; CHECK: @no-implicit-float_callee0(i32 %i) {
226; CHECK-NEXT: ret i32
227}
228
229define i32 @no-implicit-float_callee1(i32 %i) noimplicitfloat {
230  ret i32 %i
231; CHECK: @no-implicit-float_callee1(i32 %i) [[NOIMPLICITFLOAT:#[0-9]+]] {
232; CHECK-NEXT: ret i32
233}
234
235define i32 @test_no-implicit-float0(i32 %i) {
236  %1 = call i32 @no-implicit-float_callee0(i32 %i)
237  ret i32 %1
238; CHECK: @test_no-implicit-float0(i32 %i) {
239; CHECK-NEXT: ret i32
240}
241
242define i32 @test_no-implicit-float1(i32 %i) {
243  %1 = call i32 @no-implicit-float_callee1(i32 %i)
244  ret i32 %1
245; CHECK: @test_no-implicit-float1(i32 %i) [[NOIMPLICITFLOAT]] {
246; CHECK-NEXT: ret i32
247}
248
249define i32 @test_no-implicit-float2(i32 %i) noimplicitfloat {
250  %1 = call i32 @no-implicit-float_callee0(i32 %i)
251  ret i32 %1
252; CHECK: @test_no-implicit-float2(i32 %i) [[NOIMPLICITFLOAT]] {
253; CHECK-NEXT: ret i32
254}
255
256define i32 @test_no-implicit-float3(i32 %i) noimplicitfloat {
257  %1 = call i32 @no-implicit-float_callee1(i32 %i)
258  ret i32 %1
259; CHECK: @test_no-implicit-float3(i32 %i) [[NOIMPLICITFLOAT]] {
260; CHECK-NEXT: ret i32
261}
262
263; Check that no-jump-tables flag propagates from inlined callee to caller
264
265define i32 @no-use-jump-tables_callee0(i32 %i) {
266  ret i32 %i
267; CHECK: @no-use-jump-tables_callee0(i32 %i) {
268; CHECK-NEXT: ret i32
269}
270
271define i32 @no-use-jump-tables_callee1(i32 %i) "no-jump-tables"="true" {
272  ret i32 %i
273; CHECK: @no-use-jump-tables_callee1(i32 %i) [[NOUSEJUMPTABLES:#[0-9]+]] {
274; CHECK-NEXT: ret i32
275}
276
277define i32 @test_no-use-jump-tables0(i32 %i) {
278  %1 = call i32 @no-use-jump-tables_callee0(i32 %i)
279  ret i32 %1
280; CHECK: @test_no-use-jump-tables0(i32 %i) {
281; CHECK-NEXT: ret i32
282}
283
284define i32 @test_no-use-jump-tables1(i32 %i) {
285  %1 = call i32 @no-use-jump-tables_callee1(i32 %i)
286  ret i32 %1
287; CHECK: @test_no-use-jump-tables1(i32 %i) [[NOUSEJUMPTABLES]] {
288; CHECK-NEXT: ret i32
289}
290
291define i32 @test_no-use-jump-tables2(i32 %i) "no-jump-tables"="true" {
292  %1 = call i32 @no-use-jump-tables_callee0(i32 %i)
293  ret i32 %1
294; CHECK: @test_no-use-jump-tables2(i32 %i) [[NOUSEJUMPTABLES]] {
295; CHECK-NEXT: ret i32
296}
297
298define i32 @test_no-use-jump-tables3(i32 %i) "no-jump-tables"="true" {
299  %1 = call i32 @no-use-jump-tables_callee1(i32 %i)
300  ret i32 %1
301; CHECK: @test_no-use-jump-tables3(i32 %i) [[NOUSEJUMPTABLES]] {
302; CHECK-NEXT: ret i32
303}
304
305; CHECK: attributes [[FPMAD_FALSE]] = { "less-precise-fpmad"="false" }
306; CHECK: attributes [[FPMAD_TRUE]] = { "less-precise-fpmad"="true" }
307; CHECK: attributes [[NOIMPLICITFLOAT]] = { noimplicitfloat }
308; CHECK: attributes [[NOUSEJUMPTABLES]] = { "no-jump-tables"="true" }