Skip to content

Commit ea4ce16

Browse files
authored
[ConstraintElim] Use disjoint flag for decomposition (#74478)
Use the or disjoint flag for decomposing or into add, which will handle cases that haveNoCommonBitsSet() may not be able to reinfer (e.g. because they require context-sensitive facts, which the call here does not use.)
1 parent b304873 commit ea4ce16

File tree

2 files changed

+106
-43
lines changed

2 files changed

+106
-43
lines changed

llvm/lib/Transforms/Scalar/ConstraintElimination.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -544,10 +544,8 @@ static Decomposition decompose(Value *V,
544544
}
545545

546546
// Decompose or as an add if there are no common bits between the operands.
547-
if (match(V, m_Or(m_Value(Op0), m_ConstantInt(CI))) &&
548-
haveNoCommonBitsSet(Op0, CI, DL)) {
547+
if (match(V, m_DisjointOr(m_Value(Op0), m_ConstantInt(CI))))
549548
return MergeResults(Op0, CI, IsSigned);
550-
}
551549

552550
if (match(V, m_NUWShl(m_Value(Op1), m_ConstantInt(CI))) && canUseSExt(CI)) {
553551
if (CI->getSExtValue() < 0 || CI->getSExtValue() >= 64)

llvm/test/Transforms/ConstraintElimination/or.ll

Lines changed: 105 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -414,20 +414,20 @@ define void @test_or_as_add_ult(i8 %init_val, i8 %high) {
414414
; CHECK: then:
415415
; CHECK-NEXT: [[F_0:%.*]] = icmp ult i8 [[START]], [[HIGH]]
416416
; CHECK-NEXT: call void @use(i1 [[F_0]])
417-
; CHECK-NEXT: [[I_1:%.*]] = or i8 [[START]], 1
417+
; CHECK-NEXT: [[I_1:%.*]] = or disjoint i8 [[START]], 1
418418
; CHECK-NEXT: [[F_1:%.*]] = icmp ult i8 [[I_1]], [[HIGH]]
419419
; CHECK-NEXT: call void @use(i1 [[F_1]])
420-
; CHECK-NEXT: [[I_2:%.*]] = or i8 [[START]], 2
420+
; CHECK-NEXT: [[I_2:%.*]] = or disjoint i8 [[START]], 2
421421
; CHECK-NEXT: [[F_2:%.*]] = icmp ult i8 [[I_2]], [[HIGH]]
422422
; CHECK-NEXT: call void @use(i1 [[F_2]])
423423
; CHECK-NEXT: ret void
424424
; CHECK: end:
425425
; CHECK-NEXT: call void @use(i1 true)
426-
; CHECK-NEXT: [[START_1:%.*]] = or i8 [[START]], 1
426+
; CHECK-NEXT: [[START_1:%.*]] = or disjoint i8 [[START]], 1
427427
; CHECK-NEXT: call void @use(i1 true)
428-
; CHECK-NEXT: [[START_2:%.*]] = or i8 [[START]], 2
428+
; CHECK-NEXT: [[START_2:%.*]] = or disjoint i8 [[START]], 2
429429
; CHECK-NEXT: call void @use(i1 true)
430-
; CHECK-NEXT: [[START_3:%.*]] = or i8 [[START]], 3
430+
; CHECK-NEXT: [[START_3:%.*]] = or disjoint i8 [[START]], 3
431431
; CHECK-NEXT: call void @use(i1 true)
432432
; CHECK-NEXT: [[START_4:%.*]] = or i8 [[START]], 4
433433
; CHECK-NEXT: [[C_4:%.*]] = icmp ult i8 [[START_4]], [[HIGH]]
@@ -443,24 +443,24 @@ entry:
443443
then: ; preds = %entry
444444
%f.0 = icmp ult i8 %start, %high
445445
call void @use(i1 %f.0)
446-
%i.1 = or i8 %start, 1
446+
%i.1 = or disjoint i8 %start, 1
447447
%f.1 = icmp ult i8 %i.1, %high
448448
call void @use(i1 %f.1)
449-
%i.2 = or i8 %start, 2
449+
%i.2 = or disjoint i8 %start, 2
450450
%f.2 = icmp ult i8 %i.2, %high
451451
call void @use(i1 %f.2)
452452
ret void
453453

454454
end: ; preds = %entry
455455
%t.0 = icmp ult i8 %start, %high
456456
call void @use(i1 %t.0)
457-
%start.1 = or i8 %start, 1
457+
%start.1 = or disjoint i8 %start, 1
458458
%t.1 = icmp ult i8 %start.1, %high
459459
call void @use(i1 %t.1)
460-
%start.2 = or i8 %start, 2
460+
%start.2 = or disjoint i8 %start, 2
461461
%t.2 = icmp ult i8 %start.2, %high
462462
call void @use(i1 %t.2)
463-
%start.3 = or i8 %start, 3
463+
%start.3 = or disjoint i8 %start, 3
464464
%t.3 = icmp ult i8 %start.3, %high
465465
call void @use(i1 %t.3)
466466
%start.4 = or i8 %start, 4
@@ -479,20 +479,20 @@ define void @test_or_as_add_ule(i8 %init_val, i8 %high) {
479479
; CHECK: then:
480480
; CHECK-NEXT: [[F_0:%.*]] = icmp ule i8 [[START]], [[HIGH]]
481481
; CHECK-NEXT: call void @use(i1 [[F_0]])
482-
; CHECK-NEXT: [[I_1:%.*]] = or i8 [[START]], 1
482+
; CHECK-NEXT: [[I_1:%.*]] = or disjoint i8 [[START]], 1
483483
; CHECK-NEXT: [[F_1:%.*]] = icmp ule i8 [[I_1]], [[HIGH]]
484484
; CHECK-NEXT: call void @use(i1 [[F_1]])
485-
; CHECK-NEXT: [[I_2:%.*]] = or i8 [[START]], 2
485+
; CHECK-NEXT: [[I_2:%.*]] = or disjoint i8 [[START]], 2
486486
; CHECK-NEXT: [[F_2:%.*]] = icmp ule i8 [[I_2]], [[HIGH]]
487487
; CHECK-NEXT: call void @use(i1 [[F_2]])
488488
; CHECK-NEXT: ret void
489489
; CHECK: end:
490490
; CHECK-NEXT: call void @use(i1 true)
491-
; CHECK-NEXT: [[START_1:%.*]] = or i8 [[START]], 1
491+
; CHECK-NEXT: [[START_1:%.*]] = or disjoint i8 [[START]], 1
492492
; CHECK-NEXT: call void @use(i1 true)
493-
; CHECK-NEXT: [[START_2:%.*]] = or i8 [[START]], 2
493+
; CHECK-NEXT: [[START_2:%.*]] = or disjoint i8 [[START]], 2
494494
; CHECK-NEXT: call void @use(i1 true)
495-
; CHECK-NEXT: [[START_3:%.*]] = or i8 [[START]], 3
495+
; CHECK-NEXT: [[START_3:%.*]] = or disjoint i8 [[START]], 3
496496
; CHECK-NEXT: call void @use(i1 true)
497497
; CHECK-NEXT: [[START_4:%.*]] = or i8 [[START]], 4
498498
; CHECK-NEXT: [[T_4:%.*]] = icmp ule i8 [[START_4]], [[HIGH]]
@@ -511,24 +511,24 @@ entry:
511511
then: ; preds = %entry
512512
%f.0 = icmp ule i8 %start, %high
513513
call void @use(i1 %f.0)
514-
%i.1 = or i8 %start, 1
514+
%i.1 = or disjoint i8 %start, 1
515515
%f.1 = icmp ule i8 %i.1, %high
516516
call void @use(i1 %f.1)
517-
%i.2 = or i8 %start, 2
517+
%i.2 = or disjoint i8 %start, 2
518518
%f.2 = icmp ule i8 %i.2, %high
519519
call void @use(i1 %f.2)
520520
ret void
521521

522522
end: ; preds = %entry
523523
%t.0 = icmp ule i8 %start, %high
524524
call void @use(i1 %t.0)
525-
%start.1 = or i8 %start, 1
525+
%start.1 = or disjoint i8 %start, 1
526526
%t.1 = icmp ule i8 %start.1, %high
527527
call void @use(i1 %t.1)
528-
%start.2 = or i8 %start, 2
528+
%start.2 = or disjoint i8 %start, 2
529529
%t.2 = icmp ule i8 %start.2, %high
530530
call void @use(i1 %t.2)
531-
%start.3 = or i8 %start, 3
531+
%start.3 = or disjoint i8 %start, 3
532532
%t.3 = icmp ule i8 %start.3, %high
533533
call void @use(i1 %t.3)
534534
%start.4 = or i8 %start, 4
@@ -551,20 +551,20 @@ define void @test_or_as_add_ugt(i8 %init_val, i8 %high) {
551551
; CHECK: then:
552552
; CHECK-NEXT: [[T_0:%.*]] = icmp ugt i8 [[START]], [[HIGH]]
553553
; CHECK-NEXT: call void @use(i1 [[T_0]])
554-
; CHECK-NEXT: [[I_1:%.*]] = or i8 [[START]], 1
554+
; CHECK-NEXT: [[I_1:%.*]] = or disjoint i8 [[START]], 1
555555
; CHECK-NEXT: [[T_1:%.*]] = icmp ugt i8 [[I_1]], [[HIGH]]
556556
; CHECK-NEXT: call void @use(i1 [[T_1]])
557-
; CHECK-NEXT: [[I_2:%.*]] = or i8 [[START]], 2
557+
; CHECK-NEXT: [[I_2:%.*]] = or disjoint i8 [[START]], 2
558558
; CHECK-NEXT: [[T_2:%.*]] = icmp ugt i8 [[I_2]], [[HIGH]]
559559
; CHECK-NEXT: call void @use(i1 [[T_2]])
560560
; CHECK-NEXT: ret void
561561
; CHECK: end:
562562
; CHECK-NEXT: call void @use(i1 false)
563-
; CHECK-NEXT: [[START_1:%.*]] = or i8 [[START]], 1
563+
; CHECK-NEXT: [[START_1:%.*]] = or disjoint i8 [[START]], 1
564564
; CHECK-NEXT: call void @use(i1 false)
565-
; CHECK-NEXT: [[START_2:%.*]] = or i8 [[START]], 2
565+
; CHECK-NEXT: [[START_2:%.*]] = or disjoint i8 [[START]], 2
566566
; CHECK-NEXT: call void @use(i1 false)
567-
; CHECK-NEXT: [[START_3:%.*]] = or i8 [[START]], 3
567+
; CHECK-NEXT: [[START_3:%.*]] = or disjoint i8 [[START]], 3
568568
; CHECK-NEXT: call void @use(i1 false)
569569
; CHECK-NEXT: [[START_4:%.*]] = or i8 [[START]], 4
570570
; CHECK-NEXT: [[F_4:%.*]] = icmp ugt i8 [[START_4]], [[HIGH]]
@@ -583,24 +583,24 @@ entry:
583583
then: ; preds = %entry
584584
%t.0 = icmp ugt i8 %start, %high
585585
call void @use(i1 %t.0)
586-
%i.1 = or i8 %start, 1
586+
%i.1 = or disjoint i8 %start, 1
587587
%t.1 = icmp ugt i8 %i.1, %high
588588
call void @use(i1 %t.1)
589-
%i.2 = or i8 %start, 2
589+
%i.2 = or disjoint i8 %start, 2
590590
%t.2 = icmp ugt i8 %i.2, %high
591591
call void @use(i1 %t.2)
592592
ret void
593593

594594
end: ; preds = %entry
595595
%f.0 = icmp ugt i8 %start, %high
596596
call void @use(i1 %f.0)
597-
%start.1 = or i8 %start, 1
597+
%start.1 = or disjoint i8 %start, 1
598598
%f.1 = icmp ugt i8 %start.1, %high
599599
call void @use(i1 %f.1)
600-
%start.2 = or i8 %start, 2
600+
%start.2 = or disjoint i8 %start, 2
601601
%f.2 = icmp ugt i8 %start.2, %high
602602
call void @use(i1 %f.2)
603-
%start.3 = or i8 %start, 3
603+
%start.3 = or disjoint i8 %start, 3
604604
%f.3 = icmp ugt i8 %start.3, %high
605605
call void @use(i1 %f.3)
606606
%start.4 = or i8 %start, 4
@@ -622,20 +622,20 @@ define void @test_or_as_add_uge(i8 %init_val, i8 %high) {
622622
; CHECK: then:
623623
; CHECK-NEXT: [[T_0:%.*]] = icmp ugt i8 [[START]], [[HIGH]]
624624
; CHECK-NEXT: call void @use(i1 [[T_0]])
625-
; CHECK-NEXT: [[I_1:%.*]] = or i8 [[START]], 1
625+
; CHECK-NEXT: [[I_1:%.*]] = or disjoint i8 [[START]], 1
626626
; CHECK-NEXT: [[T_1:%.*]] = icmp uge i8 [[I_1]], [[HIGH]]
627627
; CHECK-NEXT: call void @use(i1 [[T_1]])
628-
; CHECK-NEXT: [[I_2:%.*]] = or i8 [[START]], 2
628+
; CHECK-NEXT: [[I_2:%.*]] = or disjoint i8 [[START]], 2
629629
; CHECK-NEXT: [[T_2:%.*]] = icmp uge i8 [[I_2]], [[HIGH]]
630630
; CHECK-NEXT: call void @use(i1 [[T_2]])
631631
; CHECK-NEXT: ret void
632632
; CHECK: end:
633633
; CHECK-NEXT: call void @use(i1 false)
634-
; CHECK-NEXT: [[START_1:%.*]] = or i8 [[START]], 1
634+
; CHECK-NEXT: [[START_1:%.*]] = or disjoint i8 [[START]], 1
635635
; CHECK-NEXT: call void @use(i1 false)
636-
; CHECK-NEXT: [[START_2:%.*]] = or i8 [[START]], 2
636+
; CHECK-NEXT: [[START_2:%.*]] = or disjoint i8 [[START]], 2
637637
; CHECK-NEXT: call void @use(i1 false)
638-
; CHECK-NEXT: [[START_3:%.*]] = or i8 [[START]], 3
638+
; CHECK-NEXT: [[START_3:%.*]] = or disjoint i8 [[START]], 3
639639
; CHECK-NEXT: call void @use(i1 false)
640640
; CHECK-NEXT: [[START_4:%.*]] = or i8 [[START]], 4
641641
; CHECK-NEXT: [[C_4:%.*]] = icmp uge i8 [[START_4]], [[HIGH]]
@@ -654,24 +654,24 @@ entry:
654654
then: ; preds = %entry
655655
%t.0 = icmp ugt i8 %start, %high
656656
call void @use(i1 %t.0)
657-
%i.1 = or i8 %start, 1
657+
%i.1 = or disjoint i8 %start, 1
658658
%t.1 = icmp uge i8 %i.1, %high
659659
call void @use(i1 %t.1)
660-
%i.2 = or i8 %start, 2
660+
%i.2 = or disjoint i8 %start, 2
661661
%t.2 = icmp uge i8 %i.2, %high
662662
call void @use(i1 %t.2)
663663
ret void
664664

665665
end: ; preds = %entry
666666
%f.0 = icmp ugt i8 %start, %high
667667
call void @use(i1 %f.0)
668-
%start.1 = or i8 %start, 1
668+
%start.1 = or disjoint i8 %start, 1
669669
%f.1 = icmp uge i8 %start.1, %high
670670
call void @use(i1 %f.1)
671-
%start.2 = or i8 %start, 2
671+
%start.2 = or disjoint i8 %start, 2
672672
%f.2 = icmp uge i8 %start.2, %high
673673
call void @use(i1 %f.2)
674-
%start.3 = or i8 %start, 3
674+
%start.3 = or disjoint i8 %start, 3
675675
%f.3 = icmp uge i8 %start.3, %high
676676
call void @use(i1 %f.3)
677677
%start.4 = or i8 %start, 4
@@ -748,3 +748,68 @@ end: ; preds = %entry
748748

749749
ret void
750750
}
751+
752+
; Nothing in the IR implies the disjoint flag, but we can still use it
753+
; to decompose into an add.
754+
define void @test_decompose_explicit_disjoint(i8 %start, i8 %high) {
755+
; CHECK-LABEL: @test_decompose_explicit_disjoint(
756+
; CHECK-NEXT: entry:
757+
; CHECK-NEXT: [[START_PLUS_3:%.*]] = add nuw i8 [[START:%.*]], 3
758+
; CHECK-NEXT: [[C_1:%.*]] = icmp uge i8 [[START_PLUS_3]], [[HIGH:%.*]]
759+
; CHECK-NEXT: br i1 [[C_1]], label [[THEN:%.*]], label [[END:%.*]]
760+
; CHECK: then:
761+
; CHECK-NEXT: [[I_1:%.*]] = or disjoint i8 [[START]], 1
762+
; CHECK-NEXT: [[T_1:%.*]] = icmp uge i8 [[I_1]], [[HIGH]]
763+
; CHECK-NEXT: call void @use(i1 [[T_1]])
764+
; CHECK-NEXT: [[I_2:%.*]] = or disjoint i8 [[START]], 2
765+
; CHECK-NEXT: [[T_2:%.*]] = icmp uge i8 [[I_2]], [[HIGH]]
766+
; CHECK-NEXT: call void @use(i1 [[T_2]])
767+
; CHECK-NEXT: ret void
768+
; CHECK: end:
769+
; CHECK-NEXT: [[START_1:%.*]] = or disjoint i8 [[START]], 1
770+
; CHECK-NEXT: call void @use(i1 false)
771+
; CHECK-NEXT: [[START_2:%.*]] = or disjoint i8 [[START]], 2
772+
; CHECK-NEXT: call void @use(i1 false)
773+
; CHECK-NEXT: [[START_3:%.*]] = or disjoint i8 [[START]], 3
774+
; CHECK-NEXT: call void @use(i1 false)
775+
; CHECK-NEXT: [[START_4:%.*]] = or disjoint i8 [[START]], 4
776+
; CHECK-NEXT: [[C_4:%.*]] = icmp uge i8 [[START_4]], [[HIGH]]
777+
; CHECK-NEXT: call void @use(i1 [[C_4]])
778+
; CHECK-NEXT: [[START_5:%.*]] = or disjoint i8 [[START]], 5
779+
; CHECK-NEXT: [[C_5:%.*]] = icmp uge i8 [[START_5]], [[HIGH]]
780+
; CHECK-NEXT: call void @use(i1 [[C_5]])
781+
; CHECK-NEXT: ret void
782+
;
783+
entry:
784+
%start.plus.3 = add nuw i8 %start, 3
785+
%c.1 = icmp uge i8 %start.plus.3, %high
786+
br i1 %c.1, label %then, label %end
787+
788+
then: ; preds = %entry
789+
%i.1 = or disjoint i8 %start, 1
790+
%t.1 = icmp uge i8 %i.1, %high
791+
call void @use(i1 %t.1)
792+
%i.2 = or disjoint i8 %start, 2
793+
%t.2 = icmp uge i8 %i.2, %high
794+
call void @use(i1 %t.2)
795+
ret void
796+
797+
end: ; preds = %entry
798+
%start.1 = or disjoint i8 %start, 1
799+
%f.1 = icmp uge i8 %start.1, %high
800+
call void @use(i1 %f.1)
801+
%start.2 = or disjoint i8 %start, 2
802+
%f.2 = icmp uge i8 %start.2, %high
803+
call void @use(i1 %f.2)
804+
%start.3 = or disjoint i8 %start, 3
805+
%f.3 = icmp uge i8 %start.3, %high
806+
call void @use(i1 %f.3)
807+
%start.4 = or disjoint i8 %start, 4
808+
%c.4 = icmp uge i8 %start.4, %high
809+
call void @use(i1 %c.4)
810+
%start.5 = or disjoint i8 %start, 5
811+
%c.5 = icmp uge i8 %start.5, %high
812+
call void @use(i1 %c.5)
813+
814+
ret void
815+
}

0 commit comments

Comments
 (0)