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 @alwaysinline_callee(i32 %i) alwaysinline {
21  ret i32 %i
22}
23
24define i32 @alwaysinline_sanitize_address_callee(i32 %i) alwaysinline sanitize_address {
25  ret i32 %i
26}
27
28define i32 @alwaysinline_sanitize_thread_callee(i32 %i) alwaysinline sanitize_thread {
29  ret i32 %i
30}
31
32define i32 @alwaysinline_sanitize_memory_callee(i32 %i) alwaysinline sanitize_memory {
33  ret i32 %i
34}
35
36
37; Check that:
38;  * noattr callee is inlined into noattr caller,
39;  * sanitize_(address|memory|thread) callee is not inlined into noattr caller,
40;  * alwaysinline callee is always inlined no matter what sanitize_* attributes are present.
41
42define i32 @test_no_sanitize_address(i32 %arg) {
43  %x1 = call i32 @noattr_callee(i32 %arg)
44  %x2 = call i32 @sanitize_address_callee(i32 %x1)
45  %x3 = call i32 @alwaysinline_callee(i32 %x2)
46  %x4 = call i32 @alwaysinline_sanitize_address_callee(i32 %x3)
47  ret i32 %x4
48; CHECK-LABEL: @test_no_sanitize_address(
49; CHECK-NEXT: @sanitize_address_callee
50; CHECK-NEXT: ret i32
51}
52
53define i32 @test_no_sanitize_memory(i32 %arg) {
54  %x1 = call i32 @noattr_callee(i32 %arg)
55  %x2 = call i32 @sanitize_memory_callee(i32 %x1)
56  %x3 = call i32 @alwaysinline_callee(i32 %x2)
57  %x4 = call i32 @alwaysinline_sanitize_memory_callee(i32 %x3)
58  ret i32 %x4
59; CHECK-LABEL: @test_no_sanitize_memory(
60; CHECK-NEXT: @sanitize_memory_callee
61; CHECK-NEXT: ret i32
62}
63
64define i32 @test_no_sanitize_thread(i32 %arg) {
65  %x1 = call i32 @noattr_callee(i32 %arg)
66  %x2 = call i32 @sanitize_thread_callee(i32 %x1)
67  %x3 = call i32 @alwaysinline_callee(i32 %x2)
68  %x4 = call i32 @alwaysinline_sanitize_thread_callee(i32 %x3)
69  ret i32 %x4
70; CHECK-LABEL: @test_no_sanitize_thread(
71; CHECK-NEXT: @sanitize_thread_callee
72; CHECK-NEXT: ret i32
73}
74
75
76; Check that:
77;  * noattr callee is not inlined into sanitize_(address|memory|thread) caller,
78;  * sanitize_(address|memory|thread) callee is inlined into the caller with the same attribute,
79;  * alwaysinline callee is always inlined no matter what sanitize_* attributes are present.
80
81define i32 @test_sanitize_address(i32 %arg) sanitize_address {
82  %x1 = call i32 @noattr_callee(i32 %arg)
83  %x2 = call i32 @sanitize_address_callee(i32 %x1)
84  %x3 = call i32 @alwaysinline_callee(i32 %x2)
85  %x4 = call i32 @alwaysinline_sanitize_address_callee(i32 %x3)
86  ret i32 %x4
87; CHECK-LABEL: @test_sanitize_address(
88; CHECK-NEXT: @noattr_callee
89; CHECK-NEXT: ret i32
90}
91
92define i32 @test_sanitize_memory(i32 %arg) sanitize_memory {
93  %x1 = call i32 @noattr_callee(i32 %arg)
94  %x2 = call i32 @sanitize_memory_callee(i32 %x1)
95  %x3 = call i32 @alwaysinline_callee(i32 %x2)
96  %x4 = call i32 @alwaysinline_sanitize_memory_callee(i32 %x3)
97  ret i32 %x4
98; CHECK-LABEL: @test_sanitize_memory(
99; CHECK-NEXT: @noattr_callee
100; CHECK-NEXT: ret i32
101}
102
103define i32 @test_sanitize_thread(i32 %arg) sanitize_thread {
104  %x1 = call i32 @noattr_callee(i32 %arg)
105  %x2 = call i32 @sanitize_thread_callee(i32 %x1)
106  %x3 = call i32 @alwaysinline_callee(i32 %x2)
107  %x4 = call i32 @alwaysinline_sanitize_thread_callee(i32 %x3)
108  ret i32 %x4
109; CHECK-LABEL: @test_sanitize_thread(
110; CHECK-NEXT: @noattr_callee
111; CHECK-NEXT: ret i32
112}
113
114; Check that a function doesn't get inlined if target-cpu strings don't match
115; exactly.
116define i32 @test_target_cpu_callee0(i32 %i) "target-cpu"="corei7" {
117  ret i32 %i
118}
119
120define i32 @test_target_cpu0(i32 %i) "target-cpu"="corei7" {
121  %1 = call i32 @test_target_cpu_callee0(i32 %i)
122  ret i32 %1
123; CHECK-LABEL: @test_target_cpu0(
124; CHECK-NOT: @test_target_cpu_callee0
125}
126
127define i32 @test_target_cpu_callee1(i32 %i) "target-cpu"="x86-64" {
128  ret i32 %i
129}
130
131define i32 @test_target_cpu1(i32 %i) "target-cpu"="corei7" {
132  %1 = call i32 @test_target_cpu_callee1(i32 %i)
133  ret i32 %1
134; CHECK-LABEL: @test_target_cpu1(
135; CHECK-NEXT: @test_target_cpu_callee1
136; CHECK-NEXT: ret i32
137}
138
139; Check that a function doesn't get inlined if target-features strings don't
140; match exactly.
141define i32 @test_target_features_callee0(i32 %i)  "target-features"="+sse4.2" {
142  ret i32 %i
143}
144
145define i32 @test_target_features0(i32 %i) "target-features"="+sse4.2" {
146  %1 = call i32 @test_target_features_callee0(i32 %i)
147  ret i32 %1
148; CHECK-LABEL: @test_target_features0(
149; CHECK-NOT: @test_target_features_callee0
150}
151
152define i32 @test_target_features_callee1(i32 %i) "target-features"="+avx2" {
153  ret i32 %i
154}
155
156define i32 @test_target_features1(i32 %i) "target-features"="+sse4.2" {
157  %1 = call i32 @test_target_features_callee1(i32 %i)
158  ret i32 %1
159; CHECK-LABEL: @test_target_features1(
160; CHECK-NEXT: @test_target_features_callee1
161; CHECK-NEXT: ret i32
162}
163