[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