[llvm] [llvm][LICM] Add flag to control re-association (PR #149829)
Theodoros Theodoridis via llvm-commits
llvm-commits at lists.llvm.org
Wed Jul 23 07:30:14 PDT 2025
https://github.com/thetheodor updated https://github.com/llvm/llvm-project/pull/149829
>From 583f17ec2e20f8d01b23163365a7b6dae58ffc39 Mon Sep 17 00:00:00 2001
From: Theodoros Theodoridis <ttheodoridis at nvidia.com>
Date: Wed, 4 Jun 2025 14:34:40 +0000
Subject: [PATCH 1/2] [llvm][LICM] Flag to control re-association
Add a command line flag that controls the amount of binary op
re-association based on the number of uses.
---
llvm/lib/Transforms/Scalar/LICM.cpp | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/llvm/lib/Transforms/Scalar/LICM.cpp b/llvm/lib/Transforms/Scalar/LICM.cpp
index 68094c354cf46..35d2dc0a0e641 100644
--- a/llvm/lib/Transforms/Scalar/LICM.cpp
+++ b/llvm/lib/Transforms/Scalar/LICM.cpp
@@ -146,6 +146,11 @@ static cl::opt<unsigned> IntAssociationUpperLimit(
"Set upper limit for the number of transformations performed "
"during a single round of hoisting the reassociated expressions."));
+static cl::opt<unsigned> BOAssociationUserLimit(
+ "licm-hoist-bo-association-user-limit", cl::init(2), cl::Hidden,
+ cl::desc("Limit the number of users of the variant operand when "
+ "reassociating a binary operator for hoisting."));
+
// Experimental option to allow imprecision in LICM in pathological cases, in
// exchange for faster compile. This is to be removed if MemorySSA starts to
// address the same issue. LICM calls MemorySSAWalker's
@@ -2850,7 +2855,7 @@ static bool hoistBOAssociation(Instruction &I, Loop &L,
bool LVInRHS = L.isLoopInvariant(BO->getOperand(0));
auto *BO0 = dyn_cast<BinaryOperator>(BO->getOperand(LVInRHS));
if (!BO0 || BO0->getOpcode() != Opcode || !BO0->isAssociative() ||
- BO0->hasNUsesOrMore(3))
+ BO0->hasNUsesOrMore(BOAssociationUserLimit + 1))
return false;
Value *LV = BO0->getOperand(0);
>From 4147222d1a6096be627cc865cd38ad076436f0b2 Mon Sep 17 00:00:00 2001
From: Theodoros Theodoridis <ttheodoridis at nvidia.com>
Date: Wed, 23 Jul 2025 14:25:24 +0000
Subject: [PATCH 2/2] Add test for licm-hoist-bo-association-user-limit
---
.../Transforms/LICM/hoist-binop-user-limit.ll | 90 +++++++++++++++++++
1 file changed, 90 insertions(+)
create mode 100644 llvm/test/Transforms/LICM/hoist-binop-user-limit.ll
diff --git a/llvm/test/Transforms/LICM/hoist-binop-user-limit.ll b/llvm/test/Transforms/LICM/hoist-binop-user-limit.ll
new file mode 100644
index 0000000000000..dc413fd5fbfa1
--- /dev/null
+++ b/llvm/test/Transforms/LICM/hoist-binop-user-limit.ll
@@ -0,0 +1,90 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt -S -passes=licm -licm-hoist-bo-association-user-limit=0 < %s | FileCheck %s --check-prefix=LIMIT0
+; RUN: opt -S -passes=licm -licm-hoist-bo-association-user-limit=1 < %s | FileCheck %s --check-prefix=LIMIT1
+; RUN: opt -S -passes=licm -licm-hoist-bo-association-user-limit=2 < %s | FileCheck %s --check-prefix=LIMIT2
+
+; Hoisted if the limit is at least 1.
+define void @single_use(i64 %c1, i64 %c2) {
+; LIMIT0-LABEL: @single_use(
+; LIMIT0-NEXT: entry:
+; LIMIT0-NEXT: br label [[LOOP:%.*]]
+; LIMIT0: loop:
+; LIMIT0-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDEX_NEXT:%.*]], [[LOOP]] ]
+; LIMIT0-NEXT: [[STEP_ADD:%.*]] = add i64 [[INDEX]], [[C1:%.*]]
+; LIMIT0-NEXT: [[INDEX_NEXT]] = add i64 [[STEP_ADD]], [[C2:%.*]]
+; LIMIT0-NEXT: br label [[LOOP]]
+;
+; LIMIT1-LABEL: @single_use(
+; LIMIT1-NEXT: entry:
+; LIMIT1-NEXT: [[INVARIANT_OP:%.*]] = add i64 [[C1:%.*]], [[C2:%.*]]
+; LIMIT1-NEXT: br label [[LOOP:%.*]]
+; LIMIT1: loop:
+; LIMIT1-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDEX_NEXT_REASS:%.*]], [[LOOP]] ]
+; LIMIT1-NEXT: [[INDEX_NEXT_REASS]] = add i64 [[INDEX]], [[INVARIANT_OP]]
+; LIMIT1-NEXT: br label [[LOOP]]
+;
+; LIMIT2-LABEL: @single_use(
+; LIMIT2-NEXT: entry:
+; LIMIT2-NEXT: [[INVARIANT_OP:%.*]] = add i64 [[C1:%.*]], [[C2:%.*]]
+; LIMIT2-NEXT: br label [[LOOP:%.*]]
+; LIMIT2: loop:
+; LIMIT2-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDEX_NEXT_REASS:%.*]], [[LOOP]] ]
+; LIMIT2-NEXT: [[INDEX_NEXT_REASS]] = add i64 [[INDEX]], [[INVARIANT_OP]]
+; LIMIT2-NEXT: br label [[LOOP]]
+;
+entry:
+ br label %loop
+
+loop:
+ %index = phi i64 [ 0, %entry ], [ %index.next, %loop ]
+ %step.add = add i64 %index, %c1
+ %index.next = add i64 %step.add, %c2
+ br label %loop
+}
+
+; Hoisted if the limit is at least 2.
+define void @two_uses(i64 %c1, i64 %c2) {
+; LIMIT0-LABEL: @two_uses(
+; LIMIT0-NEXT: entry:
+; LIMIT0-NEXT: br label [[LOOP:%.*]]
+; LIMIT0: loop:
+; LIMIT0-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDEX_NEXT:%.*]], [[LOOP]] ]
+; LIMIT0-NEXT: [[STEP_ADD:%.*]] = add i64 [[INDEX]], [[C1:%.*]]
+; LIMIT0-NEXT: call void @use(i64 [[STEP_ADD]])
+; LIMIT0-NEXT: [[INDEX_NEXT]] = add i64 [[STEP_ADD]], [[C2:%.*]]
+; LIMIT0-NEXT: br label [[LOOP]]
+;
+; LIMIT1-LABEL: @two_uses(
+; LIMIT1-NEXT: entry:
+; LIMIT1-NEXT: br label [[LOOP:%.*]]
+; LIMIT1: loop:
+; LIMIT1-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDEX_NEXT_REASS:%.*]], [[LOOP]] ]
+; LIMIT1-NEXT: [[STEP_ADD:%.*]] = add i64 [[INDEX]], [[C1:%.*]]
+; LIMIT1-NEXT: call void @use(i64 [[STEP_ADD]])
+; LIMIT1-NEXT: [[INDEX_NEXT_REASS]] = add i64 [[STEP_ADD]], [[C2:%.*]]
+; LIMIT1-NEXT: br label [[LOOP]]
+;
+; LIMIT2-LABEL: @two_uses(
+; LIMIT2-NEXT: entry:
+; LIMIT2-NEXT: [[INVARIANT_OP:%.*]] = add i64 [[C1:%.*]], [[C2:%.*]]
+; LIMIT2-NEXT: br label [[LOOP:%.*]]
+; LIMIT2: loop:
+; LIMIT2-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDEX_NEXT_REASS:%.*]], [[LOOP]] ]
+; LIMIT2-NEXT: [[STEP_ADD:%.*]] = add i64 [[INDEX]], [[C1]]
+; LIMIT2-NEXT: call void @use(i64 [[STEP_ADD]])
+; LIMIT2-NEXT: [[INDEX_NEXT_REASS]] = add i64 [[INDEX]], [[INVARIANT_OP]]
+; LIMIT2-NEXT: br label [[LOOP]]
+;
+entry:
+ br label %loop
+
+loop:
+ %index = phi i64 [ 0, %entry ], [ %index.next, %loop ]
+ %step.add = add i64 %index, %c1
+ call void @use(i64 %step.add)
+ %index.next = add i64 %step.add, %c2
+ br label %loop
+}
+
+
+declare void @use()
More information about the llvm-commits
mailing list