[llvm] SPIRV: Fix constructing temporary TTI in SPIRVPrepareFunctions (PR #209977)

Matt Arsenault via llvm-commits llvm-commits at lists.llvm.org
Wed Jul 15 23:14:36 PDT 2026


https://github.com/arsenm created https://github.com/llvm/llvm-project/pull/209977

Passes should obtain TargetTransformInfo from the analysis manager
and never construct one. It may contain pipeline configuration state
(e.g., TargetLibraryInfo).

Co-authored-by: Claude (Claude Opus 4.8) <noreply at anthropic.com>

>From a9b570a432736a678953e5127f232ff9f76367bf Mon Sep 17 00:00:00 2001
From: Matt Arsenault <Matthew.Arsenault at amd.com>
Date: Thu, 16 Jul 2026 08:05:26 +0200
Subject: [PATCH] SPIRV: Fix constructing temporary TTI in
 SPIRVPrepareFunctions

Passes should obtain TargetTransformInfo from the analysis manager
and never construct one. It may contain pipeline configuration state
(e.g., TargetLibraryInfo).

Co-authored-by: Claude (Claude Opus 4.8) <noreply at anthropic.com>
---
 .../Target/SPIRV/SPIRVPrepareFunctions.cpp    | 35 +++++++++++++++----
 1 file changed, 29 insertions(+), 6 deletions(-)

diff --git a/llvm/lib/Target/SPIRV/SPIRVPrepareFunctions.cpp b/llvm/lib/Target/SPIRV/SPIRVPrepareFunctions.cpp
index 2b07f23e717d5..9b418e6f88d67 100644
--- a/llvm/lib/Target/SPIRV/SPIRVPrepareFunctions.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVPrepareFunctions.cpp
@@ -35,6 +35,7 @@
 #include "llvm/IR/IntrinsicInst.h"
 #include "llvm/IR/Intrinsics.h"
 #include "llvm/IR/IntrinsicsSPIRV.h"
+#include "llvm/InitializePasses.h"
 #include "llvm/Transforms/Utils/Cloning.h"
 #include "llvm/Transforms/Utils/Local.h"
 #include "llvm/Transforms/Utils/LowerMemIntrinsics.h"
@@ -46,6 +47,7 @@ namespace {
 
 class SPIRVPrepareFunctionsImpl {
   const SPIRVTargetMachine &TM;
+  function_ref<const TargetTransformInfo &(Function &)> GetTTI;
   bool substituteIntrinsicCalls(Function *F);
   bool substituteAbortKHRCalls(Function *F);
   bool terminateBlocksAfterTrap(Module &M, Intrinsic::ID IID);
@@ -53,7 +55,10 @@ class SPIRVPrepareFunctionsImpl {
   bool removeAggregateTypesFromCalls(Function *F);
 
 public:
-  SPIRVPrepareFunctionsImpl(const SPIRVTargetMachine &TM) : TM(TM) {}
+  SPIRVPrepareFunctionsImpl(
+      const SPIRVTargetMachine &TM,
+      function_ref<const TargetTransformInfo &(Function &)> GetTTI)
+      : TM(TM), GetTTI(GetTTI) {}
   bool runOnModule(Module &M);
 };
 
@@ -66,7 +71,14 @@ class SPIRVPrepareFunctionsLegacy : public ModulePass {
       : ModulePass(ID), TM(TM) {}
 
   bool runOnModule(Module &M) override {
-    return SPIRVPrepareFunctionsImpl(TM).runOnModule(M);
+    auto GetTTI = [this](Function &F) -> const TargetTransformInfo & {
+      return getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F);
+    };
+    return SPIRVPrepareFunctionsImpl(TM, GetTTI).runOnModule(M);
+  }
+
+  void getAnalysisUsage(AnalysisUsage &AU) const override {
+    AU.addRequired<TargetTransformInfoWrapperPass>();
   }
 
   StringRef getPassName() const override { return "SPIRV prepare functions"; }
@@ -83,8 +95,11 @@ static cl::list<std::string> SPVAllowUnknownIntrinsics(
 
 char SPIRVPrepareFunctionsLegacy::ID = 0;
 
-INITIALIZE_PASS(SPIRVPrepareFunctionsLegacy, "spirv-prepare-functions",
-                "SPIRV prepare functions", false, false)
+INITIALIZE_PASS_BEGIN(SPIRVPrepareFunctionsLegacy, "spirv-prepare-functions",
+                      "SPIRV prepare functions", false, false)
+INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass)
+INITIALIZE_PASS_END(SPIRVPrepareFunctionsLegacy, "spirv-prepare-functions",
+                    "SPIRV prepare functions", false, false)
 
 static std::string lowerLLVMIntrinsicName(IntrinsicInst *II) {
   Function *IntrinsicFunc = II->getCalledFunction();
@@ -452,10 +467,13 @@ lowerConstrainedFmuladd(IntrinsicInst *II,
 // Substitutes calls to LLVM intrinsics with either calls to SPIR-V intrinsics
 // or calls to proper generated functions. Returns True if F was modified.
 bool SPIRVPrepareFunctionsImpl::substituteIntrinsicCalls(Function *F) {
+  if (F->isDeclaration())
+    return false;
+
   bool Changed = false;
   const SPIRVSubtarget &STI = TM.getSubtarget<SPIRVSubtarget>(*F);
   SmallVector<Instruction *> EraseFromParent;
-  const TargetTransformInfo &TTI = TM.getTargetTransformInfo(*F);
+  const TargetTransformInfo &TTI = GetTTI(*F);
   for (BasicBlock &BB : *F) {
     for (Instruction &I : make_early_inc_range(BB)) {
       auto Call = dyn_cast<CallInst>(&I);
@@ -896,7 +914,12 @@ bool SPIRVPrepareFunctionsImpl::runOnModule(Module &M) {
 
 PreservedAnalyses SPIRVPrepareFunctions::run(Module &M,
                                              ModuleAnalysisManager &AM) {
-  return SPIRVPrepareFunctionsImpl(TM).runOnModule(M)
+  FunctionAnalysisManager &FAM =
+      AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
+  auto GetTTI = [&FAM](Function &F) -> const TargetTransformInfo & {
+    return FAM.getResult<TargetIRAnalysis>(F);
+  };
+  return SPIRVPrepareFunctionsImpl(TM, GetTTI).runOnModule(M)
              ? PreservedAnalyses::none()
              : PreservedAnalyses::all();
 }



More information about the llvm-commits mailing list