[llvm] [SPIR-V] Reset SPIRVGlobalRegistry at module entry (PR #196058)

Arseniy Obolenskiy via llvm-commits llvm-commits at lists.llvm.org
Wed May 6 05:41:32 PDT 2026


https://github.com/aobolensk created https://github.com/llvm/llvm-project/pull/196058

GlobalRegistry is owned by the TartgetMaching lifetime Subtarget but caches IR pointers, so a reused TargetMachine (e.g. in case of JIT, libFuzzer) would carry stale entries from a prior module

The bug was caught by `llvm-isel-fuzzer` ran for `spirv64-unknown-unknown`

>From 5a9d6e3aeaa988ead7a3c41a6f573190309dd49e Mon Sep 17 00:00:00 2001
From: Arseniy Obolenskiy <arseniy.obolenskiy at amd.com>
Date: Wed, 6 May 2026 14:39:43 +0200
Subject: [PATCH] [SPIR-V] Reset SPIRVGlobalRegistry at module entry

GlobalRegistry is owned by the TartgetMaching lifetime Subtarget but caches IR pointers, so a reused TargetMachine (JIT, libFuzzer) would carry stale entries from a prior module. resolveEnvFromModule is the existing per-module hook

The bug was caught by `llvm-isel-fuzzer` ran for `spirv64-unknown-unknown`
---
 llvm/lib/Target/SPIRV/SPIRVSubtarget.cpp      |  2 ++
 .../Target/SPIRV/SPIRVGlobalRegistryTests.cpp | 30 +++++++++++++++++++
 2 files changed, 32 insertions(+)

diff --git a/llvm/lib/Target/SPIRV/SPIRVSubtarget.cpp b/llvm/lib/Target/SPIRV/SPIRVSubtarget.cpp
index e4c98984bf0af..5619748965112 100644
--- a/llvm/lib/Target/SPIRV/SPIRVSubtarget.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVSubtarget.cpp
@@ -193,6 +193,8 @@ void SPIRVSubtarget::setEnv(SPIRVEnvType E) {
 }
 
 void SPIRVSubtarget::resolveEnvFromModule(const Module &M) {
+  *GR = SPIRVGlobalRegistry(M.getDataLayout());
+
   if (Env != Unknown) {
     assert(!(isKernel() && any_of(M,
                                   [](const Function &F) {
diff --git a/llvm/unittests/Target/SPIRV/SPIRVGlobalRegistryTests.cpp b/llvm/unittests/Target/SPIRV/SPIRVGlobalRegistryTests.cpp
index e65a9321b403e..c7d4072cbf32e 100644
--- a/llvm/unittests/Target/SPIRV/SPIRVGlobalRegistryTests.cpp
+++ b/llvm/unittests/Target/SPIRV/SPIRVGlobalRegistryTests.cpp
@@ -6,15 +6,22 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "SPIRV.h"
 #include "SPIRVGlobalRegistry.h"
+#include "SPIRVISelLowering.h"
 #include "SPIRVInstrInfo.h"
+#include "SPIRVSubtarget.h"
+#include "SPIRVTargetMachine.h"
 #include "llvm/CodeGen/MachineInstrBuilder.h"
 #include "llvm/CodeGen/MachineModuleInfo.h"
+#include "llvm/CodeGen/MachineRegisterInfo.h"
+#include "llvm/IR/LegacyPassManager.h"
 #include "llvm/IR/Module.h"
 #include "llvm/MC/TargetRegistry.h"
 #include "llvm/Support/TargetSelect.h"
 #include "llvm/Target/TargetMachine.h"
 #include "gtest/gtest.h"
+#include <optional>
 
 using namespace llvm;
 
@@ -71,3 +78,26 @@ TEST_F(SPIRVGlobalRegistryTest, IsAggregateType) {
   EXPECT_FALSE(GR.isAggregateType(makeTypeInstr(SPIRV::OpTypeFloat)));
   EXPECT_FALSE(GR.isAggregateType(SPIRVTypeInst(nullptr)));
 }
+
+TEST_F(SPIRVGlobalRegistryTest, PrepareFunctionsClearsStalePointers) {
+  auto *STM = static_cast<SPIRVTargetMachine *>(TM.get());
+  auto *GR = STM->getSubtargetImpl()->getSPIRVGlobalRegistry();
+
+  Function *F = Mod->getFunction("f");
+  ASSERT_NE(F, nullptr);
+  Type *I32 = Type::getInt32Ty(*Ctx);
+  GR->addDeducedElementType(F, I32);
+  ASSERT_EQ(GR->findDeducedElementType(F), I32);
+
+  LLVMContext Ctx2;
+  Module Mod2("M2", Ctx2);
+  Mod2.setDataLayout(TM->createDataLayout());
+  Function::Create(FunctionType::get(Type::getVoidTy(Ctx2), false),
+                   GlobalValue::ExternalLinkage, "g", Mod2);
+
+  legacy::PassManager PM;
+  PM.add(createSPIRVPrepareFunctionsPass(*STM));
+  PM.run(Mod2);
+
+  EXPECT_EQ(GR->findDeducedElementType(F), nullptr);
+}



More information about the llvm-commits mailing list