Skip to content

Commit 32cc8f7

Browse files
committed
[NFC][SCEV] Improve tests for ptrtoint modelling (D88806)
1 parent 701fbe8 commit 32cc8f7

File tree

2 files changed

+239
-115
lines changed

2 files changed

+239
-115
lines changed
Lines changed: 239 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,239 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py
2+
; RUN: opt < %s --data-layout="e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" -S -analyze -enable-new-pm=0 -scalar-evolution | FileCheck --check-prefixes=ALL,X64 %s
3+
; RUN: opt < %s--data-layout="e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" -S -disable-output "-passes=print<scalar-evolution>" 2>&1 | FileCheck --check-prefixes=ALL,X64 %s
4+
; RUN: opt < %s --data-layout="e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-f64:32:64-f80:32-n8:16:32-S128" -S -analyze -enable-new-pm=0 -scalar-evolution | FileCheck --check-prefixes=ALL,X32 %s
5+
; RUN: opt < %s--data-layout="e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-f64:32:64-f80:32-n8:16:32-S128" -S -disable-output "-passes=print<scalar-evolution>" 2>&1 | FileCheck --check-prefixes=ALL,X32 %s
6+
7+
; While we can't treat inttoptr/ptrtoint casts as fully transparent,
8+
; for ptrtoint cast, instead of modelling it as fully opaque (unknown),
9+
; we can at least model it as zext/trunc/self of an unknown,
10+
; iff it it's argument would be modelled as unknown anyways.
11+
12+
declare void @useptr(i8*)
13+
14+
; Simple ptrtoint of an argument, with casts to potentially different bit widths.
15+
define void @ptrtoint(i8* %in, i64* %out0, i32* %out1, i16* %out2, i128* %out3) {
16+
; X64-LABEL: 'ptrtoint'
17+
; X64-NEXT: Classifying expressions for: @ptrtoint
18+
; X64-NEXT: %p0 = ptrtoint i8* %in to i64
19+
; X64-NEXT: --> %p0 U: full-set S: full-set
20+
; X64-NEXT: %p1 = ptrtoint i8* %in to i32
21+
; X64-NEXT: --> %p1 U: full-set S: full-set
22+
; X64-NEXT: %p2 = ptrtoint i8* %in to i16
23+
; X64-NEXT: --> %p2 U: full-set S: full-set
24+
; X64-NEXT: %p3 = ptrtoint i8* %in to i128
25+
; X64-NEXT: --> %p3 U: [0,18446744073709551616) S: [-18446744073709551616,18446744073709551616)
26+
; X64-NEXT: Determining loop execution counts for: @ptrtoint
27+
;
28+
; X32-LABEL: 'ptrtoint'
29+
; X32-NEXT: Classifying expressions for: @ptrtoint
30+
; X32-NEXT: %p0 = ptrtoint i8* %in to i64
31+
; X32-NEXT: --> %p0 U: [0,4294967296) S: [-4294967296,4294967296)
32+
; X32-NEXT: %p1 = ptrtoint i8* %in to i32
33+
; X32-NEXT: --> %p1 U: full-set S: full-set
34+
; X32-NEXT: %p2 = ptrtoint i8* %in to i16
35+
; X32-NEXT: --> %p2 U: full-set S: full-set
36+
; X32-NEXT: %p3 = ptrtoint i8* %in to i128
37+
; X32-NEXT: --> %p3 U: [0,4294967296) S: [-4294967296,4294967296)
38+
; X32-NEXT: Determining loop execution counts for: @ptrtoint
39+
;
40+
%p0 = ptrtoint i8* %in to i64
41+
%p1 = ptrtoint i8* %in to i32
42+
%p2 = ptrtoint i8* %in to i16
43+
%p3 = ptrtoint i8* %in to i128
44+
store i64 %p0, i64* %out0
45+
store i32 %p1, i32* %out1
46+
store i16 %p2, i16* %out2
47+
store i128 %p3, i128* %out3
48+
ret void
49+
}
50+
51+
; Same, but from non-zero/non-default address space.
52+
define void @ptrtoint_as1(i8 addrspace(1)* %in, i64* %out0, i32* %out1, i16* %out2, i128* %out3) {
53+
; X64-LABEL: 'ptrtoint_as1'
54+
; X64-NEXT: Classifying expressions for: @ptrtoint_as1
55+
; X64-NEXT: %p0 = ptrtoint i8 addrspace(1)* %in to i64
56+
; X64-NEXT: --> %p0 U: full-set S: full-set
57+
; X64-NEXT: %p1 = ptrtoint i8 addrspace(1)* %in to i32
58+
; X64-NEXT: --> %p1 U: full-set S: full-set
59+
; X64-NEXT: %p2 = ptrtoint i8 addrspace(1)* %in to i16
60+
; X64-NEXT: --> %p2 U: full-set S: full-set
61+
; X64-NEXT: %p3 = ptrtoint i8 addrspace(1)* %in to i128
62+
; X64-NEXT: --> %p3 U: [0,18446744073709551616) S: [-18446744073709551616,18446744073709551616)
63+
; X64-NEXT: Determining loop execution counts for: @ptrtoint_as1
64+
;
65+
; X32-LABEL: 'ptrtoint_as1'
66+
; X32-NEXT: Classifying expressions for: @ptrtoint_as1
67+
; X32-NEXT: %p0 = ptrtoint i8 addrspace(1)* %in to i64
68+
; X32-NEXT: --> %p0 U: [0,4294967296) S: [-4294967296,4294967296)
69+
; X32-NEXT: %p1 = ptrtoint i8 addrspace(1)* %in to i32
70+
; X32-NEXT: --> %p1 U: full-set S: full-set
71+
; X32-NEXT: %p2 = ptrtoint i8 addrspace(1)* %in to i16
72+
; X32-NEXT: --> %p2 U: full-set S: full-set
73+
; X32-NEXT: %p3 = ptrtoint i8 addrspace(1)* %in to i128
74+
; X32-NEXT: --> %p3 U: [0,4294967296) S: [-4294967296,4294967296)
75+
; X32-NEXT: Determining loop execution counts for: @ptrtoint_as1
76+
;
77+
%p0 = ptrtoint i8 addrspace(1)* %in to i64
78+
%p1 = ptrtoint i8 addrspace(1)* %in to i32
79+
%p2 = ptrtoint i8 addrspace(1)* %in to i16
80+
%p3 = ptrtoint i8 addrspace(1)* %in to i128
81+
store i64 %p0, i64* %out0
82+
store i32 %p1, i32* %out1
83+
store i16 %p2, i16* %out2
84+
store i128 %p3, i128* %out3
85+
ret void
86+
}
87+
88+
; Likewise, ptrtoint of a bitcast is fine, we simply skip it.
89+
define void @ptrtoint_of_bitcast(i8* %in, i64* %out0) {
90+
; X64-LABEL: 'ptrtoint_of_bitcast'
91+
; X64-NEXT: Classifying expressions for: @ptrtoint_of_bitcast
92+
; X64-NEXT: %in_casted = bitcast i8* %in to float*
93+
; X64-NEXT: --> %in U: full-set S: full-set
94+
; X64-NEXT: %p0 = ptrtoint float* %in_casted to i64
95+
; X64-NEXT: --> %p0 U: full-set S: full-set
96+
; X64-NEXT: Determining loop execution counts for: @ptrtoint_of_bitcast
97+
;
98+
; X32-LABEL: 'ptrtoint_of_bitcast'
99+
; X32-NEXT: Classifying expressions for: @ptrtoint_of_bitcast
100+
; X32-NEXT: %in_casted = bitcast i8* %in to float*
101+
; X32-NEXT: --> %in U: full-set S: full-set
102+
; X32-NEXT: %p0 = ptrtoint float* %in_casted to i64
103+
; X32-NEXT: --> %p0 U: [0,4294967296) S: [-4294967296,4294967296)
104+
; X32-NEXT: Determining loop execution counts for: @ptrtoint_of_bitcast
105+
;
106+
%in_casted = bitcast i8* %in to float*
107+
%p0 = ptrtoint float* %in_casted to i64
108+
store i64 %p0, i64* %out0
109+
ret void
110+
}
111+
112+
; addrspacecast is fine too, but We don't model addrspacecast, so we stop there.
113+
define void @ptrtoint_of_addrspacecast(i8* %in, i64* %out0) {
114+
; X64-LABEL: 'ptrtoint_of_addrspacecast'
115+
; X64-NEXT: Classifying expressions for: @ptrtoint_of_addrspacecast
116+
; X64-NEXT: %in_casted = addrspacecast i8* %in to i8 addrspace(1)*
117+
; X64-NEXT: --> %in_casted U: full-set S: full-set
118+
; X64-NEXT: %p0 = ptrtoint i8 addrspace(1)* %in_casted to i64
119+
; X64-NEXT: --> %p0 U: full-set S: full-set
120+
; X64-NEXT: Determining loop execution counts for: @ptrtoint_of_addrspacecast
121+
;
122+
; X32-LABEL: 'ptrtoint_of_addrspacecast'
123+
; X32-NEXT: Classifying expressions for: @ptrtoint_of_addrspacecast
124+
; X32-NEXT: %in_casted = addrspacecast i8* %in to i8 addrspace(1)*
125+
; X32-NEXT: --> %in_casted U: full-set S: full-set
126+
; X32-NEXT: %p0 = ptrtoint i8 addrspace(1)* %in_casted to i64
127+
; X32-NEXT: --> %p0 U: [0,4294967296) S: [-4294967296,4294967296)
128+
; X32-NEXT: Determining loop execution counts for: @ptrtoint_of_addrspacecast
129+
;
130+
%in_casted = addrspacecast i8* %in to i8 addrspace(1)*
131+
%p0 = ptrtoint i8 addrspace(1)* %in_casted to i64
132+
store i64 %p0, i64* %out0
133+
ret void
134+
}
135+
136+
; inttoptr is fine too, but we don't (and can't) model inttoptr, so we stop there.
137+
define void @ptrtoint_of_inttoptr(i64 %in, i64* %out0) {
138+
; X64-LABEL: 'ptrtoint_of_inttoptr'
139+
; X64-NEXT: Classifying expressions for: @ptrtoint_of_inttoptr
140+
; X64-NEXT: %in_casted = inttoptr i64 %in to i8*
141+
; X64-NEXT: --> %in_casted U: full-set S: full-set
142+
; X64-NEXT: %p0 = ptrtoint i8* %in_casted to i64
143+
; X64-NEXT: --> %p0 U: full-set S: full-set
144+
; X64-NEXT: Determining loop execution counts for: @ptrtoint_of_inttoptr
145+
;
146+
; X32-LABEL: 'ptrtoint_of_inttoptr'
147+
; X32-NEXT: Classifying expressions for: @ptrtoint_of_inttoptr
148+
; X32-NEXT: %in_casted = inttoptr i64 %in to i8*
149+
; X32-NEXT: --> %in_casted U: full-set S: full-set
150+
; X32-NEXT: %p0 = ptrtoint i8* %in_casted to i64
151+
; X32-NEXT: --> %p0 U: [0,4294967296) S: [-4294967296,4294967296)
152+
; X32-NEXT: Determining loop execution counts for: @ptrtoint_of_inttoptr
153+
;
154+
%in_casted = inttoptr i64 %in to i8*
155+
%p0 = ptrtoint i8* %in_casted to i64
156+
store i64 %p0, i64* %out0
157+
ret void
158+
}
159+
160+
; However, GEP is something SCEV knows how to model, so in this case ptrtoint
161+
; can't be modelled as a cast, only as an unknown.
162+
define void @ptrtoint_of_gep(i8* %in, i64* %out0) {
163+
; X64-LABEL: 'ptrtoint_of_gep'
164+
; X64-NEXT: Classifying expressions for: @ptrtoint_of_gep
165+
; X64-NEXT: %in_adj = getelementptr inbounds i8, i8* %in, i64 42
166+
; X64-NEXT: --> (42 + %in)<nsw> U: [-9223372036854775766,-9223372036854775808) S: [-9223372036854775766,-9223372036854775808)
167+
; X64-NEXT: %p0 = ptrtoint i8* %in_adj to i64
168+
; X64-NEXT: --> %p0 U: full-set S: full-set
169+
; X64-NEXT: Determining loop execution counts for: @ptrtoint_of_gep
170+
;
171+
; X32-LABEL: 'ptrtoint_of_gep'
172+
; X32-NEXT: Classifying expressions for: @ptrtoint_of_gep
173+
; X32-NEXT: %in_adj = getelementptr inbounds i8, i8* %in, i64 42
174+
; X32-NEXT: --> (42 + %in)<nsw> U: [-2147483606,-2147483648) S: [-2147483606,-2147483648)
175+
; X32-NEXT: %p0 = ptrtoint i8* %in_adj to i64
176+
; X32-NEXT: --> %p0 U: [0,4294967296) S: [-4294967296,4294967296)
177+
; X32-NEXT: Determining loop execution counts for: @ptrtoint_of_gep
178+
;
179+
%in_adj = getelementptr inbounds i8, i8* %in, i64 42
180+
%p0 = ptrtoint i8* %in_adj to i64
181+
store i64 %p0, i64* %out0
182+
ret void
183+
}
184+
185+
; A constant pointer is fine
186+
define void @ptrtoint_of_nullptr(i64* %out0) {
187+
; ALL-LABEL: 'ptrtoint_of_nullptr'
188+
; ALL-NEXT: Classifying expressions for: @ptrtoint_of_nullptr
189+
; ALL-NEXT: %p0 = ptrtoint i8* null to i64
190+
; ALL-NEXT: --> %p0 U: [0,1) S: [-1,1)
191+
; ALL-NEXT: Determining loop execution counts for: @ptrtoint_of_nullptr
192+
;
193+
%p0 = ptrtoint i8* null to i64
194+
store i64 %p0, i64* %out0
195+
ret void
196+
}
197+
198+
; A constant inttoptr argument of an ptrtoint is still bad.
199+
define void @ptrtoint_of_constantexpr_inttoptr(i64* %out0) {
200+
; ALL-LABEL: 'ptrtoint_of_constantexpr_inttoptr'
201+
; ALL-NEXT: Classifying expressions for: @ptrtoint_of_constantexpr_inttoptr
202+
; ALL-NEXT: %p0 = ptrtoint i8* inttoptr (i64 42 to i8*) to i64
203+
; ALL-NEXT: --> %p0 U: [42,43) S: [-64,64)
204+
; ALL-NEXT: Determining loop execution counts for: @ptrtoint_of_constantexpr_inttoptr
205+
;
206+
%p0 = ptrtoint i8* inttoptr (i64 42 to i8*) to i64
207+
store i64 %p0, i64* %out0
208+
ret void
209+
}
210+
211+
; However, while bitcast would be fine, GEP we can model, so we are back
212+
; to modelling the whole cast as unknown..
213+
define void @ptrtoint_of_bitcast_of_gep(i8* %in, i64* %out0) {
214+
; X64-LABEL: 'ptrtoint_of_bitcast_of_gep'
215+
; X64-NEXT: Classifying expressions for: @ptrtoint_of_bitcast_of_gep
216+
; X64-NEXT: %in_adj = getelementptr inbounds i8, i8* %in, i64 42
217+
; X64-NEXT: --> (42 + %in)<nsw> U: [-9223372036854775766,-9223372036854775808) S: [-9223372036854775766,-9223372036854775808)
218+
; X64-NEXT: %in_adj_casted = bitcast i8* %in_adj to float*
219+
; X64-NEXT: --> (42 + %in)<nsw> U: [-9223372036854775766,-9223372036854775808) S: [-9223372036854775766,-9223372036854775808)
220+
; X64-NEXT: %p0 = ptrtoint float* %in_adj_casted to i64
221+
; X64-NEXT: --> %p0 U: full-set S: full-set
222+
; X64-NEXT: Determining loop execution counts for: @ptrtoint_of_bitcast_of_gep
223+
;
224+
; X32-LABEL: 'ptrtoint_of_bitcast_of_gep'
225+
; X32-NEXT: Classifying expressions for: @ptrtoint_of_bitcast_of_gep
226+
; X32-NEXT: %in_adj = getelementptr inbounds i8, i8* %in, i64 42
227+
; X32-NEXT: --> (42 + %in)<nsw> U: [-2147483606,-2147483648) S: [-2147483606,-2147483648)
228+
; X32-NEXT: %in_adj_casted = bitcast i8* %in_adj to float*
229+
; X32-NEXT: --> (42 + %in)<nsw> U: [-2147483606,-2147483648) S: [-2147483606,-2147483648)
230+
; X32-NEXT: %p0 = ptrtoint float* %in_adj_casted to i64
231+
; X32-NEXT: --> %p0 U: [0,4294967296) S: [-4294967296,4294967296)
232+
; X32-NEXT: Determining loop execution counts for: @ptrtoint_of_bitcast_of_gep
233+
;
234+
%in_adj = getelementptr inbounds i8, i8* %in, i64 42
235+
%in_adj_casted = bitcast i8* %in_adj to float*
236+
%p0 = ptrtoint float* %in_adj_casted to i64
237+
store i64 %p0, i64* %out0
238+
ret void
239+
}

llvm/test/Analysis/ScalarEvolution/semi-transparent-inttoptr-ptrtoint-casts.ll

Lines changed: 0 additions & 115 deletions
This file was deleted.

0 commit comments

Comments
 (0)