1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=instsimplify -S | FileCheck %s
4 ; This is a specialization of generic folds for min/max values targeted to the
6 ; Related tests for non-pointer types should be included in another file.
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.
13 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
15 ; (X == null) && (X > Y) --> false
17 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19 define i1 @ugt_and_min(ptr %x, ptr %y) {
20 ; CHECK-LABEL: @ugt_and_min(
21 ; CHECK-NEXT: ret i1 false
23 %cmp = icmp ugt ptr %x, %y
24 %cmpeq = icmp eq ptr %x, null
25 %r = and i1 %cmp, %cmpeq
29 define i1 @ugt_and_min_commute(ptr %x, ptr %y) {
30 ; CHECK-LABEL: @ugt_and_min_commute(
31 ; CHECK-NEXT: ret i1 false
33 %cmp = icmp ugt ptr %x, %y
34 %cmpeq = icmp eq ptr %x, null
35 %r = and i1 %cmpeq, %cmp
39 define i1 @ugt_swap_and_min(ptr %x, ptr %y) {
40 ; CHECK-LABEL: @ugt_swap_and_min(
41 ; CHECK-NEXT: ret i1 false
43 %cmp = icmp ult ptr %y, %x
44 %cmpeq = icmp eq ptr %x, null
45 %r = and i1 %cmp, %cmpeq
49 define i1 @ugt_swap_and_min_commute(ptr %x, ptr %y) {
50 ; CHECK-LABEL: @ugt_swap_and_min_commute(
51 ; CHECK-NEXT: ret i1 false
53 %cmp = icmp ult ptr %y, %x
54 %cmpeq = icmp eq ptr %x, null
55 %r = and i1 %cmpeq, %cmp
59 ; Negative test - signed compare
61 define 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]]
68 %cmp = icmp sgt ptr %x, %y
69 %cmpeq = icmp eq ptr %x, null
70 %r = and i1 %cmp, %cmpeq
74 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
76 ; (X != null) || (X <= Y) --> true
78 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
80 define i1 @ule_or_not_min(ptr %x, ptr %y) {
81 ; CHECK-LABEL: @ule_or_not_min(
82 ; CHECK-NEXT: ret i1 true
84 %cmp = icmp ule ptr %x, %y
85 %cmpeq = icmp ne ptr %x, null
86 %r = or i1 %cmp, %cmpeq
90 define i1 @ule_or_not_min_commute(ptr %x, ptr %y) {
91 ; CHECK-LABEL: @ule_or_not_min_commute(
92 ; CHECK-NEXT: ret i1 true
94 %cmp = icmp ule ptr %x, %y
95 %cmpeq = icmp ne ptr %x, null
96 %r = or i1 %cmpeq, %cmp
100 define i1 @ule_swap_or_not_min(ptr %x, ptr %y) {
101 ; CHECK-LABEL: @ule_swap_or_not_min(
102 ; CHECK-NEXT: ret i1 true
104 %cmp = icmp uge ptr %y, %x
105 %cmpeq = icmp ne ptr %x, null
106 %r = or i1 %cmp, %cmpeq
110 define 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
114 %cmp = icmp uge ptr %y, %x
115 %cmpeq = icmp ne ptr %x, null
116 %r = or i1 %cmpeq, %cmp
120 ; Negative test - signed compare
122 define 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]]
129 %cmp = icmp sle ptr %x, %y
130 %cmpeq = icmp ne ptr %x, null
131 %r = or i1 %cmp, %cmpeq
135 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
137 ; (X == null) && (X <= Y) --> X == null
139 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
141 define 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]]
146 %cmp = icmp ule ptr %x, %y
147 %cmpeq = icmp eq ptr %x, null
148 %r = and i1 %cmp, %cmpeq
152 define 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]]
157 %cmp = icmp ule ptr %x, %y
158 %cmpeq = icmp eq ptr %x, null
159 %r = and i1 %cmpeq, %cmp
163 define 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]]
168 %cmp = icmp uge ptr %y, %x
169 %cmpeq = icmp eq ptr %x, null
170 %r = and i1 %cmp, %cmpeq
174 define 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]]
179 %cmp = icmp uge ptr %y, %x
180 %cmpeq = icmp eq ptr %x, null
181 %r = and i1 %cmpeq, %cmp
185 ; Negative test - signed compare
187 define 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]]
194 %cmp = icmp sle ptr %x, %y
195 %cmpeq = icmp eq ptr %x, null
196 %r = and i1 %cmp, %cmpeq
200 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
202 ; (X == null) || (X <= Y) --> X <= Y
204 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
206 define 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]]
211 %cmp = icmp ule ptr %x, %y
212 %cmpeq = icmp eq ptr %x, null
213 %r = or i1 %cmp, %cmpeq
217 define 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]]
222 %cmp = icmp ule ptr %x, %y
223 %cmpeq = icmp eq ptr %x, null
224 %r = or i1 %cmpeq, %cmp
228 define 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]]
233 %cmp = icmp uge ptr %y, %x
234 %cmpeq = icmp eq ptr %x, null
235 %r = or i1 %cmp, %cmpeq
239 define 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]]
244 %cmp = icmp uge ptr %y, %x
245 %cmpeq = icmp eq ptr %x, null
246 %r = or i1 %cmpeq, %cmp
250 ; Negative test - signed compare
252 define 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]]
259 %cmp = icmp sle ptr %x, %y
260 %cmpeq = icmp eq ptr %x, null
261 %r = or i1 %cmp, %cmpeq
265 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
267 ; (X != null) && (X > Y) --> X > Y
269 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
271 define 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]]
276 %cmp = icmp ugt ptr %x, %y
277 %cmpeq = icmp ne ptr %x, null
278 %r = and i1 %cmp, %cmpeq
282 define 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]]
287 %cmp = icmp ugt ptr %x, %y
288 %cmpeq = icmp ne ptr %x, null
289 %r = and i1 %cmpeq, %cmp
293 define 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]]
298 %cmp = icmp ult ptr %y, %x
299 %cmpeq = icmp ne ptr %x, null
300 %r = and i1 %cmp, %cmpeq
304 define 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]]
309 %cmp = icmp ult ptr %y, %x
310 %cmpeq = icmp ne ptr %x, null
311 %r = and i1 %cmpeq, %cmp
315 ; Negative test - signed compare
317 define 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]]
324 %cmp = icmp sgt ptr %x, %y
325 %cmpeq = icmp ne ptr %x, null
326 %r = and i1 %cmp, %cmpeq
330 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
332 ; (X != null) || (X > Y) --> X != null
334 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
336 define 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]]
341 %cmp = icmp ugt ptr %x, %y
342 %cmpeq = icmp ne ptr %x, null
343 %r = or i1 %cmp, %cmpeq
347 define 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]]
352 %cmp = icmp ugt ptr %x, %y
353 %cmpeq = icmp ne ptr %x, null
354 %r = or i1 %cmpeq, %cmp
358 define 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]]
363 %cmp = icmp ult ptr %y, %x
364 %cmpeq = icmp ne ptr %x, null
365 %r = or i1 %cmp, %cmpeq
369 define 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]]
374 %cmp = icmp ult ptr %y, %x
375 %cmpeq = icmp ne ptr %x, null
376 %r = or i1 %cmpeq, %cmp
380 ; Negative test - signed compare
382 define 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]]
389 %cmp = icmp sgt ptr %x, %y
390 %cmpeq = icmp ne ptr %x, null
391 %r = or i1 %cmp, %cmpeq