xref: /llvm-project/llvm/test/Transforms/InstSimplify/ConstProp/icmp-global.ll (revision 10f315dc9c96ec2413881ab55a285e35d80def88)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -passes=instsimplify,verify -S | 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:    [[CMP:%.*]] = icmp slt ptr @ugt_null_constexpr, null
51; CHECK-NEXT:    ret i1 [[CMP]]
52;
53  %cmp = icmp slt ptr @ugt_null_constexpr, null
54  ret i1 %cmp
55}
56
57; Negative test - we don't try to evaluate this comparison of constant expressions.
58
59define i1 @ult_constexpr_constexpr_one(ptr %x) {
60; CHECK-LABEL: @ult_constexpr_constexpr_one(
61; CHECK-NEXT:    [[CMP:%.*]] = icmp ult ptr @ugt_null_constexpr, inttoptr (i32 1 to ptr)
62; CHECK-NEXT:    ret i1 [[CMP]]
63;
64  %cmp = icmp ult ptr @ugt_null_constexpr, inttoptr (i32 1 to ptr)
65  ret i1 %cmp
66}
67
68@g = global [2 x i32] [i32 1, i32 2]
69@g2 = global i32 0
70@g2_weak = extern_weak global i32
71@g3 = global i8 0
72
73define i1 @global_ne_null() {
74; CHECK-LABEL: @global_ne_null(
75; CHECK-NEXT:    ret i1 true
76;
77  %cmp = icmp ne ptr @g, null
78  ret i1 %cmp
79}
80
81define i1 @global_ugt_null() {
82; CHECK-LABEL: @global_ugt_null(
83; CHECK-NEXT:    ret i1 true
84;
85  %cmp = icmp ugt ptr @g, null
86  ret i1 %cmp
87}
88
89define i1 @global_sgt_null() {
90; CHECK-LABEL: @global_sgt_null(
91; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt ptr @g, null
92; CHECK-NEXT:    ret i1 [[CMP]]
93;
94  %cmp = icmp sgt ptr @g, null
95  ret i1 %cmp
96}
97
98; Should not fold to true, as the gep computes a null value.
99define i1 @global_out_of_bounds_gep_ne_null() {
100; CHECK-LABEL: @global_out_of_bounds_gep_ne_null(
101; CHECK-NEXT:    [[CMP:%.*]] = icmp ne ptr getelementptr (i8, ptr @g3, i64 sub (i64 0, i64 ptrtoint (ptr @g3 to i64))), null
102; CHECK-NEXT:    ret i1 [[CMP]]
103;
104  %cmp = icmp ne ptr getelementptr (i8, ptr @g3, i64 sub (i64 0, i64 ptrtoint (ptr @g3 to i64))), null
105  ret i1 %cmp
106}
107
108define i1 @global_inbounds_gep_ne_null() {
109; CHECK-LABEL: @global_inbounds_gep_ne_null(
110; CHECK-NEXT:    ret i1 true
111;
112  %gep = getelementptr inbounds [2 x i32], ptr @g, i64 1
113  %cmp = icmp ne ptr %gep, null
114  ret i1 %cmp
115}
116
117define i1 @global_gep_ugt_null() {
118; CHECK-LABEL: @global_gep_ugt_null(
119; CHECK-NEXT:    ret i1 true
120;
121  %gep = getelementptr inbounds [2 x i32], ptr @g, i64 1
122  %cmp = icmp ugt ptr %gep, null
123  ret i1 %cmp
124}
125
126define i1 @global_gep_sgt_null() {
127; CHECK-LABEL: @global_gep_sgt_null(
128; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt ptr getelementptr inbounds nuw (i8, ptr @g, i64 8), null
129; CHECK-NEXT:    ret i1 [[CMP]]
130;
131  %gep = getelementptr inbounds [2 x i32], ptr @g, i64 1
132  %cmp = icmp sgt ptr %gep, null
133  ret i1 %cmp
134}
135
136; @g2_weak may be null, in which case this is a zero-index GEP and the pointers
137; are equal.
138define i1 @null_gep_ne_null() {
139; CHECK-LABEL: @null_gep_ne_null(
140; CHECK-NEXT:    [[CMP:%.*]] = icmp ne ptr getelementptr (i8, ptr null, i64 ptrtoint (ptr @g2_weak to i64)), null
141; CHECK-NEXT:    ret i1 [[CMP]]
142;
143  %gep = getelementptr i8, ptr null, i64 ptrtoint (ptr @g2_weak to i64)
144  %cmp = icmp ne ptr %gep, null
145  ret i1 %cmp
146}
147
148define i1 @null_gep_ugt_null() {
149; CHECK-LABEL: @null_gep_ugt_null(
150; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt ptr getelementptr (i8, ptr null, i64 ptrtoint (ptr @g2_weak to i64)), null
151; CHECK-NEXT:    ret i1 [[CMP]]
152;
153  %gep = getelementptr i8, ptr null, i64 ptrtoint (ptr @g2_weak to i64)
154  %cmp = icmp ugt ptr %gep, null
155  ret i1 %cmp
156}
157
158define i1 @null_gep_sgt_null() {
159; CHECK-LABEL: @null_gep_sgt_null(
160; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt ptr getelementptr (i8, ptr null, i64 ptrtoint (ptr @g2_weak to i64)), null
161; CHECK-NEXT:    ret i1 [[CMP]]
162;
163  %gep = getelementptr i8, ptr null, i64 ptrtoint (ptr @g2_weak to i64)
164  %cmp = icmp sgt ptr %gep, null
165  ret i1 %cmp
166}
167
168define i1 @null_gep_ne_null_constant_int() {
169; CHECK-LABEL: @null_gep_ne_null_constant_int(
170; CHECK-NEXT:    ret i1 true
171;
172  %gep = getelementptr i8, ptr null, i64 1
173  %cmp = icmp ne ptr %gep, null
174  ret i1 %cmp
175}
176
177define i1 @null_gep_ugt_null_constant_int() {
178; CHECK-LABEL: @null_gep_ugt_null_constant_int(
179; CHECK-NEXT:    ret i1 true
180;
181  %gep = getelementptr i8, ptr null, i64 1
182  %cmp = icmp ugt ptr %gep, null
183  ret i1 %cmp
184}
185
186define i1 @null_gep_ne_global() {
187; CHECK-LABEL: @null_gep_ne_global(
188; CHECK-NEXT:    [[CMP:%.*]] = icmp ne ptr getelementptr (i8, ptr null, i64 ptrtoint (ptr @g3 to i64)), @g3
189; CHECK-NEXT:    ret i1 [[CMP]]
190;
191  %gep = getelementptr i8, ptr null, i64 ptrtoint (ptr @g3 to i64)
192  %cmp = icmp ne ptr %gep, @g3
193  ret i1 %cmp
194}
195
196define i1 @null_gep_ult_global() {
197; CHECK-LABEL: @null_gep_ult_global(
198; CHECK-NEXT:    [[CMP:%.*]] = icmp ult ptr getelementptr (i8, ptr null, i64 ptrtoint (ptr @g3 to i64)), @g3
199; CHECK-NEXT:    ret i1 [[CMP]]
200;
201  %gep = getelementptr i8, ptr null, i64 ptrtoint (ptr @g3 to i64)
202  %cmp = icmp ult ptr %gep, @g3
203  ret i1 %cmp
204}
205
206define i1 @null_gep_slt_global() {
207; CHECK-LABEL: @null_gep_slt_global(
208; CHECK-NEXT:    [[CMP:%.*]] = icmp slt ptr getelementptr ([2 x i32], ptr null, i64 ptrtoint (ptr @g2 to i64)), @g
209; CHECK-NEXT:    ret i1 [[CMP]]
210;
211  %gep = getelementptr [2 x i32], ptr null, i64 ptrtoint (ptr @g2 to i64)
212  %cmp = icmp slt ptr %gep, @g
213  ret i1 %cmp
214}
215
216define i1 @global_gep_ne_global() {
217; CHECK-LABEL: @global_gep_ne_global(
218; CHECK-NEXT:    ret i1 true
219;
220  %gep = getelementptr inbounds [2 x i32], ptr @g, i64 1
221  %cmp = icmp ne ptr %gep, @g
222  ret i1 %cmp
223}
224
225define i1 @global_gep_ugt_global() {
226; CHECK-LABEL: @global_gep_ugt_global(
227; CHECK-NEXT:    ret i1 true
228;
229  %gep = getelementptr inbounds [2 x i32], ptr @g, i64 1
230  %cmp = icmp ugt ptr %gep, @g
231  ret i1 %cmp
232}
233
234define i1 @global_gep_sgt_global() {
235; CHECK-LABEL: @global_gep_sgt_global(
236; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt ptr getelementptr inbounds nuw (i8, ptr @g, i64 8), @g
237; CHECK-NEXT:    ret i1 [[CMP]]
238;
239  %gep = getelementptr inbounds [2 x i32], ptr @g, i64 1
240  %cmp = icmp sgt ptr %gep, @g
241  ret i1 %cmp
242}
243
244; This should not fold to true, as the offset is negative.
245define i1 @global_gep_ugt_global_neg_offset() {
246; CHECK-LABEL: @global_gep_ugt_global_neg_offset(
247; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt ptr getelementptr (i8, ptr @g, i64 -8), @g
248; CHECK-NEXT:    ret i1 [[CMP]]
249;
250  %gep = getelementptr [2 x i32], ptr @g, i64 -1
251  %cmp = icmp ugt ptr %gep, @g
252  ret i1 %cmp
253}
254
255define i1 @global_gep_sgt_global_neg_offset() {
256; CHECK-LABEL: @global_gep_sgt_global_neg_offset(
257; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt ptr getelementptr (i8, ptr @g, i64 -8), @g
258; CHECK-NEXT:    ret i1 [[CMP]]
259;
260  %gep = getelementptr [2 x i32], ptr @g, i64 -1
261  %cmp = icmp sgt ptr %gep, @g
262  ret i1 %cmp
263}
264
265define i1 @global_gep_ugt_global_gep() {
266; CHECK-LABEL: @global_gep_ugt_global_gep(
267; CHECK-NEXT:    ret i1 true
268;
269  %gep2 = getelementptr inbounds [2 x i32], ptr @g, i64 0, i64 1
270  %cmp = icmp ugt ptr %gep2, @g
271  ret i1 %cmp
272}
273
274; Should not fold due to signed comparison.
275define i1 @global_gep_sgt_global_gep() {
276; CHECK-LABEL: @global_gep_sgt_global_gep(
277; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt ptr getelementptr inbounds nuw (i8, ptr @g, i64 4), @g
278; CHECK-NEXT:    ret i1 [[CMP]]
279;
280  %gep2 = getelementptr inbounds [2 x i32], ptr @g, i64 0, i64 1
281  %cmp = icmp sgt ptr %gep2, @g
282  ret i1 %cmp
283}
284
285define i1 @global_gep_ugt_global_gep_complex() {
286; CHECK-LABEL: @global_gep_ugt_global_gep_complex(
287; CHECK-NEXT:    ret i1 true
288;
289  %gep3 = getelementptr inbounds i8, ptr @g, i64 2
290  %cmp = icmp ugt ptr %gep3, @g
291  ret i1 %cmp
292}
293
294declare void @func()
295
296define i1 @global_no_cfi() {
297; CHECK-LABEL: @global_no_cfi(
298; CHECK-NEXT:    [[CMP:%.*]] = icmp eq ptr @func, no_cfi @func
299; CHECK-NEXT:    ret i1 [[CMP]]
300;
301  %cmp = icmp eq ptr @func, no_cfi @func
302  ret i1 %cmp
303}
304
305define i1 @blockaddr_no_cfi() {
306; CHECK-LABEL: @blockaddr_no_cfi(
307; CHECK-NEXT:    br label [[BB:%.*]]
308; CHECK:       bb:
309; CHECK-NEXT:    [[CMP:%.*]] = icmp eq ptr blockaddress(@blockaddr_no_cfi, [[BB]]), no_cfi @func
310; CHECK-NEXT:    ret i1 [[CMP]]
311;
312  br label %bb
313
314bb:
315  %cmp = icmp eq ptr blockaddress(@blockaddr_no_cfi, %bb), no_cfi @func
316  ret i1 %cmp
317}
318
319define i1 @global_no_cfi_dso_local_equivalent() {
320; CHECK-LABEL: @global_no_cfi_dso_local_equivalent(
321; CHECK-NEXT:    [[CMP:%.*]] = icmp eq ptr dso_local_equivalent @func, no_cfi @func
322; CHECK-NEXT:    ret i1 [[CMP]]
323;
324  %cmp = icmp eq ptr dso_local_equivalent @func, no_cfi @func
325  ret i1 %cmp
326}
327