From d648008e3c0f86cdac01cfd43ab18593fc55d937 Mon Sep 17 00:00:00 2001 From: "Zhao, Maosu" Date: Thu, 5 Jun 2025 08:07:46 +0200 Subject: [PATCH 1/2] [DevSAN] Make device sanitizer kernel metadata has a unique id We decorated kernel metadata global as a device global, if we don't give a unique id to it, device sanitizer will not work in shared libraries. --- .../Instrumentation/SPIRVSanitizerCommonUtils.h | 4 ++++ .../Instrumentation/AddressSanitizer.cpp | 7 +++++-- .../Transforms/Instrumentation/MemorySanitizer.cpp | 7 +++++-- .../Instrumentation/SPIRVSanitizerCommonUtils.cpp | 14 ++++++++++++++ .../Transforms/Instrumentation/ThreadSanitizer.cpp | 8 ++++++-- .../SPIRV/extend_launch_info_arg.ll | 3 ++- .../SPIRV/instrument_global_address_space.ll | 2 +- .../ThreadSanitizer/SPIRV/kernel_metadata.ll | 2 ++ 8 files changed, 39 insertions(+), 8 deletions(-) diff --git a/llvm/include/llvm/Transforms/Instrumentation/SPIRVSanitizerCommonUtils.h b/llvm/include/llvm/Transforms/Instrumentation/SPIRVSanitizerCommonUtils.h index f6edabcc3bbf3..c40a245ece572 100644 --- a/llvm/include/llvm/Transforms/Instrumentation/SPIRVSanitizerCommonUtils.h +++ b/llvm/include/llvm/Transforms/Instrumentation/SPIRVSanitizerCommonUtils.h @@ -12,6 +12,7 @@ #ifndef LLVM_TRANSFORMS_INSTRUMENTATION_SPIRVSANITIZERCOMMONUTILS_H #define LLVM_TRANSFORMS_INSTRUMENTATION_SPIRVSANITIZERCOMMONUTILS_H +#include "llvm/ADT/SmallString.h" #include "llvm/IR/DerivedTypes.h" #include "llvm/IR/Type.h" #include "llvm/IR/Value.h" @@ -26,6 +27,9 @@ constexpr unsigned kSpirOffloadGenericAS = 4; TargetExtType *getTargetExtType(Type *Ty); bool isJointMatrixAccess(Value *V); + +SmallString<128> computeKernelMetadataUniqueId(StringRef Prefix, + SmallVectorImpl &KernelNamesBytes); } // namespace llvm #endif // LLVM_TRANSFORMS_INSTRUMENTATION_SPIRVSANITIZERCOMMONUTILS_H diff --git a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp index e5c7958ac644f..40493a3f5a4a3 100644 --- a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp @@ -1402,6 +1402,7 @@ static void ExtendSpirKernelArgs(Module &M, FunctionAnalysisManager &FAM, bool HasESIMD) { SmallVector SpirFixupKernels; SmallVector SpirKernelsMetadata; + SmallVector KernelNamesBytes; const auto &DL = M.getDataLayout(); Type *IntptrTy = DL.getIntPtrType(M.getContext()); @@ -1438,6 +1439,7 @@ static void ExtendSpirKernelArgs(Module &M, FunctionAnalysisManager &FAM, SpirFixupKernels.emplace_back(&F); auto KernelName = F.getName(); + KernelNamesBytes.append(KernelName.begin(), KernelName.end()); auto *KernelNameGV = GetOrCreateGlobalString( M, "__asan_kernel", KernelName, kSpirOffloadConstantAS); SpirKernelsMetadata.emplace_back(ConstantStruct::get( @@ -1459,8 +1461,9 @@ static void ExtendSpirKernelArgs(Module &M, FunctionAnalysisManager &FAM, "sycl-device-global-size", std::to_string(DL.getTypeAllocSize(ArrayTy))); AsanSpirKernelMetadata->addAttribute("sycl-device-image-scope"); AsanSpirKernelMetadata->addAttribute("sycl-host-access", "0"); // read only - AsanSpirKernelMetadata->addAttribute("sycl-unique-id", - "_Z20__AsanKernelMetadata"); + AsanSpirKernelMetadata->addAttribute( + "sycl-unique-id", + computeKernelMetadataUniqueId("__AsanKernelMetadata", KernelNamesBytes)); AsanSpirKernelMetadata->setDSOLocal(true); // Handle SpirFixupKernels diff --git a/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp b/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp index f95d3ca03b4bd..b584c97fbf2b8 100644 --- a/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp @@ -1175,6 +1175,7 @@ void MemorySanitizerOnSpirv::instrumentPrivateArguments( // kernel void MemorySanitizerOnSpirv::instrumentKernelsMetadata() { SmallVector SpirKernelsMetadata; + SmallVector KernelNamesBytes; // SpirKernelsMetadata only saves fixed kernels, and is described by // following structure: @@ -1193,6 +1194,7 @@ void MemorySanitizerOnSpirv::instrumentKernelsMetadata() { continue; auto KernelName = F.getName(); + KernelNamesBytes.append(KernelName.begin(), KernelName.end()); auto *KernelNameGV = getOrCreateGlobalString("__msan_kernel", KernelName, kSpirOffloadConstantAS); SpirKernelsMetadata.emplace_back(ConstantStruct::get( @@ -1217,8 +1219,9 @@ void MemorySanitizerOnSpirv::instrumentKernelsMetadata() { MsanSpirKernelMetadata->addAttribute("sycl-device-image-scope"); MsanSpirKernelMetadata->addAttribute("sycl-host-access", "0"); // read only - MsanSpirKernelMetadata->addAttribute("sycl-unique-id", - "_Z20__MsanKernelMetadata"); + MsanSpirKernelMetadata->addAttribute( + "sycl-unique-id", + computeKernelMetadataUniqueId("__MsanKernelMetadata", KernelNamesBytes)); MsanSpirKernelMetadata->setDSOLocal(true); } diff --git a/llvm/lib/Transforms/Instrumentation/SPIRVSanitizerCommonUtils.cpp b/llvm/lib/Transforms/Instrumentation/SPIRVSanitizerCommonUtils.cpp index f08d931b96375..ac2ba91c171c5 100644 --- a/llvm/lib/Transforms/Instrumentation/SPIRVSanitizerCommonUtils.cpp +++ b/llvm/lib/Transforms/Instrumentation/SPIRVSanitizerCommonUtils.cpp @@ -12,6 +12,7 @@ #include "llvm/Transforms/Instrumentation/SPIRVSanitizerCommonUtils.h" #include "llvm/IR/Instructions.h" +#include "llvm/Support/MD5.h" using namespace llvm; @@ -58,4 +59,17 @@ bool isJointMatrixAccess(Value *V) { } return false; } + +SmallString<128> +computeKernelMetadataUniqueId(StringRef Prefix, + SmallVectorImpl &KernelNamesBytes) { + MD5 Hash; + SmallString<32> UniqueIdSuffix; + SmallString<128> UniqueId(Prefix); + auto R = Hash.hash(KernelNamesBytes); + Hash.stringifyResult(R, UniqueIdSuffix); + UniqueId.append(UniqueIdSuffix); + return UniqueId; +} + } // namespace llvm diff --git a/llvm/lib/Transforms/Instrumentation/ThreadSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/ThreadSanitizer.cpp index 6b449ad1ab3c0..769ce19dc24de 100644 --- a/llvm/lib/Transforms/Instrumentation/ThreadSanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/ThreadSanitizer.cpp @@ -37,6 +37,7 @@ #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Metadata.h" #include "llvm/IR/Module.h" +#include "llvm/IR/ModuleSummaryIndex.h" #include "llvm/IR/Type.h" #include "llvm/ProfileData/InstrProf.h" #include "llvm/Support/CommandLine.h" @@ -505,6 +506,7 @@ void ThreadSanitizerOnSpirv::instrumentGlobalVariables() { void ThreadSanitizerOnSpirv::instrumentKernelsMetadata() { SmallVector SpirKernelsMetadata; + SmallVector KernelNamesBytes; // SpirKernelsMetadata only saves fixed kernels, and is described by // following structure: @@ -518,6 +520,7 @@ void ThreadSanitizerOnSpirv::instrumentKernelsMetadata() { if (isSupportedSPIRKernel(F)) { auto KernelName = F.getName(); + KernelNamesBytes.append(KernelName.begin(), KernelName.end()); auto *KernelNameGV = GetOrCreateGlobalString("__tsan_kernel", KernelName, kSpirOffloadConstantAS); SpirKernelsMetadata.emplace_back(ConstantStruct::get( @@ -540,8 +543,9 @@ void ThreadSanitizerOnSpirv::instrumentKernelsMetadata() { "sycl-device-global-size", std::to_string(DL.getTypeAllocSize(ArrayTy))); TsanSpirKernelMetadata->addAttribute("sycl-device-image-scope"); TsanSpirKernelMetadata->addAttribute("sycl-host-access", "0"); // read only - TsanSpirKernelMetadata->addAttribute("sycl-unique-id", - "_Z20__TsanKernelMetadata"); + TsanSpirKernelMetadata->addAttribute( + "sycl-unique-id", computeKernelMetadataUniqueId("__TsanKernelMetadata", + KernelNamesBytes)); TsanSpirKernelMetadata->setDSOLocal(true); } diff --git a/llvm/test/Instrumentation/AddressSanitizer/SPIRV/extend_launch_info_arg.ll b/llvm/test/Instrumentation/AddressSanitizer/SPIRV/extend_launch_info_arg.ll index 073eca99cdd27..1590d1f8997fb 100644 --- a/llvm/test/Instrumentation/AddressSanitizer/SPIRV/extend_launch_info_arg.ll +++ b/llvm/test/Instrumentation/AddressSanitizer/SPIRV/extend_launch_info_arg.ll @@ -4,6 +4,7 @@ target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256: target triple = "spir64-unknown-unknown" ; CHECK: @__AsanKernelMetadata = appending dso_local local_unnamed_addr addrspace(1) global +; CHECK-SAME: [[ATTR0:#[0-9]+]] ; CHECK: @__AsanLaunchInfo = external addrspace(3) global ptr addrspace(1) define spir_kernel void @sycl_kernel1() #0 { @@ -25,4 +26,4 @@ entry: attributes #0 = { sanitize_address } ;; sycl-device-global-size = 16 * 2 ;; sycl-host-access = 0 read-only -; CHECK: attributes #{{.*}} = { "sycl-device-global-size"="32" "sycl-device-image-scope" "sycl-host-access"="0" "sycl-unique-id"="_Z20__AsanKernelMetadata" } +; CHECK: attributes [[ATTR0]] = { "sycl-device-global-size"="32" "sycl-device-image-scope" "sycl-host-access"="0" "sycl-unique-id"="__AsanKernelMetadata833c47834a0b74946e370c23c39607cc" } diff --git a/llvm/test/Instrumentation/MemorySanitizer/SPIRV/instrument_global_address_space.ll b/llvm/test/Instrumentation/MemorySanitizer/SPIRV/instrument_global_address_space.ll index e161876b37913..bb71ec9a436f7 100644 --- a/llvm/test/Instrumentation/MemorySanitizer/SPIRV/instrument_global_address_space.ll +++ b/llvm/test/Instrumentation/MemorySanitizer/SPIRV/instrument_global_address_space.ll @@ -31,4 +31,4 @@ entry: } ; CHECK: attributes [[ATTR0]] -; CHECK-SAME: "sycl-device-global-size"="32" "sycl-device-image-scope" "sycl-host-access"="0" "sycl-unique-id"="_Z20__MsanKernelMetadata" +; CHECK-SAME: "sycl-device-global-size"="32" "sycl-device-image-scope" "sycl-host-access"="0" "sycl-unique-id"="__MsanKernelMetadata3ff767e9a7a43f1f3968062dbb4ee3b4" diff --git a/llvm/test/Instrumentation/ThreadSanitizer/SPIRV/kernel_metadata.ll b/llvm/test/Instrumentation/ThreadSanitizer/SPIRV/kernel_metadata.ll index 656071e562797..ca9d7b67eafad 100644 --- a/llvm/test/Instrumentation/ThreadSanitizer/SPIRV/kernel_metadata.ll +++ b/llvm/test/Instrumentation/ThreadSanitizer/SPIRV/kernel_metadata.ll @@ -4,6 +4,7 @@ target triple = "spir64-unknown-unknown" ; CHECK-LABEL: @__TsanKernelMetadata = appending dso_local local_unnamed_addr addrspace(1) global ; CHECK-SAME: i64 ptrtoint (ptr addrspace(2) @__tsan_kernel to i64 +; CHECK-SAME: [[ATTR0:#[0-9]+]] ; Function Attrs: sanitize_thread define spir_kernel void @test() #0 { @@ -11,4 +12,5 @@ entry: ret void } +; CHECK: attributes [[ATTR0]] = {{.*}} "sycl-unique-id"="__TsanKernelMetadata098f6bcd4621d373cade4e832627b4f6" attributes #0 = { sanitize_thread } From 07590bf6619ae4bcf0ce0079a4fb1aed58f13e27 Mon Sep 17 00:00:00 2001 From: "Zhao, Maosu" Date: Thu, 5 Jun 2025 08:14:36 +0200 Subject: [PATCH 2/2] Fix format --- .../Transforms/Instrumentation/SPIRVSanitizerCommonUtils.h | 3 ++- llvm/lib/Transforms/Instrumentation/ThreadSanitizer.cpp | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/llvm/include/llvm/Transforms/Instrumentation/SPIRVSanitizerCommonUtils.h b/llvm/include/llvm/Transforms/Instrumentation/SPIRVSanitizerCommonUtils.h index c40a245ece572..0711b465af333 100644 --- a/llvm/include/llvm/Transforms/Instrumentation/SPIRVSanitizerCommonUtils.h +++ b/llvm/include/llvm/Transforms/Instrumentation/SPIRVSanitizerCommonUtils.h @@ -28,7 +28,8 @@ constexpr unsigned kSpirOffloadGenericAS = 4; TargetExtType *getTargetExtType(Type *Ty); bool isJointMatrixAccess(Value *V); -SmallString<128> computeKernelMetadataUniqueId(StringRef Prefix, +SmallString<128> +computeKernelMetadataUniqueId(StringRef Prefix, SmallVectorImpl &KernelNamesBytes); } // namespace llvm diff --git a/llvm/lib/Transforms/Instrumentation/ThreadSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/ThreadSanitizer.cpp index 769ce19dc24de..2eecbe57dda3f 100644 --- a/llvm/lib/Transforms/Instrumentation/ThreadSanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/ThreadSanitizer.cpp @@ -544,8 +544,8 @@ void ThreadSanitizerOnSpirv::instrumentKernelsMetadata() { TsanSpirKernelMetadata->addAttribute("sycl-device-image-scope"); TsanSpirKernelMetadata->addAttribute("sycl-host-access", "0"); // read only TsanSpirKernelMetadata->addAttribute( - "sycl-unique-id", computeKernelMetadataUniqueId("__TsanKernelMetadata", - KernelNamesBytes)); + "sycl-unique-id", + computeKernelMetadataUniqueId("__TsanKernelMetadata", KernelNamesBytes)); TsanSpirKernelMetadata->setDSOLocal(true); }