[ARM] Adjust how NEON shifts are lowered
[llvm-core.git] / test / Transforms / Inline / attributes.ll
blob028f3b0f1978368c8b2c3e239b485f38ce665ea7
1 ; RUN: opt < %s -inline -S | FileCheck %s
2 ; RUN: opt < %s -passes='cgscc(inline)' -S | FileCheck %s
3 target 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"
5 define i32 @noattr_callee(i32 %i) {
6   ret i32 %i
9 define i32 @sanitize_address_callee(i32 %i) sanitize_address {
10   ret i32 %i
13 define i32 @sanitize_hwaddress_callee(i32 %i) sanitize_hwaddress {
14   ret i32 %i
17 define i32 @sanitize_thread_callee(i32 %i) sanitize_thread {
18   ret i32 %i
21 define i32 @sanitize_memory_callee(i32 %i) sanitize_memory {
22   ret i32 %i
25 define i32 @safestack_callee(i32 %i) safestack {
26   ret i32 %i
29 define i32 @slh_callee(i32 %i) speculative_load_hardening {
30   ret i32 %i
33 define i32 @alwaysinline_callee(i32 %i) alwaysinline {
34   ret i32 %i
37 define i32 @alwaysinline_sanitize_address_callee(i32 %i) alwaysinline sanitize_address {
38   ret i32 %i
41 define i32 @alwaysinline_sanitize_hwaddress_callee(i32 %i) alwaysinline sanitize_hwaddress {
42   ret i32 %i
45 define i32 @alwaysinline_sanitize_thread_callee(i32 %i) alwaysinline sanitize_thread {
46   ret i32 %i
49 define i32 @alwaysinline_sanitize_memory_callee(i32 %i) alwaysinline sanitize_memory {
50   ret i32 %i
53 define i32 @alwaysinline_safestack_callee(i32 %i) alwaysinline safestack {
54   ret i32 %i
58 ; Check that:
59 ;  * noattr callee is inlined into noattr caller,
60 ;  * sanitize_(address|memory|thread) callee is not inlined into noattr caller,
61 ;  * alwaysinline callee is always inlined no matter what sanitize_* attributes are present.
63 define i32 @test_no_sanitize_address(i32 %arg) {
64   %x1 = call i32 @noattr_callee(i32 %arg)
65   %x2 = call i32 @sanitize_address_callee(i32 %x1)
66   %x3 = call i32 @alwaysinline_callee(i32 %x2)
67   %x4 = call i32 @alwaysinline_sanitize_address_callee(i32 %x3)
68   ret i32 %x4
69 ; CHECK-LABEL: @test_no_sanitize_address(
70 ; CHECK-NEXT: @sanitize_address_callee
71 ; CHECK-NEXT: ret i32
74 define i32 @test_no_sanitize_hwaddress(i32 %arg) {
75   %x1 = call i32 @noattr_callee(i32 %arg)
76   %x2 = call i32 @sanitize_hwaddress_callee(i32 %x1)
77   %x3 = call i32 @alwaysinline_callee(i32 %x2)
78   %x4 = call i32 @alwaysinline_sanitize_hwaddress_callee(i32 %x3)
79   ret i32 %x4
80 ; CHECK-LABEL: @test_no_sanitize_hwaddress(
81 ; CHECK-NEXT: @sanitize_hwaddress_callee
82 ; CHECK-NEXT: ret i32
85 define i32 @test_no_sanitize_memory(i32 %arg) {
86   %x1 = call i32 @noattr_callee(i32 %arg)
87   %x2 = call i32 @sanitize_memory_callee(i32 %x1)
88   %x3 = call i32 @alwaysinline_callee(i32 %x2)
89   %x4 = call i32 @alwaysinline_sanitize_memory_callee(i32 %x3)
90   ret i32 %x4
91 ; CHECK-LABEL: @test_no_sanitize_memory(
92 ; CHECK-NEXT: @sanitize_memory_callee
93 ; CHECK-NEXT: ret i32
96 define i32 @test_no_sanitize_thread(i32 %arg) {
97   %x1 = call i32 @noattr_callee(i32 %arg)
98   %x2 = call i32 @sanitize_thread_callee(i32 %x1)
99   %x3 = call i32 @alwaysinline_callee(i32 %x2)
100   %x4 = call i32 @alwaysinline_sanitize_thread_callee(i32 %x3)
101   ret i32 %x4
102 ; CHECK-LABEL: @test_no_sanitize_thread(
103 ; CHECK-NEXT: @sanitize_thread_callee
104 ; CHECK-NEXT: ret i32
108 ; Check that:
109 ;  * noattr callee is not inlined into sanitize_(address|memory|thread) caller,
110 ;  * sanitize_(address|memory|thread) callee is inlined into the caller with the same attribute,
111 ;  * alwaysinline callee is always inlined no matter what sanitize_* attributes are present.
113 define i32 @test_sanitize_address(i32 %arg) sanitize_address {
114   %x1 = call i32 @noattr_callee(i32 %arg)
115   %x2 = call i32 @sanitize_address_callee(i32 %x1)
116   %x3 = call i32 @alwaysinline_callee(i32 %x2)
117   %x4 = call i32 @alwaysinline_sanitize_address_callee(i32 %x3)
118   ret i32 %x4
119 ; CHECK-LABEL: @test_sanitize_address(
120 ; CHECK-NEXT: @noattr_callee
121 ; CHECK-NEXT: ret i32
124 define i32 @test_sanitize_hwaddress(i32 %arg) sanitize_hwaddress {
125   %x1 = call i32 @noattr_callee(i32 %arg)
126   %x2 = call i32 @sanitize_hwaddress_callee(i32 %x1)
127   %x3 = call i32 @alwaysinline_callee(i32 %x2)
128   %x4 = call i32 @alwaysinline_sanitize_hwaddress_callee(i32 %x3)
129   ret i32 %x4
130 ; CHECK-LABEL: @test_sanitize_hwaddress(
131 ; CHECK-NEXT: @noattr_callee
132 ; CHECK-NEXT: ret i32
135 define i32 @test_sanitize_memory(i32 %arg) sanitize_memory {
136   %x1 = call i32 @noattr_callee(i32 %arg)
137   %x2 = call i32 @sanitize_memory_callee(i32 %x1)
138   %x3 = call i32 @alwaysinline_callee(i32 %x2)
139   %x4 = call i32 @alwaysinline_sanitize_memory_callee(i32 %x3)
140   ret i32 %x4
141 ; CHECK-LABEL: @test_sanitize_memory(
142 ; CHECK-NEXT: @noattr_callee
143 ; CHECK-NEXT: ret i32
146 define i32 @test_sanitize_thread(i32 %arg) sanitize_thread {
147   %x1 = call i32 @noattr_callee(i32 %arg)
148   %x2 = call i32 @sanitize_thread_callee(i32 %x1)
149   %x3 = call i32 @alwaysinline_callee(i32 %x2)
150   %x4 = call i32 @alwaysinline_sanitize_thread_callee(i32 %x3)
151   ret i32 %x4
152 ; CHECK-LABEL: @test_sanitize_thread(
153 ; CHECK-NEXT: @noattr_callee
154 ; CHECK-NEXT: ret i32
157 define i32 @test_safestack(i32 %arg) safestack {
158   %x1 = call i32 @noattr_callee(i32 %arg)
159   %x2 = call i32 @safestack_callee(i32 %x1)
160   %x3 = call i32 @alwaysinline_callee(i32 %x2)
161   %x4 = call i32 @alwaysinline_safestack_callee(i32 %x3)
162   ret i32 %x4
163 ; CHECK-LABEL: @test_safestack(
164 ; CHECK-NEXT: @noattr_callee
165 ; CHECK-NEXT: ret i32
168 ; Can inline a normal function into an SLH'ed function.
169 define i32 @test_caller_slh(i32 %i) speculative_load_hardening {
170 ; CHECK-LABEL: @test_caller_slh(
171 ; CHECK-SAME: ) [[SLH:.*]] {
172 ; CHECK-NOT: call
173 ; CHECK: ret i32
174 entry:
175   %callee = call i32 @noattr_callee(i32 %i)
176   ret i32 %callee
179 ; Can inline a SLH'ed function into a normal one, propagating SLH.
180 define i32 @test_callee_slh(i32 %i) {
181 ; CHECK-LABEL: @test_callee_slh(
182 ; CHECK-SAME: ) [[SLH:.*]] {
183 ; CHECK-NOT: call
184 ; CHECK: ret i32
185 entry:
186   %callee = call i32 @slh_callee(i32 %i)
187   ret i32 %callee
190 ; Check that a function doesn't get inlined if target-cpu strings don't match
191 ; exactly.
192 define i32 @test_target_cpu_callee0(i32 %i) "target-cpu"="corei7" {
193   ret i32 %i
196 define i32 @test_target_cpu0(i32 %i) "target-cpu"="corei7" {
197   %1 = call i32 @test_target_cpu_callee0(i32 %i)
198   ret i32 %1
199 ; CHECK-LABEL: @test_target_cpu0(
200 ; CHECK-NOT: @test_target_cpu_callee0
203 define i32 @test_target_cpu_callee1(i32 %i) "target-cpu"="x86-64" {
204   ret i32 %i
207 define i32 @test_target_cpu1(i32 %i) "target-cpu"="corei7" {
208   %1 = call i32 @test_target_cpu_callee1(i32 %i)
209   ret i32 %1
210 ; CHECK-LABEL: @test_target_cpu1(
211 ; CHECK-NEXT: @test_target_cpu_callee1
212 ; CHECK-NEXT: ret i32
215 ; Check that a function doesn't get inlined if target-features strings don't
216 ; match exactly.
217 define i32 @test_target_features_callee0(i32 %i)  "target-features"="+sse4.2" {
218   ret i32 %i
221 define i32 @test_target_features0(i32 %i) "target-features"="+sse4.2" {
222   %1 = call i32 @test_target_features_callee0(i32 %i)
223   ret i32 %1
224 ; CHECK-LABEL: @test_target_features0(
225 ; CHECK-NOT: @test_target_features_callee0
228 define i32 @test_target_features_callee1(i32 %i) "target-features"="+avx2" {
229   ret i32 %i
232 define i32 @test_target_features1(i32 %i) "target-features"="+sse4.2" {
233   %1 = call i32 @test_target_features_callee1(i32 %i)
234   ret i32 %1
235 ; CHECK-LABEL: @test_target_features1(
236 ; CHECK-NEXT: @test_target_features_callee1
237 ; CHECK-NEXT: ret i32
240 define i32 @less-precise-fpmad_callee0(i32 %i) "less-precise-fpmad"="false" {
241   ret i32 %i
242 ; CHECK: @less-precise-fpmad_callee0(i32 %i) [[FPMAD_FALSE:#[0-9]+]] {
243 ; CHECK-NEXT: ret i32
246 define i32 @less-precise-fpmad_callee1(i32 %i) "less-precise-fpmad"="true" {
247   ret i32 %i
248 ; CHECK: @less-precise-fpmad_callee1(i32 %i) [[FPMAD_TRUE:#[0-9]+]] {
249 ; CHECK-NEXT: ret i32
252 define i32 @test_less-precise-fpmad0(i32 %i) "less-precise-fpmad"="false" {
253   %1 = call i32 @less-precise-fpmad_callee0(i32 %i)
254   ret i32 %1
255 ; CHECK: @test_less-precise-fpmad0(i32 %i) [[FPMAD_FALSE]] {
256 ; CHECK-NEXT: ret i32
259 define i32 @test_less-precise-fpmad1(i32 %i) "less-precise-fpmad"="false" {
260   %1 = call i32 @less-precise-fpmad_callee1(i32 %i)
261   ret i32 %1
262 ; CHECK: @test_less-precise-fpmad1(i32 %i) [[FPMAD_FALSE]] {
263 ; CHECK-NEXT: ret i32
266 define i32 @test_less-precise-fpmad2(i32 %i) "less-precise-fpmad"="true" {
267   %1 = call i32 @less-precise-fpmad_callee0(i32 %i)
268   ret i32 %1
269 ; CHECK: @test_less-precise-fpmad2(i32 %i) [[FPMAD_FALSE]] {
270 ; CHECK-NEXT: ret i32
273 define i32 @test_less-precise-fpmad3(i32 %i) "less-precise-fpmad"="true" {
274   %1 = call i32 @less-precise-fpmad_callee1(i32 %i)
275   ret i32 %1
276 ; CHECK: @test_less-precise-fpmad3(i32 %i) [[FPMAD_TRUE]] {
277 ; CHECK-NEXT: ret i32
280 define i32 @no-implicit-float_callee0(i32 %i) {
281   ret i32 %i
282 ; CHECK: @no-implicit-float_callee0(i32 %i) {
283 ; CHECK-NEXT: ret i32
286 define i32 @no-implicit-float_callee1(i32 %i) noimplicitfloat {
287   ret i32 %i
288 ; CHECK: @no-implicit-float_callee1(i32 %i) [[NOIMPLICITFLOAT:#[0-9]+]] {
289 ; CHECK-NEXT: ret i32
292 define i32 @test_no-implicit-float0(i32 %i) {
293   %1 = call i32 @no-implicit-float_callee0(i32 %i)
294   ret i32 %1
295 ; CHECK: @test_no-implicit-float0(i32 %i) {
296 ; CHECK-NEXT: ret i32
299 define i32 @test_no-implicit-float1(i32 %i) {
300   %1 = call i32 @no-implicit-float_callee1(i32 %i)
301   ret i32 %1
302 ; CHECK: @test_no-implicit-float1(i32 %i) [[NOIMPLICITFLOAT]] {
303 ; CHECK-NEXT: ret i32
306 define i32 @test_no-implicit-float2(i32 %i) noimplicitfloat {
307   %1 = call i32 @no-implicit-float_callee0(i32 %i)
308   ret i32 %1
309 ; CHECK: @test_no-implicit-float2(i32 %i) [[NOIMPLICITFLOAT]] {
310 ; CHECK-NEXT: ret i32
313 define i32 @test_no-implicit-float3(i32 %i) noimplicitfloat {
314   %1 = call i32 @no-implicit-float_callee1(i32 %i)
315   ret i32 %1
316 ; CHECK: @test_no-implicit-float3(i32 %i) [[NOIMPLICITFLOAT]] {
317 ; CHECK-NEXT: ret i32
320 ; Check that no-jump-tables flag propagates from inlined callee to caller 
322 define i32 @no-use-jump-tables_callee0(i32 %i) {
323   ret i32 %i
324 ; CHECK: @no-use-jump-tables_callee0(i32 %i) {
325 ; CHECK-NEXT: ret i32
328 define i32 @no-use-jump-tables_callee1(i32 %i) "no-jump-tables"="true" {
329   ret i32 %i
330 ; CHECK: @no-use-jump-tables_callee1(i32 %i) [[NOUSEJUMPTABLES:#[0-9]+]] {
331 ; CHECK-NEXT: ret i32
334 define i32 @test_no-use-jump-tables0(i32 %i) {
335   %1 = call i32 @no-use-jump-tables_callee0(i32 %i)
336   ret i32 %1
337 ; CHECK: @test_no-use-jump-tables0(i32 %i) {
338 ; CHECK-NEXT: ret i32
341 define i32 @test_no-use-jump-tables1(i32 %i) {
342   %1 = call i32 @no-use-jump-tables_callee1(i32 %i)
343   ret i32 %1
344 ; CHECK: @test_no-use-jump-tables1(i32 %i) [[NOUSEJUMPTABLES]] {
345 ; CHECK-NEXT: ret i32
348 define i32 @test_no-use-jump-tables2(i32 %i) "no-jump-tables"="true" {
349   %1 = call i32 @no-use-jump-tables_callee0(i32 %i)
350   ret i32 %1
351 ; CHECK: @test_no-use-jump-tables2(i32 %i) [[NOUSEJUMPTABLES]] {
352 ; CHECK-NEXT: ret i32
355 define i32 @test_no-use-jump-tables3(i32 %i) "no-jump-tables"="true" {
356   %1 = call i32 @no-use-jump-tables_callee1(i32 %i)
357   ret i32 %1
358 ; CHECK: @test_no-use-jump-tables3(i32 %i) [[NOUSEJUMPTABLES]] {
359 ; CHECK-NEXT: ret i32
362 ; Callee with "null-pointer-is-valid"="true" attribute should not be inlined
363 ; into a caller without this attribute.
364 ; Exception: alwaysinline callee can still be inlined but
365 ; "null-pointer-is-valid"="true" should get copied to caller.
367 define i32 @null-pointer-is-valid_callee0(i32 %i) "null-pointer-is-valid"="true" {
368   ret i32 %i
369 ; CHECK: @null-pointer-is-valid_callee0(i32 %i)
370 ; CHECK-NEXT: ret i32
373 define i32 @null-pointer-is-valid_callee1(i32 %i) alwaysinline "null-pointer-is-valid"="true" {
374   ret i32 %i
375 ; CHECK: @null-pointer-is-valid_callee1(i32 %i)
376 ; CHECK-NEXT: ret i32
379 define i32 @null-pointer-is-valid_callee2(i32 %i)  {
380   ret i32 %i
381 ; CHECK: @null-pointer-is-valid_callee2(i32 %i)
382 ; CHECK-NEXT: ret i32
385 ; No inlining since caller does not have "null-pointer-is-valid"="true" attribute.
386 define i32 @test_null-pointer-is-valid0(i32 %i) {
387   %1 = call i32 @null-pointer-is-valid_callee0(i32 %i)
388   ret i32 %1
389 ; CHECK: @test_null-pointer-is-valid0(
390 ; CHECK: call i32 @null-pointer-is-valid_callee0
391 ; CHECK-NEXT: ret i32
394 ; alwaysinline should force inlining even when caller does not have
395 ; "null-pointer-is-valid"="true" attribute. However, the attribute should be
396 ; copied to caller.
397 define i32 @test_null-pointer-is-valid1(i32 %i) "null-pointer-is-valid"="false" {
398   %1 = call i32 @null-pointer-is-valid_callee1(i32 %i)
399   ret i32 %1
400 ; CHECK: @test_null-pointer-is-valid1(i32 %i) [[NULLPOINTERISVALID:#[0-9]+]] {
401 ; CHECK-NEXT: ret i32
404 ; Can inline since both caller and callee have "null-pointer-is-valid"="true"
405 ; attribute.
406 define i32 @test_null-pointer-is-valid2(i32 %i) "null-pointer-is-valid"="true" {
407   %1 = call i32 @null-pointer-is-valid_callee2(i32 %i)
408   ret i32 %1
409 ; CHECK: @test_null-pointer-is-valid2(i32 %i) [[NULLPOINTERISVALID]] {
410 ; CHECK-NEXT: ret i32
413 ; CHECK: attributes [[SLH]] = { speculative_load_hardening }
414 ; CHECK: attributes [[FPMAD_FALSE]] = { "less-precise-fpmad"="false" }
415 ; CHECK: attributes [[FPMAD_TRUE]] = { "less-precise-fpmad"="true" }
416 ; CHECK: attributes [[NOIMPLICITFLOAT]] = { noimplicitfloat }
417 ; CHECK: attributes [[NOUSEJUMPTABLES]] = { "no-jump-tables"="true" }
418 ; CHECK: attributes [[NULLPOINTERISVALID]] = { "null-pointer-is-valid"="true" }