@@ -375,3 +375,120 @@ define i1 @sdiv_eq_smin_use(i32 %x, i32 %y) {
375
375
%r = icmp eq i32 %d , -2147483648
376
376
ret i1 %r
377
377
}
378
+
379
+ ; Fold (X / C) cmp X into X ~cmp 0 (~cmp is the inverse predicate of cmp), for some C != 1
380
+ ; Alternative form of this fold is when division is replaced with logic right shift
381
+
382
+ define i1 @sdiv_x_by_const_cmp_x (i32 %x ) {
383
+ ; CHECK-LABEL: @sdiv_x_by_const_cmp_x(
384
+ ; CHECK-NEXT: [[V:%.*]] = udiv i32 [[X:%.*]], 13
385
+ ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[V]], [[X]]
386
+ ; CHECK-NEXT: ret i1 [[TMP1]]
387
+ ;
388
+ %v = udiv i32 %x , 13
389
+ %r = icmp eq i32 %v , %x
390
+ ret i1 %r
391
+ }
392
+
393
+ define i1 @udiv_x_by_const_cmp_x (i32 %x ) {
394
+ ; CHECK-LABEL: @udiv_x_by_const_cmp_x(
395
+ ; CHECK-NEXT: [[TMP2:%.*]] = udiv i32 [[X:%.*]], 123
396
+ ; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i32 [[TMP2]], [[X]]
397
+ ; CHECK-NEXT: ret i1 [[TMP1]]
398
+ ;
399
+ %1 = udiv i32 %x , 123
400
+ %2 = icmp slt i32 %1 , %x
401
+ ret i1 %2
402
+ }
403
+
404
+ ; Same as above but with right shift instead of division (C != 0)
405
+
406
+ define i1 @lshr_x_by_const_cmp_x (i32 %x ) {
407
+ ; CHECK-LABEL: @lshr_x_by_const_cmp_x(
408
+ ; CHECK-NEXT: [[V:%.*]] = lshr i32 [[X:%.*]], 1
409
+ ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[V]], [[X]]
410
+ ; CHECK-NEXT: ret i1 [[TMP1]]
411
+ ;
412
+ %v = lshr i32 %x , 1
413
+ %r = icmp eq i32 %v , %x
414
+ ret i1 %r
415
+ }
416
+
417
+ define <4 x i1 > @lshr_by_const_cmp_sle_value (<4 x i32 > %x ) {
418
+ ; CHECK-LABEL: @lshr_by_const_cmp_sle_value(
419
+ ; CHECK-NEXT: [[V:%.*]] = lshr <4 x i32> [[X:%.*]], <i32 3, i32 3, i32 3, i32 3>
420
+ ; CHECK-NEXT: [[R:%.*]] = icmp sle <4 x i32> [[V]], [[X]]
421
+ ; CHECK-NEXT: ret <4 x i1> [[R]]
422
+ ;
423
+ %v = lshr <4 x i32 > %x , <i32 3 , i32 3 , i32 3 , i32 3 >
424
+ %r = icmp sle <4 x i32 > %v , %x
425
+ ret <4 x i1 > %r
426
+ }
427
+
428
+ define i1 @lshr_by_const_cmp_uge_value (i32 %x ) {
429
+ ; CHECK-LABEL: @lshr_by_const_cmp_uge_value(
430
+ ; CHECK-NEXT: [[V:%.*]] = lshr i32 [[X:%.*]], 3
431
+ ; CHECK-NEXT: [[R:%.*]] = icmp sle i32 [[V]], [[X]]
432
+ ; CHECK-NEXT: ret i1 [[R]]
433
+ ;
434
+ %v = lshr i32 %x , 3
435
+ %r = icmp sle i32 %v , %x
436
+ ret i1 %r
437
+ }
438
+
439
+ ; Negative test - constant is 1
440
+
441
+ define i1 @udiv_by_const_cmp_eq_value_neg (i32 %x ) {
442
+ ; CHECK-LABEL: @udiv_by_const_cmp_eq_value_neg(
443
+ ; CHECK-NEXT: ret i1 true
444
+ ;
445
+ %v = udiv i32 %x , 1
446
+ %r = icmp eq i32 %v , %x
447
+ ret i1 %r
448
+ }
449
+
450
+ define i1 @sdiv_by_const_cmp_eq_value_neg (i32 %x ) {
451
+ ; CHECK-LABEL: @sdiv_by_const_cmp_eq_value_neg(
452
+ ; CHECK-NEXT: ret i1 true
453
+ ;
454
+ %v = sdiv i32 %x , 1
455
+ %r = icmp eq i32 %v , %x
456
+ ret i1 %r
457
+ }
458
+
459
+ ; Negative test - constant is 0
460
+
461
+ define i1 @lshr_by_const_cmp_slt_value_neg (i32 %x ) {
462
+ ; CHECK-LABEL: @lshr_by_const_cmp_slt_value_neg(
463
+ ; CHECK-NEXT: ret i1 false
464
+ ;
465
+ %v = lshr i32 %x , 0
466
+ %r = icmp slt i32 %v , %x
467
+ ret i1 %r
468
+ }
469
+
470
+ ; Negative test - unsigned predicate with sdiv
471
+
472
+ define i1 @sdiv_by_const_cmp_ult_value_neg (i32 %x ) {
473
+ ; CHECK-LABEL: @sdiv_by_const_cmp_ult_value_neg(
474
+ ; CHECK-NEXT: [[V:%.*]] = sdiv i32 [[X:%.*]], 3
475
+ ; CHECK-NEXT: [[R:%.*]] = icmp ult i32 [[V]], [[X]]
476
+ ; CHECK-NEXT: ret i1 [[R]]
477
+ ;
478
+ %v = sdiv i32 %x , 3
479
+ %r = icmp ult i32 %v , %x
480
+ ret i1 %r
481
+ }
482
+
483
+ ; Negative case - one of the components of a vector is 1
484
+
485
+ define <4 x i1 > @sdiv_by_const_cmp_sgt_value_neg (<4 x i32 > %x ) {
486
+ ; CHECK-LABEL: @sdiv_by_const_cmp_sgt_value_neg(
487
+ ; CHECK-NEXT: [[V:%.*]] = sdiv <4 x i32> [[X:%.*]], <i32 1, i32 2, i32 3, i32 4>
488
+ ; CHECK-NEXT: [[R:%.*]] = icmp sgt <4 x i32> [[V]], [[X]]
489
+ ; CHECK-NEXT: ret <4 x i1> [[R]]
490
+ ;
491
+ %v = sdiv <4 x i32 > %x , <i32 1 , i32 2 , i32 3 , i32 4 >
492
+ %r = icmp sgt <4 x i32 > %v , %x
493
+ ret <4 x i1 > %r
494
+ }
0 commit comments