xref: /llvm-project/llvm/test/Transforms/InstSimplify/and-or-icmp-nullptr.ll (revision 04b944e23050e4e0c6ee983cc9bc17740315ea4f)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -passes=instsimplify -S | FileCheck %s
3
4; This is a specialization of generic folds for min/max values targeted to the
5; 'null' ptr constant.
6; Related tests for non-pointer types should be included in another file.
7
8; There are 6 basic patterns (or 3 with DeMorganized equivalent) with
9;    2 (commute logic op) *
10;    2 (swap compare operands) *
11; variations for a total of 24 tests.
12
13;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
14;
15; (X == null) && (X > Y) --> false
16;
17;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18
19define i1 @ugt_and_min(ptr %x, ptr %y)  {
20; CHECK-LABEL: @ugt_and_min(
21; CHECK-NEXT:    ret i1 false
22;
23  %cmp = icmp ugt ptr %x, %y
24  %cmpeq = icmp eq ptr %x, null
25  %r = and i1 %cmp, %cmpeq
26  ret i1 %r
27}
28
29define i1 @ugt_and_min_commute(ptr %x, ptr %y)  {
30; CHECK-LABEL: @ugt_and_min_commute(
31; CHECK-NEXT:    ret i1 false
32;
33  %cmp = icmp ugt ptr %x, %y
34  %cmpeq = icmp eq ptr %x, null
35  %r = and i1 %cmpeq, %cmp
36  ret i1 %r
37}
38
39define i1 @ugt_swap_and_min(ptr %x, ptr %y)  {
40; CHECK-LABEL: @ugt_swap_and_min(
41; CHECK-NEXT:    ret i1 false
42;
43  %cmp = icmp ult ptr %y, %x
44  %cmpeq = icmp eq ptr %x, null
45  %r = and i1 %cmp, %cmpeq
46  ret i1 %r
47}
48
49define i1 @ugt_swap_and_min_commute(ptr %x, ptr %y)  {
50; CHECK-LABEL: @ugt_swap_and_min_commute(
51; CHECK-NEXT:    ret i1 false
52;
53  %cmp = icmp ult ptr %y, %x
54  %cmpeq = icmp eq ptr %x, null
55  %r = and i1 %cmpeq, %cmp
56  ret i1 %r
57}
58
59; Negative test - signed compare
60
61define i1 @sgt_and_min(ptr %x, ptr %y)  {
62; CHECK-LABEL: @sgt_and_min(
63; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt ptr [[X:%.*]], [[Y:%.*]]
64; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp eq ptr [[X]], null
65; CHECK-NEXT:    [[R:%.*]] = and i1 [[CMP]], [[CMPEQ]]
66; CHECK-NEXT:    ret i1 [[R]]
67;
68  %cmp = icmp sgt ptr %x, %y
69  %cmpeq = icmp eq ptr %x, null
70  %r = and i1 %cmp, %cmpeq
71  ret i1 %r
72}
73
74;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
75;
76; (X != null) || (X <= Y) --> true
77;
78;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
79
80define i1 @ule_or_not_min(ptr %x, ptr %y)  {
81; CHECK-LABEL: @ule_or_not_min(
82; CHECK-NEXT:    ret i1 true
83;
84  %cmp = icmp ule ptr %x, %y
85  %cmpeq = icmp ne ptr %x, null
86  %r = or i1 %cmp, %cmpeq
87  ret i1 %r
88}
89
90define i1 @ule_or_not_min_commute(ptr %x, ptr %y)  {
91; CHECK-LABEL: @ule_or_not_min_commute(
92; CHECK-NEXT:    ret i1 true
93;
94  %cmp = icmp ule ptr %x, %y
95  %cmpeq = icmp ne ptr %x, null
96  %r = or i1 %cmpeq, %cmp
97  ret i1 %r
98}
99
100define i1 @ule_swap_or_not_min(ptr %x, ptr %y)  {
101; CHECK-LABEL: @ule_swap_or_not_min(
102; CHECK-NEXT:    ret i1 true
103;
104  %cmp = icmp uge ptr %y, %x
105  %cmpeq = icmp ne ptr %x, null
106  %r = or i1 %cmp, %cmpeq
107  ret i1 %r
108}
109
110define i1 @ule_swap_or_not_min_commute(ptr %x, ptr %y)  {
111; CHECK-LABEL: @ule_swap_or_not_min_commute(
112; CHECK-NEXT:    ret i1 true
113;
114  %cmp = icmp uge ptr %y, %x
115  %cmpeq = icmp ne ptr %x, null
116  %r = or i1 %cmpeq, %cmp
117  ret i1 %r
118}
119
120; Negative test - signed compare
121
122define i1 @sle_or_not_min(ptr %x, ptr %y)  {
123; CHECK-LABEL: @sle_or_not_min(
124; CHECK-NEXT:    [[CMP:%.*]] = icmp sle ptr [[X:%.*]], [[Y:%.*]]
125; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp ne ptr [[X]], null
126; CHECK-NEXT:    [[R:%.*]] = or i1 [[CMP]], [[CMPEQ]]
127; CHECK-NEXT:    ret i1 [[R]]
128;
129  %cmp = icmp sle ptr %x, %y
130  %cmpeq = icmp ne ptr %x, null
131  %r = or i1 %cmp, %cmpeq
132  ret i1 %r
133}
134
135;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
136;
137; (X == null) && (X <= Y) --> X == null
138;
139;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
140
141define i1 @ule_and_min(ptr %x, ptr %y)  {
142; CHECK-LABEL: @ule_and_min(
143; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp eq ptr [[X:%.*]], null
144; CHECK-NEXT:    ret i1 [[CMPEQ]]
145;
146  %cmp = icmp ule ptr %x, %y
147  %cmpeq = icmp eq ptr %x, null
148  %r = and i1 %cmp, %cmpeq
149  ret i1 %r
150}
151
152define i1 @ule_and_min_commute(ptr %x, ptr %y)  {
153; CHECK-LABEL: @ule_and_min_commute(
154; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp eq ptr [[X:%.*]], null
155; CHECK-NEXT:    ret i1 [[CMPEQ]]
156;
157  %cmp = icmp ule ptr %x, %y
158  %cmpeq = icmp eq ptr %x, null
159  %r = and i1 %cmpeq, %cmp
160  ret i1 %r
161}
162
163define i1 @ule_swap_and_min(ptr %x, ptr %y)  {
164; CHECK-LABEL: @ule_swap_and_min(
165; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp eq ptr [[X:%.*]], null
166; CHECK-NEXT:    ret i1 [[CMPEQ]]
167;
168  %cmp = icmp uge ptr %y, %x
169  %cmpeq = icmp eq ptr %x, null
170  %r = and i1 %cmp, %cmpeq
171  ret i1 %r
172}
173
174define i1 @ule_swap_and_min_commute(ptr %x, ptr %y)  {
175; CHECK-LABEL: @ule_swap_and_min_commute(
176; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp eq ptr [[X:%.*]], null
177; CHECK-NEXT:    ret i1 [[CMPEQ]]
178;
179  %cmp = icmp uge ptr %y, %x
180  %cmpeq = icmp eq ptr %x, null
181  %r = and i1 %cmpeq, %cmp
182  ret i1 %r
183}
184
185; Negative test - signed compare
186
187define i1 @sle_and_min(ptr %x, ptr %y)  {
188; CHECK-LABEL: @sle_and_min(
189; CHECK-NEXT:    [[CMP:%.*]] = icmp sle ptr [[X:%.*]], [[Y:%.*]]
190; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp eq ptr [[X]], null
191; CHECK-NEXT:    [[R:%.*]] = and i1 [[CMP]], [[CMPEQ]]
192; CHECK-NEXT:    ret i1 [[R]]
193;
194  %cmp = icmp sle ptr %x, %y
195  %cmpeq = icmp eq ptr %x, null
196  %r = and i1 %cmp, %cmpeq
197  ret i1 %r
198}
199
200;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
201;
202; (X == null) || (X <= Y) --> X <= Y
203;
204;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
205
206define i1 @ule_or_min(ptr %x, ptr %y)  {
207; CHECK-LABEL: @ule_or_min(
208; CHECK-NEXT:    [[CMP:%.*]] = icmp ule ptr [[X:%.*]], [[Y:%.*]]
209; CHECK-NEXT:    ret i1 [[CMP]]
210;
211  %cmp = icmp ule ptr %x, %y
212  %cmpeq = icmp eq ptr %x, null
213  %r = or i1 %cmp, %cmpeq
214  ret i1 %r
215}
216
217define i1 @ule_or_min_commute(ptr %x, ptr %y)  {
218; CHECK-LABEL: @ule_or_min_commute(
219; CHECK-NEXT:    [[CMP:%.*]] = icmp ule ptr [[X:%.*]], [[Y:%.*]]
220; CHECK-NEXT:    ret i1 [[CMP]]
221;
222  %cmp = icmp ule ptr %x, %y
223  %cmpeq = icmp eq ptr %x, null
224  %r = or i1 %cmpeq, %cmp
225  ret i1 %r
226}
227
228define i1 @ule_swap_or_min(ptr %x, ptr %y)  {
229; CHECK-LABEL: @ule_swap_or_min(
230; CHECK-NEXT:    [[CMP:%.*]] = icmp uge ptr [[Y:%.*]], [[X:%.*]]
231; CHECK-NEXT:    ret i1 [[CMP]]
232;
233  %cmp = icmp uge ptr %y, %x
234  %cmpeq = icmp eq ptr %x, null
235  %r = or i1 %cmp, %cmpeq
236  ret i1 %r
237}
238
239define i1 @ule_swap_or_min_commute(ptr %x, ptr %y)  {
240; CHECK-LABEL: @ule_swap_or_min_commute(
241; CHECK-NEXT:    [[CMP:%.*]] = icmp uge ptr [[Y:%.*]], [[X:%.*]]
242; CHECK-NEXT:    ret i1 [[CMP]]
243;
244  %cmp = icmp uge ptr %y, %x
245  %cmpeq = icmp eq ptr %x, null
246  %r = or i1 %cmpeq, %cmp
247  ret i1 %r
248}
249
250; Negative test - signed compare
251
252define i1 @sle_or_min(ptr %x, ptr %y)  {
253; CHECK-LABEL: @sle_or_min(
254; CHECK-NEXT:    [[CMP:%.*]] = icmp sle ptr [[X:%.*]], [[Y:%.*]]
255; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp eq ptr [[X]], null
256; CHECK-NEXT:    [[R:%.*]] = or i1 [[CMP]], [[CMPEQ]]
257; CHECK-NEXT:    ret i1 [[R]]
258;
259  %cmp = icmp sle ptr %x, %y
260  %cmpeq = icmp eq ptr %x, null
261  %r = or i1 %cmp, %cmpeq
262  ret i1 %r
263}
264
265;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
266;
267; (X != null) && (X > Y) --> X > Y
268;
269;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
270
271define i1 @ugt_and_not_min(ptr %x, ptr %y)  {
272; CHECK-LABEL: @ugt_and_not_min(
273; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt ptr [[X:%.*]], [[Y:%.*]]
274; CHECK-NEXT:    ret i1 [[CMP]]
275;
276  %cmp = icmp ugt ptr %x, %y
277  %cmpeq = icmp ne ptr %x, null
278  %r = and i1 %cmp, %cmpeq
279  ret i1 %r
280}
281
282define i1 @ugt_and_not_min_commute(ptr %x, ptr %y)  {
283; CHECK-LABEL: @ugt_and_not_min_commute(
284; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt ptr [[X:%.*]], [[Y:%.*]]
285; CHECK-NEXT:    ret i1 [[CMP]]
286;
287  %cmp = icmp ugt ptr %x, %y
288  %cmpeq = icmp ne ptr %x, null
289  %r = and i1 %cmpeq, %cmp
290  ret i1 %r
291}
292
293define i1 @ugt_swap_and_not_min(ptr %x, ptr %y)  {
294; CHECK-LABEL: @ugt_swap_and_not_min(
295; CHECK-NEXT:    [[CMP:%.*]] = icmp ult ptr [[Y:%.*]], [[X:%.*]]
296; CHECK-NEXT:    ret i1 [[CMP]]
297;
298  %cmp = icmp ult ptr %y, %x
299  %cmpeq = icmp ne ptr %x, null
300  %r = and i1 %cmp, %cmpeq
301  ret i1 %r
302}
303
304define i1 @ugt_swap_and_not_min_commute(ptr %x, ptr %y)  {
305; CHECK-LABEL: @ugt_swap_and_not_min_commute(
306; CHECK-NEXT:    [[CMP:%.*]] = icmp ult ptr [[Y:%.*]], [[X:%.*]]
307; CHECK-NEXT:    ret i1 [[CMP]]
308;
309  %cmp = icmp ult ptr %y, %x
310  %cmpeq = icmp ne ptr %x, null
311  %r = and i1 %cmpeq, %cmp
312  ret i1 %r
313}
314
315; Negative test - signed compare
316
317define i1 @sgt_and_not_min(ptr %x, ptr %y)  {
318; CHECK-LABEL: @sgt_and_not_min(
319; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt ptr [[X:%.*]], [[Y:%.*]]
320; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp ne ptr [[X]], null
321; CHECK-NEXT:    [[R:%.*]] = and i1 [[CMP]], [[CMPEQ]]
322; CHECK-NEXT:    ret i1 [[R]]
323;
324  %cmp = icmp sgt ptr %x, %y
325  %cmpeq = icmp ne ptr %x, null
326  %r = and i1 %cmp, %cmpeq
327  ret i1 %r
328}
329
330;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
331;
332; (X != null) || (X > Y) --> X != null
333;
334;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
335
336define i1 @ugt_or_not_min(ptr %x, ptr %y)  {
337; CHECK-LABEL: @ugt_or_not_min(
338; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp ne ptr [[X:%.*]], null
339; CHECK-NEXT:    ret i1 [[CMPEQ]]
340;
341  %cmp = icmp ugt ptr %x, %y
342  %cmpeq = icmp ne ptr %x, null
343  %r = or i1 %cmp, %cmpeq
344  ret i1 %r
345}
346
347define i1 @ugt_or_not_min_commute(ptr %x, ptr %y)  {
348; CHECK-LABEL: @ugt_or_not_min_commute(
349; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp ne ptr [[X:%.*]], null
350; CHECK-NEXT:    ret i1 [[CMPEQ]]
351;
352  %cmp = icmp ugt ptr %x, %y
353  %cmpeq = icmp ne ptr %x, null
354  %r = or i1 %cmpeq, %cmp
355  ret i1 %r
356}
357
358define i1 @ugt_swap_or_not_min(ptr %x, ptr %y)  {
359; CHECK-LABEL: @ugt_swap_or_not_min(
360; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp ne ptr [[X:%.*]], null
361; CHECK-NEXT:    ret i1 [[CMPEQ]]
362;
363  %cmp = icmp ult ptr %y, %x
364  %cmpeq = icmp ne ptr %x, null
365  %r = or i1 %cmp, %cmpeq
366  ret i1 %r
367}
368
369define i1 @ugt_swap_or_not_min_commute(ptr %x, ptr %y)  {
370; CHECK-LABEL: @ugt_swap_or_not_min_commute(
371; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp ne ptr [[X:%.*]], null
372; CHECK-NEXT:    ret i1 [[CMPEQ]]
373;
374  %cmp = icmp ult ptr %y, %x
375  %cmpeq = icmp ne ptr %x, null
376  %r = or i1 %cmpeq, %cmp
377  ret i1 %r
378}
379
380; Negative test - signed compare
381
382define i1 @sgt_or_not_min(ptr %x, ptr %y)  {
383; CHECK-LABEL: @sgt_or_not_min(
384; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt ptr [[X:%.*]], [[Y:%.*]]
385; CHECK-NEXT:    [[CMPEQ:%.*]] = icmp ne ptr [[X]], null
386; CHECK-NEXT:    [[R:%.*]] = or i1 [[CMP]], [[CMPEQ]]
387; CHECK-NEXT:    ret i1 [[R]]
388;
389  %cmp = icmp sgt ptr %x, %y
390  %cmpeq = icmp ne ptr %x, null
391  %r = or i1 %cmp, %cmpeq
392  ret i1 %r
393}
394