[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
Fri May 15 06:30:53 PDT 2026


https://github.com/kasuga-fj updated https://github.com/llvm/llvm-project/pull/193477

>From 57ba55f500ac0757936b73831aa1cf01da809ee7 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 93d43c76885a7..c9c4e08d84e60 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 92d56b98e2591..9c192a85b5781 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