-
Notifications
You must be signed in to change notification settings - Fork 12.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
LICM: hoist BO assoc for and, or, xor #111146
Conversation
Trivially lift the Opcode limitation on hoistBOAssociation to also hoist and, or, and xor. Alive2 proofs: https://alive2.llvm.org/ce/z/rVNP2X
@llvm/pr-subscribers-backend-powerpc @llvm/pr-subscribers-llvm-transforms Author: Ramkumar Ramachandra (artagnon) ChangesTrivially lift the Opcode limitation on hoistBOAssociation to also hoist and, or, and xor. Alive2 proofs: https://alive2.llvm.org/ce/z/rVNP2X Full diff: https://github.com/llvm/llvm-project/pull/111146.diff 2 Files Affected:
diff --git a/llvm/lib/Transforms/Scalar/LICM.cpp b/llvm/lib/Transforms/Scalar/LICM.cpp
index d73b550741fb39..50f7637b07f6f6 100644
--- a/llvm/lib/Transforms/Scalar/LICM.cpp
+++ b/llvm/lib/Transforms/Scalar/LICM.cpp
@@ -2820,18 +2820,7 @@ static bool hoistBOAssociation(Instruction &I, Loop &L,
if (!BO || !BO->isAssociative())
return false;
- // TODO: Only hoist ADDs, MULs, FADDs, and FMULs for now.
Instruction::BinaryOps Opcode = BO->getOpcode();
- switch (Opcode) {
- case Instruction::Add:
- case Instruction::Mul:
- case Instruction::FAdd:
- case Instruction::FMul:
- break;
- default:
- return false;
- }
-
bool LVInRHS = L.isLoopInvariant(BO->getOperand(0));
auto *BO0 = dyn_cast<BinaryOperator>(BO->getOperand(LVInRHS));
if (!BO0 || BO0->getOpcode() != Opcode || !BO0->isAssociative() ||
diff --git a/llvm/test/Transforms/LICM/hoist-binop.ll b/llvm/test/Transforms/LICM/hoist-binop.ll
index 74e2b7a2caf4a5..ea7d96c07d5ff2 100644
--- a/llvm/test/Transforms/LICM/hoist-binop.ll
+++ b/llvm/test/Transforms/LICM/hoist-binop.ll
@@ -681,6 +681,69 @@ loop:
br label %loop
}
+; Trivially hoist and.
+define void @and(i64 %c1, i64 %c2) {
+; CHECK-LABEL: @and(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[INVARIANT_OP:%.*]] = and 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]] = and i64 [[INDEX]], [[INVARIANT_OP]]
+; CHECK-NEXT: br label [[LOOP]]
+;
+entry:
+ br label %loop
+
+loop:
+ %index = phi i64 [ 0, %entry ], [ %index.next, %loop ]
+ %step.add = and i64 %index, %c1
+ %index.next = and i64 %step.add, %c2
+ br label %loop
+}
+
+; Trivially hoist or.
+define void @or(i64 %c1, i64 %c2) {
+; CHECK-LABEL: @or(
+; 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 i64 %c2, %step.add
+ br label %loop
+}
+
+; Trivially hoist xor.
+define void @xor(i64 %c1, i64 %c2) {
+; CHECK-LABEL: @xor(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[INVARIANT_OP:%.*]] = xor 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]] = xor i64 [[INDEX]], [[INVARIANT_OP]]
+; CHECK-NEXT: br label [[LOOP]]
+;
+entry:
+ br label %loop
+
+loop:
+ %index = phi i64 [ 0, %entry ], [ %index.next, %loop ]
+ %step.add = xor i64 %c1, %index
+ %index.next = xor i64 %step.add, %c2
+ br label %loop
+}
+
; Don't hoist if the intermediate op has more than two uses. This is an
; heuristic that can be adjusted if warranted. Currently we are being
; conservative to minimise potential impact in code size.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Trivially lift the Opcode limitation on hoistBOAssociation to also hoist and, or, and xor.
Alive2 proofs: https://alive2.llvm.org/ce/z/rVNP2X