Skip to content

Commit bf1d4a0

Browse files
authored
[LICM] Preserve Disjoint flag on OR when hoisting. (#140266)
Update hoistBOAssociation to preserve Disjoint flags on the newly created instructions if both ORs are disjoint. Fixes #139625. PR: #140266
1 parent 722385e commit bf1d4a0

File tree

2 files changed

+70
-0
lines changed

2 files changed

+70
-0
lines changed

llvm/lib/Transforms/Scalar/LICM.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2877,6 +2877,13 @@ static bool hoistBOAssociation(Instruction &I, Loop &L,
28772877
if (auto *I = dyn_cast<Instruction>(Inv))
28782878
I->setFastMathFlags(Intersect);
28792879
NewBO->setFastMathFlags(Intersect);
2880+
} else if (Opcode == Instruction::Or) {
2881+
bool Disjoint = cast<PossiblyDisjointInst>(BO)->isDisjoint() &&
2882+
cast<PossiblyDisjointInst>(BO0)->isDisjoint();
2883+
// If `Inv` was not constant-folded, a new Instruction has been created.
2884+
if (auto *I = dyn_cast<PossiblyDisjointInst>(Inv))
2885+
I->setIsDisjoint(Disjoint);
2886+
cast<PossiblyDisjointInst>(NewBO)->setIsDisjoint(Disjoint);
28802887
}
28812888

28822889
BO->replaceAllUsesWith(NewBO);

llvm/test/Transforms/LICM/hoist-binop.ll

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -723,6 +723,69 @@ loop:
723723
br label %loop
724724
}
725725

726+
; Trivially hoist or disjoint.
727+
define void @or_all_disjoint(i64 %c1, i64 %c2) {
728+
; CHECK-LABEL: @or_all_disjoint(
729+
; CHECK-NEXT: entry:
730+
; CHECK-NEXT: [[INVARIANT_OP:%.*]] = or disjoint i64 [[C1:%.*]], [[C2:%.*]]
731+
; CHECK-NEXT: br label [[LOOP:%.*]]
732+
; CHECK: loop:
733+
; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDEX_NEXT_REASS:%.*]], [[LOOP]] ]
734+
; CHECK-NEXT: [[INDEX_NEXT_REASS]] = or disjoint i64 [[INDEX]], [[INVARIANT_OP]]
735+
; CHECK-NEXT: br label [[LOOP]]
736+
;
737+
entry:
738+
br label %loop
739+
740+
loop:
741+
%index = phi i64 [ 0, %entry ], [ %index.next, %loop ]
742+
%step.add = or disjoint i64 %index, %c1
743+
%index.next = or disjoint i64 %c2, %step.add
744+
br label %loop
745+
}
746+
747+
; Trivially hoist or, disjoint on first or only .
748+
define void @or_disjoint_on_first_or_only(i64 %c1, i64 %c2) {
749+
; CHECK-LABEL: @or_disjoint_on_first_or_only(
750+
; CHECK-NEXT: entry:
751+
; CHECK-NEXT: [[INVARIANT_OP:%.*]] = or i64 [[C1:%.*]], [[C2:%.*]]
752+
; CHECK-NEXT: br label [[LOOP:%.*]]
753+
; CHECK: loop:
754+
; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDEX_NEXT_REASS:%.*]], [[LOOP]] ]
755+
; CHECK-NEXT: [[INDEX_NEXT_REASS]] = or i64 [[INDEX]], [[INVARIANT_OP]]
756+
; CHECK-NEXT: br label [[LOOP]]
757+
;
758+
entry:
759+
br label %loop
760+
761+
loop:
762+
%index = phi i64 [ 0, %entry ], [ %index.next, %loop ]
763+
%step.add = or i64 %index, %c1
764+
%index.next = or disjoint i64 %c2, %step.add
765+
br label %loop
766+
}
767+
768+
; Trivially hoist or, disjoint on second or only .
769+
define void @or_disjoint_on_second_or_only(i64 %c1, i64 %c2) {
770+
; CHECK-LABEL: @or_disjoint_on_second_or_only(
771+
; CHECK-NEXT: entry:
772+
; CHECK-NEXT: [[INVARIANT_OP:%.*]] = or i64 [[C1:%.*]], [[C2:%.*]]
773+
; CHECK-NEXT: br label [[LOOP:%.*]]
774+
; CHECK: loop:
775+
; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDEX_NEXT_REASS:%.*]], [[LOOP]] ]
776+
; CHECK-NEXT: [[INDEX_NEXT_REASS]] = or i64 [[INDEX]], [[INVARIANT_OP]]
777+
; CHECK-NEXT: br label [[LOOP]]
778+
;
779+
entry:
780+
br label %loop
781+
782+
loop:
783+
%index = phi i64 [ 0, %entry ], [ %index.next, %loop ]
784+
%step.add = or disjoint i64 %index, %c1
785+
%index.next = or i64 %c2, %step.add
786+
br label %loop
787+
}
788+
726789
; Trivially hoist xor.
727790
define void @xor(i64 %c1, i64 %c2) {
728791
; CHECK-LABEL: @xor(

0 commit comments

Comments
 (0)