[llvm] bf1d4a0 - [LICM] Preserve Disjoint flag on OR when hoisting. (#140266)
via llvm-commits
llvm-commits at lists.llvm.org
Sat May 17 06:48:43 PDT 2025
Author: Florian Hahn
Date: 2025-05-17T14:48:39+01:00
New Revision: bf1d4a0710a6e1d2c99e579bcf435b92ab5d0506
URL: https://github.com/llvm/llvm-project/commit/bf1d4a0710a6e1d2c99e579bcf435b92ab5d0506
DIFF: https://github.com/llvm/llvm-project/commit/bf1d4a0710a6e1d2c99e579bcf435b92ab5d0506.diff
LOG: [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 https://github.com/llvm/llvm-project/issues/139625.
PR: https://github.com/llvm/llvm-project/pull/140266
Added:
Modified:
llvm/lib/Transforms/Scalar/LICM.cpp
llvm/test/Transforms/LICM/hoist-binop.ll
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/Scalar/LICM.cpp b/llvm/lib/Transforms/Scalar/LICM.cpp
index 62ef40c686874..7d89a13fa3bab 100644
--- a/llvm/lib/Transforms/Scalar/LICM.cpp
+++ b/llvm/lib/Transforms/Scalar/LICM.cpp
@@ -2877,6 +2877,13 @@ static bool hoistBOAssociation(Instruction &I, Loop &L,
if (auto *I = dyn_cast<Instruction>(Inv))
I->setFastMathFlags(Intersect);
NewBO->setFastMathFlags(Intersect);
+ } else if (Opcode == Instruction::Or) {
+ bool Disjoint = cast<PossiblyDisjointInst>(BO)->isDisjoint() &&
+ cast<PossiblyDisjointInst>(BO0)->isDisjoint();
+ // If `Inv` was not constant-folded, a new Instruction has been created.
+ if (auto *I = dyn_cast<PossiblyDisjointInst>(Inv))
+ I->setIsDisjoint(Disjoint);
+ cast<PossiblyDisjointInst>(NewBO)->setIsDisjoint(Disjoint);
}
BO->replaceAllUsesWith(NewBO);
diff --git a/llvm/test/Transforms/LICM/hoist-binop.ll b/llvm/test/Transforms/LICM/hoist-binop.ll
index ea7d96c07d5ff..000b1fc1c5ce6 100644
--- a/llvm/test/Transforms/LICM/hoist-binop.ll
+++ b/llvm/test/Transforms/LICM/hoist-binop.ll
@@ -723,6 +723,69 @@ loop:
br label %loop
}
+; Trivially hoist or disjoint.
+define void @or_all_disjoint(i64 %c1, i64 %c2) {
+; CHECK-LABEL: @or_all_disjoint(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[INVARIANT_OP:%.*]] = or disjoint i64 [[C1:%.*]], [[C2:%.*]]
+; CHECK-NEXT: br label [[LOOP:%.*]]
+; CHECK: loop:
+; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDEX_NEXT_REASS:%.*]], [[LOOP]] ]
+; CHECK-NEXT: [[INDEX_NEXT_REASS]] = or disjoint i64 [[INDEX]], [[INVARIANT_OP]]
+; CHECK-NEXT: br label [[LOOP]]
+;
+entry:
+ br label %loop
+
+loop:
+ %index = phi i64 [ 0, %entry ], [ %index.next, %loop ]
+ %step.add = or disjoint i64 %index, %c1
+ %index.next = or disjoint i64 %c2, %step.add
+ br label %loop
+}
+
+; Trivially hoist or, disjoint on first or only .
+define void @or_disjoint_on_first_or_only(i64 %c1, i64 %c2) {
+; CHECK-LABEL: @or_disjoint_on_first_or_only(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[INVARIANT_OP:%.*]] = or i64 [[C1:%.*]], [[C2:%.*]]
+; CHECK-NEXT: br label [[LOOP:%.*]]
+; CHECK: loop:
+; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDEX_NEXT_REASS:%.*]], [[LOOP]] ]
+; CHECK-NEXT: [[INDEX_NEXT_REASS]] = or i64 [[INDEX]], [[INVARIANT_OP]]
+; CHECK-NEXT: br label [[LOOP]]
+;
+entry:
+ br label %loop
+
+loop:
+ %index = phi i64 [ 0, %entry ], [ %index.next, %loop ]
+ %step.add = or i64 %index, %c1
+ %index.next = or disjoint i64 %c2, %step.add
+ br label %loop
+}
+
+; Trivially hoist or, disjoint on second or only .
+define void @or_disjoint_on_second_or_only(i64 %c1, i64 %c2) {
+; CHECK-LABEL: @or_disjoint_on_second_or_only(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[INVARIANT_OP:%.*]] = or i64 [[C1:%.*]], [[C2:%.*]]
+; CHECK-NEXT: br label [[LOOP:%.*]]
+; CHECK: loop:
+; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDEX_NEXT_REASS:%.*]], [[LOOP]] ]
+; CHECK-NEXT: [[INDEX_NEXT_REASS]] = or i64 [[INDEX]], [[INVARIANT_OP]]
+; CHECK-NEXT: br label [[LOOP]]
+;
+entry:
+ br label %loop
+
+loop:
+ %index = phi i64 [ 0, %entry ], [ %index.next, %loop ]
+ %step.add = or disjoint i64 %index, %c1
+ %index.next = or i64 %c2, %step.add
+ br label %loop
+}
+
; Trivially hoist xor.
define void @xor(i64 %c1, i64 %c2) {
; CHECK-LABEL: @xor(
More information about the llvm-commits
mailing list