1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -instsimplify -S -verify | FileCheck %s
3
4define i1 @ule_null_constexpr(ptr %x) {
5; CHECK-LABEL: @ule_null_constexpr(
6; CHECK-NEXT:    ret i1 true
7;
8  %cmp = icmp ule ptr null, @ule_null_constexpr
9  ret i1 %cmp
10}
11
12define i1 @ugt_null_constexpr(ptr %x) {
13; CHECK-LABEL: @ugt_null_constexpr(
14; CHECK-NEXT:    ret i1 false
15;
16  %cmp = icmp ugt ptr null, @ugt_null_constexpr
17  ret i1 %cmp
18}
19
20define i1 @uge_constexpr_null(ptr %x) {
21; CHECK-LABEL: @uge_constexpr_null(
22; CHECK-NEXT:    ret i1 true
23;
24  %cmp = icmp uge ptr @ugt_null_constexpr, null
25  ret i1 %cmp
26}
27
28define i1 @ult_constexpr_null(ptr %x) {
29; CHECK-LABEL: @ult_constexpr_null(
30; CHECK-NEXT:    ret i1 false
31;
32  %cmp = icmp ult ptr @ugt_null_constexpr, null
33  ret i1 %cmp
34}
35
36; Negative test - we don't know if the constexpr is null.
37
38define i1 @ule_constexpr_null(ptr %x) {
39; CHECK-LABEL: @ule_constexpr_null(
40; CHECK-NEXT:    ret i1 false
41;
42  %cmp = icmp ule ptr @ugt_null_constexpr, null
43  ret i1 %cmp
44}
45
46; Negative test - we don't know if the constexpr is *signed* less-than null.
47
48define i1 @slt_constexpr_null(ptr %x) {
49; CHECK-LABEL: @slt_constexpr_null(
50; CHECK-NEXT:    ret i1 icmp slt (ptr @ugt_null_constexpr, ptr null)
51;
52  %cmp = icmp slt ptr @ugt_null_constexpr, null
53  ret i1 %cmp
54}
55
56; Negative test - we don't try to evaluate this comparison of constant expressions.
57
58define i1 @ult_constexpr_constexpr_one(ptr %x) {
59; CHECK-LABEL: @ult_constexpr_constexpr_one(
60; CHECK-NEXT:    ret i1 icmp ugt (ptr inttoptr (i32 1 to ptr), ptr @ugt_null_constexpr)
61;
62  %cmp = icmp ult ptr @ugt_null_constexpr, inttoptr (i32 1 to ptr)
63  ret i1 %cmp
64}
65
66@g = global [2 x i32] [i32 1, i32 2]
67@g2 = global i32 0
68@g2_weak = extern_weak global i32
69@g3 = global i8 0
70
71define i1 @global_ne_null() {
72; CHECK-LABEL: @global_ne_null(
73; CHECK-NEXT:    ret i1 true
74;
75  %cmp = icmp ne ptr @g, null
76  ret i1 %cmp
77}
78
79define i1 @global_ugt_null() {
80; CHECK-LABEL: @global_ugt_null(
81; CHECK-NEXT:    ret i1 true
82;
83  %cmp = icmp ugt ptr @g, null
84  ret i1 %cmp
85}
86
87define i1 @global_sgt_null() {
88; CHECK-LABEL: @global_sgt_null(
89; CHECK-NEXT:    ret i1 icmp sgt (ptr @g, ptr null)
90;
91  %cmp = icmp sgt ptr @g, null
92  ret i1 %cmp
93}
94
95; Should not fold to true, as the gep computes a null value.
96define i1 @global_out_of_bounds_gep_ne_null() {
97; CHECK-LABEL: @global_out_of_bounds_gep_ne_null(
98; CHECK-NEXT:    ret i1 icmp ne (ptr getelementptr (i8, ptr @g3, i64 sub (i64 0, i64 ptrtoint (ptr @g3 to i64))), ptr null)
99;
100  %cmp = icmp ne ptr getelementptr (i8, ptr @g3, i64 sub (i64 0, i64 ptrtoint (ptr @g3 to i64))), null
101  ret i1 %cmp
102}
103
104define i1 @global_inbounds_gep_ne_null() {
105; CHECK-LABEL: @global_inbounds_gep_ne_null(
106; CHECK-NEXT:    ret i1 true
107;
108  %gep = getelementptr inbounds [2 x i32], ptr @g, i64 1
109  %cmp = icmp ne ptr %gep, null
110  ret i1 %cmp
111}
112
113define i1 @global_gep_ugt_null() {
114; CHECK-LABEL: @global_gep_ugt_null(
115; CHECK-NEXT:    ret i1 true
116;
117  %gep = getelementptr inbounds [2 x i32], ptr @g, i64 1
118  %cmp = icmp ugt ptr %gep, null
119  ret i1 %cmp
120}
121
122define i1 @global_gep_sgt_null() {
123; CHECK-LABEL: @global_gep_sgt_null(
124; CHECK-NEXT:    ret i1 icmp sgt (ptr getelementptr inbounds ([2 x i32], ptr @g, i64 1), ptr null)
125;
126  %gep = getelementptr inbounds [2 x i32], ptr @g, i64 1
127  %cmp = icmp sgt ptr %gep, null
128  ret i1 %cmp
129}
130
131; @g2_weak may be null, in which case this is a zero-index GEP and the pointers
132; are equal.
133define i1 @null_gep_ne_null() {
134; CHECK-LABEL: @null_gep_ne_null(
135; CHECK-NEXT:    ret i1 icmp ne (ptr getelementptr (i8, ptr null, i64 ptrtoint (ptr @g2_weak to i64)), ptr null)
136;
137  %gep = getelementptr i8, ptr null, i64 ptrtoint (ptr @g2_weak to i64)
138  %cmp = icmp ne ptr %gep, null
139  ret i1 %cmp
140}
141
142define i1 @null_gep_ugt_null() {
143; CHECK-LABEL: @null_gep_ugt_null(
144; CHECK-NEXT:    ret i1 icmp ugt (ptr getelementptr (i8, ptr null, i64 ptrtoint (ptr @g2_weak to i64)), ptr null)
145;
146  %gep = getelementptr i8, ptr null, i64 ptrtoint (ptr @g2_weak to i64)
147  %cmp = icmp ugt ptr %gep, null
148  ret i1 %cmp
149}
150
151define i1 @null_gep_sgt_null() {
152; CHECK-LABEL: @null_gep_sgt_null(
153; CHECK-NEXT:    ret i1 icmp sgt (ptr getelementptr (i8, ptr null, i64 ptrtoint (ptr @g2_weak to i64)), ptr null)
154;
155  %gep = getelementptr i8, ptr null, i64 ptrtoint (ptr @g2_weak to i64)
156  %cmp = icmp sgt ptr %gep, null
157  ret i1 %cmp
158}
159
160define i1 @null_gep_ne_null_constant_int() {
161; CHECK-LABEL: @null_gep_ne_null_constant_int(
162; CHECK-NEXT:    ret i1 true
163;
164  %gep = getelementptr i8, ptr null, i64 1
165  %cmp = icmp ne ptr %gep, null
166  ret i1 %cmp
167}
168
169define i1 @null_gep_ugt_null_constant_int() {
170; CHECK-LABEL: @null_gep_ugt_null_constant_int(
171; CHECK-NEXT:    ret i1 true
172;
173  %gep = getelementptr i8, ptr null, i64 1
174  %cmp = icmp ugt ptr %gep, null
175  ret i1 %cmp
176}
177
178define i1 @null_gep_ne_global() {
179; CHECK-LABEL: @null_gep_ne_global(
180; CHECK-NEXT:    ret i1 icmp ne (ptr getelementptr (i8, ptr null, i64 ptrtoint (ptr @g3 to i64)), ptr @g3)
181;
182  %gep = getelementptr i8, ptr null, i64 ptrtoint (ptr @g3 to i64)
183  %cmp = icmp ne ptr %gep, @g3
184  ret i1 %cmp
185}
186
187define i1 @null_gep_ult_global() {
188; CHECK-LABEL: @null_gep_ult_global(
189; CHECK-NEXT:    ret i1 icmp ult (ptr getelementptr (i8, ptr null, i64 ptrtoint (ptr @g3 to i64)), ptr @g3)
190;
191  %gep = getelementptr i8, ptr null, i64 ptrtoint (ptr @g3 to i64)
192  %cmp = icmp ult ptr %gep, @g3
193  ret i1 %cmp
194}
195
196define i1 @null_gep_slt_global() {
197; CHECK-LABEL: @null_gep_slt_global(
198; CHECK-NEXT:    ret i1 icmp slt (ptr getelementptr ([2 x i32], ptr null, i64 ptrtoint (ptr @g2 to i64)), ptr @g)
199;
200  %gep = getelementptr [2 x i32], ptr null, i64 ptrtoint (ptr @g2 to i64)
201  %cmp = icmp slt ptr %gep, @g
202  ret i1 %cmp
203}
204
205define i1 @global_gep_ne_global() {
206; CHECK-LABEL: @global_gep_ne_global(
207; CHECK-NEXT:    ret i1 true
208;
209  %gep = getelementptr inbounds [2 x i32], ptr @g, i64 1
210  %cmp = icmp ne ptr %gep, @g
211  ret i1 %cmp
212}
213
214define i1 @global_gep_ugt_global() {
215; CHECK-LABEL: @global_gep_ugt_global(
216; CHECK-NEXT:    ret i1 true
217;
218  %gep = getelementptr inbounds [2 x i32], ptr @g, i64 1
219  %cmp = icmp ugt ptr %gep, @g
220  ret i1 %cmp
221}
222
223define i1 @global_gep_sgt_global() {
224; CHECK-LABEL: @global_gep_sgt_global(
225; CHECK-NEXT:    ret i1 icmp sgt (ptr getelementptr inbounds ([2 x i32], ptr @g, i64 1), ptr @g)
226;
227  %gep = getelementptr inbounds [2 x i32], ptr @g, i64 1
228  %cmp = icmp sgt ptr %gep, @g
229  ret i1 %cmp
230}
231
232; This should not fold to true, as the offset is negative.
233define i1 @global_gep_ugt_global_neg_offset() {
234; CHECK-LABEL: @global_gep_ugt_global_neg_offset(
235; CHECK-NEXT:    ret i1 icmp ugt (ptr getelementptr ([2 x i32], ptr @g, i64 -1), ptr @g)
236;
237  %gep = getelementptr [2 x i32], ptr @g, i64 -1
238  %cmp = icmp ugt ptr %gep, @g
239  ret i1 %cmp
240}
241
242define i1 @global_gep_sgt_global_neg_offset() {
243; CHECK-LABEL: @global_gep_sgt_global_neg_offset(
244; CHECK-NEXT:    ret i1 icmp sgt (ptr getelementptr ([2 x i32], ptr @g, i64 -1), ptr @g)
245;
246  %gep = getelementptr [2 x i32], ptr @g, i64 -1
247  %cmp = icmp sgt ptr %gep, @g
248  ret i1 %cmp
249}
250
251define i1 @global_gep_ugt_global_gep() {
252; CHECK-LABEL: @global_gep_ugt_global_gep(
253; CHECK-NEXT:    ret i1 true
254;
255  %gep2 = getelementptr inbounds [2 x i32], ptr @g, i64 0, i64 1
256  %cmp = icmp ugt ptr %gep2, @g
257  ret i1 %cmp
258}
259
260; Should not fold due to signed comparison.
261define i1 @global_gep_sgt_global_gep() {
262; CHECK-LABEL: @global_gep_sgt_global_gep(
263; CHECK-NEXT:    ret i1 icmp sgt (ptr getelementptr inbounds ([2 x i32], ptr @g, i64 0, i64 1), ptr @g)
264;
265  %gep2 = getelementptr inbounds [2 x i32], ptr @g, i64 0, i64 1
266  %cmp = icmp sgt ptr %gep2, @g
267  ret i1 %cmp
268}
269
270define i1 @global_gep_ugt_global_gep_complex() {
271; CHECK-LABEL: @global_gep_ugt_global_gep_complex(
272; CHECK-NEXT:    ret i1 true
273;
274  %gep3 = getelementptr inbounds i8, ptr @g, i64 2
275  %cmp = icmp ugt ptr %gep3, @g
276  ret i1 %cmp
277}
278