[llvm-branch-commits] [llvm] [LoopInterchange] Take base pointer into account in profitability check (PR #193477)
Ryotaro Kasuga via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Mon May 18 05:31:14 PDT 2026
https://github.com/kasuga-fj updated https://github.com/llvm/llvm-project/pull/193477
>From 5a029452fce20ed3be0efe2c5a0aa5cb158c47d3 Mon Sep 17 00:00:00 2001
From: Ryotaro Kasuga <kasuga.ryotaro at fujitsu.com>
Date: Wed, 22 Apr 2026 10:32:00 +0000
Subject: [PATCH] [LoopInterchange] Take base pointer into account in
profitability check
---
.../lib/Transforms/Scalar/LoopInterchange.cpp | 25 +++++++++++++------
.../profitability-instorder.ll | 24 ++++++------------
2 files changed, 25 insertions(+), 24 deletions(-)
diff --git a/llvm/lib/Transforms/Scalar/LoopInterchange.cpp b/llvm/lib/Transforms/Scalar/LoopInterchange.cpp
index afbf2ab15fbbb..c364e235b408e 100644
--- a/llvm/lib/Transforms/Scalar/LoopInterchange.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopInterchange.cpp
@@ -1589,17 +1589,19 @@ std::optional<const SCEV *> getAddRecCoefficient(ScalarEvolution &SE,
}
int LoopInterchangeProfitability::getInstrOrderCost() {
- unsigned GoodOrder, BadOrder;
- BadOrder = GoodOrder = 0;
+ // Map from the base pointer fo an acess to a pair of booleans indicating
+ // whether we find good or bad order.
+ DenseMap<const SCEV *, std::pair<bool, bool>> BasePtr2Score;
for (BasicBlock *BB : InnerLoop->blocks()) {
for (Instruction &Ins : *BB) {
if (!isa<LoadInst, StoreInst>(&Ins))
continue;
- const SCEV *Ptr = SE->getSCEV(getLoadStorePointerOperand(&Ins));
+ const SCEV *Access = SE->getSCEV(getLoadStorePointerOperand(&Ins));
+ const SCEV *BasePtr = SE->getPointerBase(Access);
std::optional<const SCEV *> OuterCoeff =
- getAddRecCoefficient(*SE, Ptr, OuterLoop);
+ getAddRecCoefficient(*SE, Access, OuterLoop);
std::optional<const SCEV *> InnerCoeff =
- getAddRecCoefficient(*SE, Ptr, InnerLoop);
+ getAddRecCoefficient(*SE, Access, InnerLoop);
if (!OuterCoeff.has_value() || !*OuterCoeff || !InnerCoeff.has_value() ||
!*InnerCoeff)
@@ -1619,7 +1621,7 @@ int LoopInterchangeProfitability::getInstrOrderCost() {
// for(int j=0;j<N;j++)
// A[i][j] = A[i-1][j-1]+k;
// then it is a good order.
- GoodOrder++;
+ BasePtr2Score[BasePtr].first = true;
} else if (SE->isKnownPredicate(ICmpInst::ICMP_SLT, OuterStep,
InnerStep)) {
// If we find the outer induction after an inner induction e.g.
@@ -1627,10 +1629,19 @@ int LoopInterchangeProfitability::getInstrOrderCost() {
// for(int j=0;j<N;j++)
// A[j][i] = A[j-1][i-1]+k;
// then it is a bad order.
- BadOrder++;
+ BasePtr2Score[BasePtr].second = true;
}
}
}
+
+ int GoodOrder = 0, BadOrder = 0;
+ for (const auto &[BasePtr, Score] : BasePtr2Score) {
+ auto [Good, Bad] = Score;
+ if (Good)
+ GoodOrder++;
+ if (Bad)
+ BadOrder++;
+ }
return GoodOrder - BadOrder;
}
diff --git a/llvm/test/Transforms/LoopInterchange/profitability-instorder.ll b/llvm/test/Transforms/LoopInterchange/profitability-instorder.ll
index d0f9447193acd..cb1b4e337c101 100644
--- a/llvm/test/Transforms/LoopInterchange/profitability-instorder.ll
+++ b/llvm/test/Transforms/LoopInterchange/profitability-instorder.ll
@@ -198,19 +198,13 @@ exit:
define void @unprofitable1(ptr noalias %A, ptr noalias %B, ptr noalias %C) {
; CHECK-LABEL: define void @unprofitable1(
; CHECK-SAME: ptr noalias [[A:%.*]], ptr noalias [[B:%.*]], ptr noalias [[C:%.*]]) {
-; CHECK-NEXT: [[ENTRY:.*:]]
-; CHECK-NEXT: br label %[[LOOP_J_PREHEADER:.*]]
-; CHECK: [[LOOP_I_HEADER_PREHEADER:.*]]:
-; CHECK-NEXT: br label %[[LOOP_I_HEADER:.*]]
-; CHECK: [[LOOP_I_HEADER]]:
-; CHECK-NEXT: [[I:%.*]] = phi i64 [ [[I_INC:%.*]], %[[LOOP_I_LATCH:.*]] ], [ 0, %[[LOOP_I_HEADER_PREHEADER]] ]
-; CHECK-NEXT: br label %[[LOOP_J_SPLIT1:.*]]
-; CHECK: [[LOOP_J_PREHEADER]]:
+; CHECK-NEXT: [[LOOP_J_PREHEADER:.*]]:
; CHECK-NEXT: br label %[[LOOP_J:.*]]
; CHECK: [[LOOP_J]]:
-; CHECK-NEXT: [[J:%.*]] = phi i64 [ [[TMP0:%.*]], %[[LOOP_J_SPLIT:.*]] ], [ 0, %[[LOOP_J_PREHEADER]] ]
-; CHECK-NEXT: br label %[[LOOP_I_HEADER_PREHEADER]]
-; CHECK: [[LOOP_J_SPLIT1]]:
+; CHECK-NEXT: [[I:%.*]] = phi i64 [ 0, %[[LOOP_J_PREHEADER]] ], [ [[I_INC:%.*]], %[[LOOP_I_LATCH:.*]] ]
+; CHECK-NEXT: br label %[[LOOP_I_HEADER_PREHEADER:.*]]
+; CHECK: [[LOOP_I_HEADER_PREHEADER]]:
+; CHECK-NEXT: [[J:%.*]] = phi i64 [ 0, %[[LOOP_J]] ], [ [[TMP0:%.*]], %[[LOOP_I_HEADER_PREHEADER]] ]
; CHECK-NEXT: [[GEP_A:%.*]] = getelementptr inbounds [100 x i8], ptr [[A]], i64 [[I]], i64 [[J]]
; CHECK-NEXT: [[GEP_B:%.*]] = getelementptr inbounds [100 x i8], ptr [[B]], i64 [[I]], i64 [[J]]
; CHECK-NEXT: [[GEP_C0:%.*]] = getelementptr inbounds [100 x i8], ptr [[C]], i64 [[J]], i64 [[I]]
@@ -224,17 +218,13 @@ define void @unprofitable1(ptr noalias %A, ptr noalias %B, ptr noalias %C) {
; CHECK-NEXT: [[SUM_1:%.*]] = add i8 [[SUM_0]], [[VAL_C1]]
; CHECK-NEXT: [[SUM_2:%.*]] = add i8 [[SUM_1]], [[VAL_C2]]
; CHECK-NEXT: store i8 [[SUM_2]], ptr [[GEP_A]], align 1
-; CHECK-NEXT: [[J_INC:%.*]] = add i64 [[J]], 1
-; CHECK-NEXT: [[EC_J:%.*]] = icmp eq i64 [[J_INC]], 10
-; CHECK-NEXT: br label %[[LOOP_I_LATCH]]
-; CHECK: [[LOOP_J_SPLIT]]:
; CHECK-NEXT: [[TMP0]] = add i64 [[J]], 1
; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i64 [[TMP0]], 10
-; CHECK-NEXT: br i1 [[TMP1]], label %[[EXIT:.*]], label %[[LOOP_J]]
+; CHECK-NEXT: br i1 [[TMP1]], label %[[LOOP_I_LATCH]], label %[[LOOP_I_HEADER_PREHEADER]]
; CHECK: [[LOOP_I_LATCH]]:
; CHECK-NEXT: [[I_INC]] = add i64 [[I]], 1
; CHECK-NEXT: [[EC_I:%.*]] = icmp eq i64 [[I_INC]], 10
-; CHECK-NEXT: br i1 [[EC_I]], label %[[LOOP_J_SPLIT]], label %[[LOOP_I_HEADER]]
+; CHECK-NEXT: br i1 [[EC_I]], label %[[EXIT:.*]], label %[[LOOP_J]]
; CHECK: [[EXIT]]:
; CHECK-NEXT: ret void
;
More information about the llvm-branch-commits
mailing list