1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=instcombine -S | FileCheck %s
4 define void @idom_sign_bit_check_edge_dominates(i64 %a) {
5 ; CHECK-LABEL: @idom_sign_bit_check_edge_dominates(
7 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i64 [[A:%.*]], 0
8 ; CHECK-NEXT: br i1 [[CMP]], label [[LAND_LHS_TRUE:%.*]], label [[LOR_RHS:%.*]]
9 ; CHECK: land.lhs.true:
10 ; CHECK-NEXT: br label [[LOR_END:%.*]]
12 ; CHECK-NEXT: [[CMP2_NOT:%.*]] = icmp eq i64 [[A]], 0
13 ; CHECK-NEXT: br i1 [[CMP2_NOT]], label [[LOR_END]], label [[LAND_RHS:%.*]]
15 ; CHECK-NEXT: br label [[LOR_END]]
17 ; CHECK-NEXT: ret void
20 %cmp = icmp slt i64 %a, 0
21 br i1 %cmp, label %land.lhs.true, label %lor.rhs
27 %cmp2 = icmp sgt i64 %a, 0
28 br i1 %cmp2, label %land.rhs, label %lor.end
37 define void @idom_sign_bit_check_edge_not_dominates(i64 %a, i1 %c1) {
38 ; CHECK-LABEL: @idom_sign_bit_check_edge_not_dominates(
40 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i64 [[A:%.*]], 0
41 ; CHECK-NEXT: br i1 [[CMP]], label [[LAND_LHS_TRUE:%.*]], label [[LOR_RHS:%.*]]
42 ; CHECK: land.lhs.true:
43 ; CHECK-NEXT: br i1 [[C1:%.*]], label [[LOR_END:%.*]], label [[LOR_RHS]]
45 ; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i64 [[A]], 0
46 ; CHECK-NEXT: br i1 [[CMP2]], label [[LAND_RHS:%.*]], label [[LOR_END]]
48 ; CHECK-NEXT: br label [[LOR_END]]
50 ; CHECK-NEXT: ret void
53 %cmp = icmp slt i64 %a, 0
54 br i1 %cmp, label %land.lhs.true, label %lor.rhs
57 br i1 %c1, label %lor.end, label %lor.rhs
60 %cmp2 = icmp sgt i64 %a, 0
61 br i1 %cmp2, label %land.rhs, label %lor.end
70 define void @idom_sign_bit_check_edge_dominates_select(i64 %a, i64 %b) {
71 ; CHECK-LABEL: @idom_sign_bit_check_edge_dominates_select(
73 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i64 [[A:%.*]], 5
74 ; CHECK-NEXT: br i1 [[CMP]], label [[LAND_LHS_TRUE:%.*]], label [[LOR_RHS:%.*]]
75 ; CHECK: land.lhs.true:
76 ; CHECK-NEXT: br label [[LOR_END:%.*]]
78 ; CHECK-NEXT: [[CMP3_NOT:%.*]] = icmp eq i64 [[A]], [[B:%.*]]
79 ; CHECK-NEXT: br i1 [[CMP3_NOT]], label [[LOR_END]], label [[LAND_RHS:%.*]]
81 ; CHECK-NEXT: br label [[LOR_END]]
83 ; CHECK-NEXT: ret void
86 %cmp = icmp slt i64 %a, 5
87 br i1 %cmp, label %land.lhs.true, label %lor.rhs
93 %cmp2 = icmp sgt i64 %a, 5
94 %select = select i1 %cmp2, i64 %a, i64 5
95 %cmp3 = icmp ne i64 %select, %b
96 br i1 %cmp3, label %land.rhs, label %lor.end
105 define void @idom_zbranch(i64 %a) {
106 ; CHECK-LABEL: @idom_zbranch(
108 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i64 [[A:%.*]], 0
109 ; CHECK-NEXT: br i1 [[CMP]], label [[LOR_END:%.*]], label [[LOR_RHS:%.*]]
111 ; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i64 [[A]], 0
112 ; CHECK-NEXT: br i1 [[CMP2]], label [[LAND_RHS:%.*]], label [[LOR_END]]
114 ; CHECK-NEXT: br label [[LOR_END]]
116 ; CHECK-NEXT: ret void
119 %cmp = icmp sgt i64 %a, 0
120 br i1 %cmp, label %lor.end, label %lor.rhs
123 %cmp2 = icmp slt i64 %a, 0
124 br i1 %cmp2, label %land.rhs, label %lor.end
133 define void @idom_not_zbranch(i32 %a, i32 %b) {
134 ; CHECK-LABEL: @idom_not_zbranch(
136 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A:%.*]], 0
137 ; CHECK-NEXT: br i1 [[CMP]], label [[RETURN:%.*]], label [[IF_END:%.*]]
139 ; CHECK-NEXT: [[CMP2_NOT:%.*]] = icmp eq i32 [[A]], [[B:%.*]]
140 ; CHECK-NEXT: br i1 [[CMP2_NOT]], label [[RETURN]], label [[IF_THEN3:%.*]]
142 ; CHECK-NEXT: br label [[RETURN]]
144 ; CHECK-NEXT: ret void
147 %cmp = icmp sgt i32 %a, 0
148 br i1 %cmp, label %return, label %if.end
151 %cmp1 = icmp slt i32 %a, 0
152 %a. = select i1 %cmp1, i32 %a, i32 0
153 %cmp2 = icmp ne i32 %a., %b
154 br i1 %cmp2, label %if.then3, label %return
163 define void @trueblock_cmp_eq(i32 %a, i32 %b) {
164 ; CHECK-LABEL: @trueblock_cmp_eq(
166 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A:%.*]], 0
167 ; CHECK-NEXT: br i1 [[CMP]], label [[IF_END:%.*]], label [[RETURN:%.*]]
169 ; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[A]], 1
170 ; CHECK-NEXT: br i1 [[CMP1]], label [[IF_THEN3:%.*]], label [[RETURN]]
172 ; CHECK-NEXT: br label [[RETURN]]
174 ; CHECK-NEXT: ret void
177 %cmp = icmp sgt i32 %a, 0
178 br i1 %cmp, label %if.end, label %return
181 %cmp1 = icmp slt i32 %a, 2
182 br i1 %cmp1, label %if.then3, label %return
191 define i1 @trueblock_cmp_is_false(i32 %x, i32 %y) {
192 ; CHECK-LABEL: @trueblock_cmp_is_false(
194 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[X:%.*]], [[Y:%.*]]
195 ; CHECK-NEXT: br i1 [[CMP]], label [[T:%.*]], label [[F:%.*]]
197 ; CHECK-NEXT: ret i1 false
199 ; CHECK-NEXT: ret i1 false
202 %cmp = icmp sgt i32 %x, %y
203 br i1 %cmp, label %t, label %f
205 %cmp2 = icmp slt i32 %x, %y
211 define i1 @trueblock_cmp_is_false_commute(i32 %x, i32 %y) {
212 ; CHECK-LABEL: @trueblock_cmp_is_false_commute(
214 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[X:%.*]], [[Y:%.*]]
215 ; CHECK-NEXT: br i1 [[CMP]], label [[T:%.*]], label [[F:%.*]]
217 ; CHECK-NEXT: ret i1 false
219 ; CHECK-NEXT: ret i1 false
222 %cmp = icmp eq i32 %x, %y
223 br i1 %cmp, label %t, label %f
225 %cmp2 = icmp sgt i32 %y, %x
231 define i1 @trueblock_cmp_is_true(i32 %x, i32 %y) {
232 ; CHECK-LABEL: @trueblock_cmp_is_true(
234 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[X:%.*]], [[Y:%.*]]
235 ; CHECK-NEXT: br i1 [[CMP]], label [[T:%.*]], label [[F:%.*]]
237 ; CHECK-NEXT: ret i1 true
239 ; CHECK-NEXT: ret i1 false
242 %cmp = icmp ult i32 %x, %y
243 br i1 %cmp, label %t, label %f
245 %cmp2 = icmp ne i32 %x, %y
251 define i1 @trueblock_cmp_is_true_commute(i32 %x, i32 %y) {
252 ; CHECK-LABEL: @trueblock_cmp_is_true_commute(
254 ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[X:%.*]], [[Y:%.*]]
255 ; CHECK-NEXT: br i1 [[CMP]], label [[T:%.*]], label [[F:%.*]]
257 ; CHECK-NEXT: ret i1 true
259 ; CHECK-NEXT: ret i1 false
262 %cmp = icmp ugt i32 %x, %y
263 br i1 %cmp, label %t, label %f
265 %cmp2 = icmp ne i32 %y, %x
271 define i1 @falseblock_cmp_is_false(i32 %x, i32 %y) {
272 ; CHECK-LABEL: @falseblock_cmp_is_false(
274 ; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp sgt i32 [[X:%.*]], [[Y:%.*]]
275 ; CHECK-NEXT: br i1 [[CMP_NOT]], label [[F:%.*]], label [[T:%.*]]
277 ; CHECK-NEXT: ret i1 true
279 ; CHECK-NEXT: ret i1 false
282 %cmp = icmp sle i32 %x, %y
283 br i1 %cmp, label %t, label %f
287 %cmp2 = icmp slt i32 %x, %y
291 define i1 @falseblock_cmp_is_false_commute(i32 %x, i32 %y) {
292 ; CHECK-LABEL: @falseblock_cmp_is_false_commute(
294 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[X:%.*]], [[Y:%.*]]
295 ; CHECK-NEXT: br i1 [[CMP]], label [[T:%.*]], label [[F:%.*]]
297 ; CHECK-NEXT: ret i1 true
299 ; CHECK-NEXT: ret i1 false
302 %cmp = icmp eq i32 %x, %y
303 br i1 %cmp, label %t, label %f
307 %cmp2 = icmp eq i32 %y, %x
311 define i1 @falseblock_cmp_is_true(i32 %x, i32 %y) {
312 ; CHECK-LABEL: @falseblock_cmp_is_true(
314 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[X:%.*]], [[Y:%.*]]
315 ; CHECK-NEXT: br i1 [[CMP]], label [[T:%.*]], label [[F:%.*]]
317 ; CHECK-NEXT: ret i1 true
319 ; CHECK-NEXT: ret i1 true
322 %cmp = icmp ult i32 %x, %y
323 br i1 %cmp, label %t, label %f
327 %cmp2 = icmp uge i32 %x, %y
331 define i1 @falseblock_cmp_is_true_commute(i32 %x, i32 %y) {
332 ; CHECK-LABEL: @falseblock_cmp_is_true_commute(
334 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[X:%.*]], [[Y:%.*]]
335 ; CHECK-NEXT: br i1 [[CMP]], label [[T:%.*]], label [[F:%.*]]
337 ; CHECK-NEXT: ret i1 true
339 ; CHECK-NEXT: ret i1 true
342 %cmp = icmp sgt i32 %x, %y
343 br i1 %cmp, label %t, label %f
347 %cmp2 = icmp sge i32 %y, %x
351 ; This used to infinite loop because of a conflict
352 ; with min/max canonicalization.
354 define i32 @PR48900(i32 %i, ptr %p) {
355 ; CHECK-LABEL: @PR48900(
356 ; CHECK-NEXT: [[UMAX:%.*]] = call i32 @llvm.umax.i32(i32 [[I:%.*]], i32 1)
357 ; CHECK-NEXT: [[I4:%.*]] = icmp sgt i32 [[UMAX]], 0
358 ; CHECK-NEXT: br i1 [[I4]], label [[TRUELABEL:%.*]], label [[FALSELABEL:%.*]]
360 ; CHECK-NEXT: [[SMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[UMAX]], i32 2)
361 ; CHECK-NEXT: ret i32 [[SMIN]]
363 ; CHECK-NEXT: ret i32 0
365 %maxcmp = icmp ugt i32 %i, 1
366 %umax = select i1 %maxcmp, i32 %i, i32 1
367 %i4 = icmp sgt i32 %umax, 0
368 br i1 %i4, label %truelabel, label %falselabel
371 %mincmp = icmp ult i32 %umax, 2
372 %smin = select i1 %mincmp, i32 %umax, i32 2
379 ; This used to infinite loop because of a conflict
380 ; with min/max canonicalization.
382 define i8 @PR48900_alt(i8 %i, ptr %p) {
383 ; CHECK-LABEL: @PR48900_alt(
384 ; CHECK-NEXT: [[SMAX:%.*]] = call i8 @llvm.smax.i8(i8 [[I:%.*]], i8 -127)
385 ; CHECK-NEXT: [[I4:%.*]] = icmp ugt i8 [[SMAX]], -128
386 ; CHECK-NEXT: br i1 [[I4]], label [[TRUELABEL:%.*]], label [[FALSELABEL:%.*]]
388 ; CHECK-NEXT: [[UMIN:%.*]] = call i8 @llvm.smin.i8(i8 [[SMAX]], i8 -126)
389 ; CHECK-NEXT: ret i8 [[UMIN]]
391 ; CHECK-NEXT: ret i8 0
393 %maxcmp = icmp sgt i8 %i, -127
394 %smax = select i1 %maxcmp, i8 %i, i8 -127
395 %i4 = icmp ugt i8 %smax, 128
396 br i1 %i4, label %truelabel, label %falselabel
399 %mincmp = icmp slt i8 %smax, -126
400 %umin = select i1 %mincmp, i8 %smax, i8 -126
407 define i1 @and_mask1_eq(i32 %conv) {
408 ; CHECK-LABEL: @and_mask1_eq(
410 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[CONV:%.*]], 1
411 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0
412 ; CHECK-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]
414 ; CHECK-NEXT: ret i1 false
416 ; CHECK-NEXT: ret i1 false
419 %and = and i32 %conv, 1
420 %cmp = icmp eq i32 %and, 0
421 br i1 %cmp, label %then, label %else
427 %and1 = and i32 %conv, 3
428 %cmp1 = icmp eq i32 %and1, 0
432 define i1 @and_mask1_ne(i32 %conv) {
433 ; CHECK-LABEL: @and_mask1_ne(
435 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[CONV:%.*]], 1
436 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0
437 ; CHECK-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]
439 ; CHECK-NEXT: ret i1 false
441 ; CHECK-NEXT: ret i1 true
444 %and = and i32 %conv, 1
445 %cmp = icmp eq i32 %and, 0
446 br i1 %cmp, label %then, label %else
452 %and1 = and i32 %conv, 3
453 %cmp1 = icmp ne i32 %and1, 0
457 define i1 @and_mask2(i32 %conv) {
458 ; CHECK-LABEL: @and_mask2(
460 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[CONV:%.*]], 4
461 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0
462 ; CHECK-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]
464 ; CHECK-NEXT: ret i1 false
466 ; CHECK-NEXT: [[AND1:%.*]] = and i32 [[CONV]], 3
467 ; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[AND1]], 0
468 ; CHECK-NEXT: ret i1 [[CMP1]]
471 %and = and i32 %conv, 4
472 %cmp = icmp eq i32 %and, 0
473 br i1 %cmp, label %then, label %else
479 %and1 = and i32 %conv, 3
480 %cmp1 = icmp eq i32 %and1, 0
484 ; TODO: %cmp1 can be folded into false.
486 define i1 @and_mask3(i32 %conv) {
487 ; CHECK-LABEL: @and_mask3(
489 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[CONV:%.*]], 3
490 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0
491 ; CHECK-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]
493 ; CHECK-NEXT: ret i1 false
495 ; CHECK-NEXT: [[AND1:%.*]] = and i32 [[CONV]], 7
496 ; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[AND1]], 0
497 ; CHECK-NEXT: ret i1 [[CMP1]]
500 %and = and i32 %conv, 3
501 %cmp = icmp eq i32 %and, 0
502 br i1 %cmp, label %then, label %else
508 %and1 = and i32 %conv, 7
509 %cmp1 = icmp eq i32 %and1, 0
513 define i1 @and_mask4(i32 %conv) {
514 ; CHECK-LABEL: @and_mask4(
516 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[CONV:%.*]], 4
517 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0
518 ; CHECK-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]
520 ; CHECK-NEXT: ret i1 false
522 ; CHECK-NEXT: ret i1 false
525 %and = and i32 %conv, 4
526 %cmp = icmp eq i32 %and, 0
527 br i1 %cmp, label %then, label %else
533 %and1 = and i32 %conv, 7
534 %cmp1 = icmp eq i32 %and1, 0