[llvm] [ICP] Fix getProfitablePromotionCandidates to respect overriden max (PR #201590)
Teresa Johnson via llvm-commits
llvm-commits at lists.llvm.org
Thu Jun 4 06:59:48 PDT 2026
https://github.com/teresajohnson created https://github.com/llvm/llvm-project/pull/201590
This addresses an issue where getProfitablePromotionCandidates used
MaxNumPromotions even when its caller getPromotionCandidatesForInstruction
was called with an explicitly overridden MaxNumValueData (e.g. from
-module-summary-max-indirect-edges in ThinLTO backend). By removing the
MaxNumPromotions check from getProfitablePromotionCandidates, we allow
it to properly return NumCandidates up to the size of the array set up
based on the provided MaxNumValueData in the caller.
Added a unit test to verify that NumCandidates correctly evaluates up to
the provided MaxNumValueData limit instead of being artificially
truncated.
>From 7138874bdfd2a4455e970855c3bf0e6a546bd4f1 Mon Sep 17 00:00:00 2001
From: Teresa Johnson <tejohnson at google.com>
Date: Wed, 3 Jun 2026 20:11:39 -0700
Subject: [PATCH] [ICP] Fix getProfitablePromotionCandidates to respect
overriden max
This addresses an issue where getProfitablePromotionCandidates used
MaxNumPromotions even when its caller getPromotionCandidatesForInstruction
was called with an explicitly overridden MaxNumValueData (e.g. from
-module-summary-max-indirect-edges in ThinLTO backend). By removing the
MaxNumPromotions check from getProfitablePromotionCandidates, we allow
it to properly return NumCandidates up to the size of the array set up
based on the provided MaxNumValueData in the caller.
Added a unit test to verify that NumCandidates correctly evaluates up to
the provided MaxNumValueData limit instead of being artificially
truncated.
---
.../IndirectCallPromotionAnalysis.cpp | 4 +-
llvm/unittests/Analysis/CMakeLists.txt | 1 +
.../IndirectCallPromotionAnalysisTest.cpp | 49 +++++++++++++++++++
3 files changed, 53 insertions(+), 1 deletion(-)
create mode 100644 llvm/unittests/Analysis/IndirectCallPromotionAnalysisTest.cpp
diff --git a/llvm/lib/Analysis/IndirectCallPromotionAnalysis.cpp b/llvm/lib/Analysis/IndirectCallPromotionAnalysis.cpp
index 6dc03bcfdf49c..0b5d5bba79138 100644
--- a/llvm/lib/Analysis/IndirectCallPromotionAnalysis.cpp
+++ b/llvm/lib/Analysis/IndirectCallPromotionAnalysis.cpp
@@ -76,7 +76,7 @@ uint32_t ICallPromotionAnalysis::getProfitablePromotionCandidates(
uint32_t I = 0;
uint64_t RemainingCount = TotalCount;
- for (; I < MaxNumPromotions && I < ValueDataArray.size(); I++) {
+ for (; I < ValueDataArray.size(); I++) {
uint64_t Count = ValueDataArray[I].Count;
assert(Count <= RemainingCount);
LLVM_DEBUG(dbgs() << " Candidate " << I << " Count=" << Count
@@ -105,6 +105,8 @@ ICallPromotionAnalysis::getPromotionCandidatesForInstruction(
NumCandidates = 0;
return MutableArrayRef<InstrProfValueData>();
}
+ assert(ValueDataArray.size() <= MaxNumValueData &&
+ "Number of profile values exceeds limit");
NumCandidates = getProfitablePromotionCandidates(I, TotalCount);
return ValueDataArray;
}
diff --git a/llvm/unittests/Analysis/CMakeLists.txt b/llvm/unittests/Analysis/CMakeLists.txt
index 50bf4539e7984..1bec438d2d339 100644
--- a/llvm/unittests/Analysis/CMakeLists.txt
+++ b/llvm/unittests/Analysis/CMakeLists.txt
@@ -32,6 +32,7 @@ set(ANALYSIS_TEST_SOURCES
GraphWriterTest.cpp
GlobalsModRefTest.cpp
FunctionPropertiesAnalysisTest.cpp
+ IndirectCallPromotionAnalysisTest.cpp
InlineCostTest.cpp
IR2VecTest.cpp
IRSimilarityIdentifierTest.cpp
diff --git a/llvm/unittests/Analysis/IndirectCallPromotionAnalysisTest.cpp b/llvm/unittests/Analysis/IndirectCallPromotionAnalysisTest.cpp
new file mode 100644
index 0000000000000..1aae1ca28d5c8
--- /dev/null
+++ b/llvm/unittests/Analysis/IndirectCallPromotionAnalysisTest.cpp
@@ -0,0 +1,49 @@
+#include "llvm/Analysis/IndirectCallPromotionAnalysis.h"
+#include "llvm/AsmParser/Parser.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/Module.h"
+#include "llvm/Support/SourceMgr.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+
+namespace {
+
+TEST(IndirectCallPromotionAnalysisTest, MaxNumValueDataOverridesMaxNumPromotions) {
+ LLVMContext C;
+ SMDiagnostic Err;
+ std::unique_ptr<Module> M = parseAssemblyString(
+ "target datalayout = \"e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128\"\n"
+ "target triple = \"x86_64-unknown-linux-gnu\"\n"
+ "define i32 @foo(ptr %p) {\n"
+ " %call = tail call i32 %p(), !prof !0\n"
+ " ret i32 0\n"
+ "}\n"
+ "!0 = !{!\"VP\", i32 0, i64 1750, i64 111, i64 1000, i64 222, i64 400, i64 333, i64 200, i64 444, i64 150}\n",
+ Err, C);
+ ASSERT_TRUE(M);
+
+ Function *F = M->getFunction("foo");
+ ASSERT_TRUE(F);
+ Instruction *Inst = &F->front().front();
+ ASSERT_TRUE(isa<CallInst>(Inst));
+
+ ICallPromotionAnalysis ICallAnalysis;
+ uint64_t TotalCount;
+ uint32_t NumCandidates;
+
+ // The default MaxNumPromotions is 3. We override MaxNumValueData to 4.
+ // The VP metadata has 4 targets.
+ auto Candidates = ICallAnalysis.getPromotionCandidatesForInstruction(
+ Inst, TotalCount, NumCandidates, 4);
+
+ EXPECT_EQ(TotalCount, 1750u);
+ EXPECT_EQ(Candidates.size(), 4u);
+
+ // NumCandidates should not be artificially truncated by the default
+ // MaxNumPromotions (3), since it was overridden by MaxNumValueData (4).
+ EXPECT_EQ(NumCandidates, 4u);
+}
+
+} // end anonymous namespace
More information about the llvm-commits
mailing list