@@ -323,12 +323,12 @@ define i5 @sdiv_mul_shl_nsw_commute1(i5 %x, i5 %y, i5 %z) {
323
323
324
324
define i5 @sdiv_mul_shl_nsw_commute2 (i5 %x , i5 %y , i5 %z ) {
325
325
; CHECK-LABEL: @sdiv_mul_shl_nsw_commute2(
326
- ; CHECK-NEXT: [[M1:%.*]] = mul nsw i5 [[X :%.*]], [[Y :%.*]]
326
+ ; CHECK-NEXT: [[M1:%.*]] = mul nsw i5 [[Y :%.*]], [[X :%.*]]
327
327
; CHECK-NEXT: [[M2:%.*]] = shl nsw i5 [[Z:%.*]], [[X]]
328
328
; CHECK-NEXT: [[D:%.*]] = sdiv i5 [[M1]], [[M2]]
329
329
; CHECK-NEXT: ret i5 [[D]]
330
330
;
331
- %m1 = mul nsw i5 %x , %y
331
+ %m1 = mul nsw i5 %y , %x
332
332
%m2 = shl nsw i5 %z , %x
333
333
%d = sdiv i5 %m1 , %m2
334
334
ret i5 %d
@@ -420,11 +420,11 @@ define i5 @sdiv_mul_shl_missing_nsw2(i5 %x, i5 %y, i5 %z) {
420
420
ret i5 %d
421
421
}
422
422
423
+ ; (X * Y) u/ (X << Z) --> Y u>> Z
424
+
423
425
define i5 @udiv_mul_shl_nuw (i5 %x , i5 %y , i5 %z ) {
424
426
; CHECK-LABEL: @udiv_mul_shl_nuw(
425
- ; CHECK-NEXT: [[M1:%.*]] = mul nuw i5 [[X:%.*]], [[Y:%.*]]
426
- ; CHECK-NEXT: [[M2:%.*]] = shl nuw i5 [[X]], [[Z:%.*]]
427
- ; CHECK-NEXT: [[D:%.*]] = udiv i5 [[M1]], [[M2]]
427
+ ; CHECK-NEXT: [[D:%.*]] = lshr i5 [[Y:%.*]], [[Z:%.*]]
428
428
; CHECK-NEXT: ret i5 [[D]]
429
429
;
430
430
%m1 = mul nuw i5 %x , %y
@@ -433,11 +433,11 @@ define i5 @udiv_mul_shl_nuw(i5 %x, i5 %y, i5 %z) {
433
433
ret i5 %d
434
434
}
435
435
436
+ ; (Y * X) u/ (X << Z) --> Y u>> Z
437
+
436
438
define i5 @udiv_mul_shl_nuw_commute1 (i5 %x , i5 %y , i5 %z ) {
437
439
; CHECK-LABEL: @udiv_mul_shl_nuw_commute1(
438
- ; CHECK-NEXT: [[M1:%.*]] = mul nuw i5 [[Y:%.*]], [[X:%.*]]
439
- ; CHECK-NEXT: [[M2:%.*]] = shl nuw i5 [[X]], [[Z:%.*]]
440
- ; CHECK-NEXT: [[D:%.*]] = udiv i5 [[M1]], [[M2]]
440
+ ; CHECK-NEXT: [[D:%.*]] = lshr i5 [[Y:%.*]], [[Z:%.*]]
441
441
; CHECK-NEXT: ret i5 [[D]]
442
442
;
443
443
%m1 = mul nuw i5 %y , %x
@@ -446,6 +446,8 @@ define i5 @udiv_mul_shl_nuw_commute1(i5 %x, i5 %y, i5 %z) {
446
446
ret i5 %d
447
447
}
448
448
449
+ ; negative test - shl is not commutative
450
+
449
451
define i5 @udiv_mul_shl_nuw_commute2 (i5 %x , i5 %y , i5 %z ) {
450
452
; CHECK-LABEL: @udiv_mul_shl_nuw_commute2(
451
453
; CHECK-NEXT: [[M1:%.*]] = mul nuw i5 [[X:%.*]], [[Y:%.*]]
@@ -459,12 +461,13 @@ define i5 @udiv_mul_shl_nuw_commute2(i5 %x, i5 %y, i5 %z) {
459
461
ret i5 %d
460
462
}
461
463
464
+ ; extra uses are ok
465
+
462
466
define i8 @udiv_mul_shl_nsw_use1 (i8 %x , i8 %y , i8 %z ) {
463
467
; CHECK-LABEL: @udiv_mul_shl_nsw_use1(
464
468
; CHECK-NEXT: [[M1:%.*]] = mul nuw i8 [[X:%.*]], [[Y:%.*]]
465
469
; CHECK-NEXT: call void @use(i8 [[M1]])
466
- ; CHECK-NEXT: [[M2:%.*]] = shl nuw i8 [[X]], [[Z:%.*]]
467
- ; CHECK-NEXT: [[D:%.*]] = udiv i8 [[M1]], [[M2]]
470
+ ; CHECK-NEXT: [[D:%.*]] = lshr i8 [[Y]], [[Z:%.*]]
468
471
; CHECK-NEXT: ret i8 [[D]]
469
472
;
470
473
%m1 = mul nuw i8 %x , %y
@@ -474,12 +477,13 @@ define i8 @udiv_mul_shl_nsw_use1(i8 %x, i8 %y, i8 %z) {
474
477
ret i8 %d
475
478
}
476
479
480
+ ; extra uses are ok
481
+
477
482
define i8 @udiv_mul_shl_nsw_use2 (i8 %x , i8 %y , i8 %z ) {
478
483
; CHECK-LABEL: @udiv_mul_shl_nsw_use2(
479
- ; CHECK-NEXT: [[M1:%.*]] = mul nuw i8 [[X:%.*]], [[Y:%.*]]
480
- ; CHECK-NEXT: [[M2:%.*]] = shl nuw i8 [[X]], [[Z:%.*]]
484
+ ; CHECK-NEXT: [[M2:%.*]] = shl nuw i8 [[X:%.*]], [[Z:%.*]]
481
485
; CHECK-NEXT: call void @use(i8 [[M2]])
482
- ; CHECK-NEXT: [[D:%.*]] = udiv i8 [[M1 ]], [[M2 ]]
486
+ ; CHECK-NEXT: [[D:%.*]] = lshr i8 [[Y:%.* ]], [[Z ]]
483
487
; CHECK-NEXT: ret i8 [[D]]
484
488
;
485
489
%m1 = mul nuw i8 %x , %y
@@ -489,13 +493,15 @@ define i8 @udiv_mul_shl_nsw_use2(i8 %x, i8 %y, i8 %z) {
489
493
ret i8 %d
490
494
}
491
495
496
+ ; extra uses are ok
497
+
492
498
define i8 @udiv_mul_shl_nsw_use3 (i8 %x , i8 %y , i8 %z ) {
493
499
; CHECK-LABEL: @udiv_mul_shl_nsw_use3(
494
500
; CHECK-NEXT: [[M1:%.*]] = mul nuw i8 [[X:%.*]], [[Y:%.*]]
495
501
; CHECK-NEXT: call void @use(i8 [[M1]])
496
502
; CHECK-NEXT: [[M2:%.*]] = shl nuw i8 [[X]], [[Z:%.*]]
497
503
; CHECK-NEXT: call void @use(i8 [[M2]])
498
- ; CHECK-NEXT: [[D:%.*]] = udiv i8 [[M1 ]], [[M2 ]]
504
+ ; CHECK-NEXT: [[D:%.*]] = lshr i8 [[Y ]], [[Z ]]
499
505
; CHECK-NEXT: ret i8 [[D]]
500
506
;
501
507
%m1 = mul nuw i8 %x , %y
@@ -506,19 +512,23 @@ define i8 @udiv_mul_shl_nsw_use3(i8 %x, i8 %y, i8 %z) {
506
512
ret i8 %d
507
513
}
508
514
515
+ ; TODO: This can fold to (1<<z) / y
516
+
509
517
define i5 @udiv_shl_mul_nuw (i5 %x , i5 %y , i5 %z ) {
510
518
; CHECK-LABEL: @udiv_shl_mul_nuw(
511
- ; CHECK-NEXT: [[M1:%.*]] = shl nuw i5 [[Z :%.*]], [[X :%.*]]
519
+ ; CHECK-NEXT: [[M1:%.*]] = shl nuw i5 [[X :%.*]], [[Z :%.*]]
512
520
; CHECK-NEXT: [[M2:%.*]] = mul nuw i5 [[X]], [[Y:%.*]]
513
521
; CHECK-NEXT: [[D:%.*]] = udiv i5 [[M1]], [[M2]]
514
522
; CHECK-NEXT: ret i5 [[D]]
515
523
;
516
- %m1 = shl nuw i5 %z , %x
524
+ %m1 = shl nuw i5 %x , %z
517
525
%m2 = mul nuw i5 %x , %y
518
526
%d = udiv i5 %m1 , %m2
519
527
ret i5 %d
520
528
}
521
529
530
+ ; negative test - wrong no-wrap
531
+
522
532
define i5 @udiv_mul_shl_missing_nsw1 (i5 %x , i5 %y , i5 %z ) {
523
533
; CHECK-LABEL: @udiv_mul_shl_missing_nsw1(
524
534
; CHECK-NEXT: [[M1:%.*]] = mul nsw i5 [[X:%.*]], [[Y:%.*]]
@@ -532,6 +542,8 @@ define i5 @udiv_mul_shl_missing_nsw1(i5 %x, i5 %y, i5 %z) {
532
542
ret i5 %d
533
543
}
534
544
545
+ ; negative test - wrong no-wrap
546
+
535
547
define i5 @udiv_mul_shl_missing_nsw2 (i5 %x , i5 %y , i5 %z ) {
536
548
; CHECK-LABEL: @udiv_mul_shl_missing_nsw2(
537
549
; CHECK-NEXT: [[M1:%.*]] = mul nuw i5 [[X:%.*]], [[Y:%.*]]
0 commit comments