[llvm] [LoopInterchange] Consider eligible inner subnests (PR #214920)

via llvm-commits llvm-commits at lists.llvm.org
Thu Sep 17 02:46:27 PDT 2026


https://github.com/MattPD updated https://github.com/llvm/llvm-project/pull/214920

>From b678046456225539553e7316c532c53280fd4c15 Mon Sep 17 00:00:00 2001
From: "Matt P. Dziubinski" <matt-p.dziubinski at hpe.com>
Date: Thu, 17 Sep 2026 04:45:53 -0500
Subject: [PATCH] [LoopInterchange] Avoid overflow in the memory-instruction
 ratio check

populateDependencyMatrix bails out if MaxMemInstrRatio * NumInsts is
less than NumMemInstr * NumMemInstr. Both products are computed in
32-bit unsigned arithmetic and can wrap, e.g., with
-loop-interchange-max-mem-instr-ratio=2147483648 and 20 instructions
the left product wraps to 0 and the pass rejects an otherwise eligible
nest.

Compute both products in uint64_t instead, which cannot overflow as all
three operands are 32 bits wide.

Assisted-by: Claude Opus 5, GPT-5.6 Sol, GPT-6 Astra, Claude Fable 5.1.
---
 llvm/lib/Transforms/Scalar/LoopInterchange.cpp      |  4 +++-
 .../LoopInterchange/memory-instr-ratio.ll           | 13 +++++++++----
 2 files changed, 12 insertions(+), 5 deletions(-)

diff --git a/llvm/lib/Transforms/Scalar/LoopInterchange.cpp b/llvm/lib/Transforms/Scalar/LoopInterchange.cpp
index 48a5ad97871b6..12708deda5096 100644
--- a/llvm/lib/Transforms/Scalar/LoopInterchange.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopInterchange.cpp
@@ -48,6 +48,7 @@
 #include "llvm/Transforms/Utils/Local.h"
 #include "llvm/Transforms/Utils/LoopUtils.h"
 #include <cassert>
+#include <cstdint>
 #include <utility>
 #include <vector>
 
@@ -203,7 +204,8 @@ static bool populateDependencyMatrix(CharMatrix &DepMatrix, unsigned Level,
   unsigned NumMemInstr = MemInstr.size();
   LLVM_DEBUG(dbgs() << "Found " << NumMemInstr
                     << " Loads and Stores to analyze\n");
-  if (MaxMemInstrRatio * NumInsts < NumMemInstr * NumMemInstr) {
+  if (static_cast<uint64_t>(MaxMemInstrRatio) * NumInsts <
+      static_cast<uint64_t>(NumMemInstr) * NumMemInstr) {
     ORE->emit([&]() {
       return OptimizationRemarkMissed(DEBUG_TYPE, "UnsupportedLoop",
                                       L->getStartLoc(), L->getHeader())
diff --git a/llvm/test/Transforms/LoopInterchange/memory-instr-ratio.ll b/llvm/test/Transforms/LoopInterchange/memory-instr-ratio.ll
index 7f76f25612d03..2b34bafb513bc 100644
--- a/llvm/test/Transforms/LoopInterchange/memory-instr-ratio.ll
+++ b/llvm/test/Transforms/LoopInterchange/memory-instr-ratio.ll
@@ -1,8 +1,15 @@
 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
 ; RUN: opt < %s -passes=loop-interchange -S -loop-interchange-profitabilities=ignore \
-; RUN:          -loop-interchange-max-mem-instr-ratio=1 | FileCheck %s --check-prefixes=CHECK,CHECK-RATIO-1
+; RUN:          -loop-interchange-max-mem-instr-ratio=1 | FileCheck %s --check-prefixes=CHECK-RATIO-1
 ; RUN: opt < %s -passes=loop-interchange -S -loop-interchange-profitabilities=ignore \
-; RUN:          -loop-interchange-max-mem-instr-ratio=100 | FileCheck %s --check-prefixes=CHECK,CHECK-RATIO-100
+; RUN:          -loop-interchange-max-mem-instr-ratio=100 | FileCheck %s --check-prefixes=CHECK-RATIO-100
+; The loop nest has 20 instructions and 10 stores. With 32-bit arithmetic,
+; 2147483648 * 20 wraps to zero, so the ratio guard rejects this otherwise
+; eligible nest. The guard bounds analysis cost, not legality. If the body
+; changes, keep the instruction count even, or choose a ratio whose 32-bit
+; product with the instruction count wraps below the squared load/store count.
+; RUN: opt < %s -passes=loop-interchange -S -loop-interchange-profitabilities=ignore \
+; RUN:          -loop-interchange-max-mem-instr-ratio=2147483648 | FileCheck %s --check-prefixes=CHECK-RATIO-100
 
 define void @f(ptr noalias %A) {
 ; CHECK-RATIO-1-LABEL: define void @f(
@@ -107,5 +114,3 @@ loop.i.latch:
 exit:
   ret void
 }
-;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
-; CHECK: {{.*}}



More information about the llvm-commits mailing list