xref: /llvm-project/llvm/test/Transforms/Inline/ptr-diff.ll (revision 151602c7a9935558ca671b35359989b261045db0)
1; RUN: opt -passes=inline < %s -S -o - -inline-threshold=10 | FileCheck %s
2
3target datalayout = "p:32:32-p1:64:64-p2:16:16-n16:32:64"
4
5define i32 @outer1() {
6; CHECK-LABEL: @outer1(
7; CHECK-NOT: call i32
8; CHECK: ret i32
9
10  %ptr = alloca i32
11  %ptr2 = getelementptr inbounds i32, ptr %ptr, i32 42
12  %result = call i32 @inner1(ptr %ptr, ptr %ptr2)
13  ret i32 %result
14}
15
16define i32 @inner1(ptr %begin, ptr %end) {
17  call void @extern()
18  %begin.i = ptrtoint ptr %begin to i32
19  %end.i = ptrtoint ptr %end to i32
20  %distance = sub i32 %end.i, %begin.i
21  %icmp = icmp sle i32 %distance, 42
22  br i1 %icmp, label %then, label %else
23
24then:
25  ret i32 3
26
27else:
28  %t = load i32, ptr %begin
29  ret i32 %t
30}
31
32define i32 @outer1_as1(ptr addrspace(1) %ptr) {
33; CHECK-LABEL: @outer1_as1(
34; CHECK-NOT: call
35; CHECK: ret i32
36  %ptr2 = getelementptr inbounds i32, ptr addrspace(1) %ptr, i32 42
37  %result = call i32 @inner1_as1(ptr addrspace(1) %ptr, ptr addrspace(1) %ptr2)
38  ret i32 %result
39}
40
41; Make sure that the address space's larger size makes the ptrtoints
42; not no-ops preventing inlining
43define i32 @inner1_as1(ptr addrspace(1) %begin, ptr addrspace(1) %end) {
44  %begin.i = ptrtoint ptr addrspace(1) %begin to i32
45  %end.i = ptrtoint ptr addrspace(1) %end to i32
46  %distance = sub i32 %end.i, %begin.i
47  %icmp = icmp sle i32 %distance, 42
48  br i1 %icmp, label %then, label %else
49
50then:
51  ret i32 3
52
53else:
54  %t = load i32, ptr addrspace(1) %begin
55  ret i32 %t
56}
57
58define i32 @outer2(ptr %ptr) {
59; Test that an inbounds GEP disables this -- it isn't safe in general as
60; wrapping changes the behavior of lessthan and greaterthan comparisons.
61; CHECK-LABEL: @outer2(
62; CHECK: call i32 @inner2
63; CHECK: ret i32
64
65  %ptr2 = getelementptr i32, ptr %ptr, i32 42
66  %result = call i32 @inner2(ptr %ptr, ptr %ptr2)
67  ret i32 %result
68}
69
70define i32 @inner2(ptr %begin, ptr %end) {
71  call void @extern()
72  %begin.i = ptrtoint ptr %begin to i32
73  %end.i = ptrtoint ptr %end to i32
74  %distance = sub i32 %end.i, %begin.i
75  %icmp = icmp sle i32 %distance, 42
76  br i1 %icmp, label %then, label %else
77
78then:
79  ret i32 3
80
81else:
82  %t = load i32, ptr %begin
83  ret i32 %t
84}
85
86define i32 @outer3(ptr addrspace(1) %ptr) {
87; CHECK-LABEL: @outer3(
88; CHECK-NOT: call i32
89; CHECK: ret i32 3
90; CHECK-LABEL: @inner3(
91  %result = call i32 @inner3(ptr addrspace(1) %ptr)
92  ret i32 %result
93}
94
95define i32 @inner3(ptr addrspace(1) %ptr) {
96  call void @extern()
97  %ptr.i = ptrtoint ptr addrspace(1) %ptr to i64
98  %distance = sub i64 %ptr.i, %ptr.i
99  %icmp = icmp eq i64 %distance, 0
100  br i1 %icmp, label %then, label %else
101
102then:
103  ret i32 3
104
105else:
106  ret i32 5
107}
108
109
110; The inttoptrs are free since it is a smaller integer to a larger
111; pointer size
112define i32 @inttoptr_free_cost(i32 %a, i32 %b, i32 %c) {
113  call void @extern()
114  %p1 = inttoptr i32 %a to ptr addrspace(1)
115  %p2 = inttoptr i32 %b to ptr addrspace(1)
116  %p3 = inttoptr i32 %c to ptr addrspace(1)
117  %t1 = load i32, ptr addrspace(1) %p1
118  %t2 = load i32, ptr addrspace(1) %p2
119  %t3 = load i32, ptr addrspace(1) %p3
120  %s = add i32 %t1, %t2
121  %s1 = add i32 %s, %t3
122  ret i32 %s1
123}
124
125define i32 @inttoptr_free_cost_user(i32 %begin, i32 %end) {
126; CHECK-LABEL: @inttoptr_free_cost_user(
127; CHECK-NOT: call i32
128  %x = call i32 @inttoptr_free_cost(i32 %begin, i32 %end, i32 9)
129  ret i32 %x
130}
131
132; The inttoptrs have a cost since it is a larger integer to a smaller
133; pointer size
134define i32 @inttoptr_cost_smaller_ptr(i32 %a, i32 %b, i32 %c) {
135  call void @extern()
136  %p1 = inttoptr i32 %a to ptr addrspace(2)
137  %p2 = inttoptr i32 %b to ptr addrspace(2)
138  %p3 = inttoptr i32 %c to ptr addrspace(2)
139  %t1 = load i32, ptr addrspace(2) %p1
140  %t2 = load i32, ptr addrspace(2) %p2
141  %t3 = load i32, ptr addrspace(2) %p3
142  %s = add i32 %t1, %t2
143  %s1 = add i32 %s, %t3
144  ret i32 %s1
145}
146
147define i32 @inttoptr_cost_smaller_ptr_user(i32 %begin, i32 %end) {
148; CHECK-LABEL: @inttoptr_cost_smaller_ptr_user(
149; CHECK: call i32
150  %x = call i32 @inttoptr_cost_smaller_ptr(i32 %begin, i32 %end, i32 9)
151  ret i32 %x
152}
153
154declare void @extern()
155