[compiler-rt] [compiler-rt] Enable ubsan_minimal runtime for SPIR-V (PR #196149)
Victor Mustya via llvm-commits
llvm-commits at lists.llvm.org
Wed May 6 11:48:36 PDT 2026
https://github.com/vmustya created https://github.com/llvm/llvm-project/pull/196149
The SPIR-V target support for UBSan Minimal Runtime is added to provide
basic undefined behavior detection capabilities for SPIR-V based devices.
Currently, only the `spirv64` target is supported.
>From 70666190001d15c9d568ab3fac7b23c536b90e7b Mon Sep 17 00:00:00 2001
From: Victor Mustya <victor.mustya at intel.com>
Date: Wed, 6 May 2026 11:41:23 -0700
Subject: [PATCH] [compiler-rt] Enable ubsan_minimal runtime for SPIR-V
The SPIR-V target support for UBSan Minimal Runtime is added to provide
basic undefined behavior detection capabilities for SPIR-V based devices.
Currently, only the `spirv64` target is supported.
---
compiler-rt/CMakeLists.txt | 4 ++--
.../cmake/Modules/AllSupportedArchDefs.cmake | 3 ++-
compiler-rt/cmake/base-config-ix.cmake | 2 ++
compiler-rt/cmake/config-ix.cmake | 2 +-
.../lib/sanitizer_common/sanitizer_platform.h | 9 +++++++-
.../ubsan_minimal/ubsan_minimal_handlers.cpp | 21 ++++++++++++++++++-
6 files changed, 35 insertions(+), 6 deletions(-)
diff --git a/compiler-rt/CMakeLists.txt b/compiler-rt/CMakeLists.txt
index 6e8045631b218..e88321d822f84 100644
--- a/compiler-rt/CMakeLists.txt
+++ b/compiler-rt/CMakeLists.txt
@@ -370,7 +370,7 @@ if("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "hexagon")
list(APPEND SANITIZER_COMMON_CFLAGS -fno-emulated-tls)
string(APPEND COMPILER_RT_TEST_COMPILER_CFLAGS " -fno-emulated-tls")
endif()
-if("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "amdgcn|nvptx")
+if("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "amdgcn|nvptx|spirv64")
append_list_if(UBSAN_COMMON_SUPPORTED_ARCH -ffreestanding SANITIZER_COMMON_CFLAGS)
append_list_if(COMPILER_RT_HAS_NOGPULIB_FLAG -nogpulib SANITIZER_COMMON_CFLAGS)
append_list_if(COMPILER_RT_HAS_FLTO_FLAG -flto SANITIZER_COMMON_CFLAGS)
@@ -395,7 +395,7 @@ append_list_if(COMPILER_RT_HAS_FVISIBILITY_HIDDEN_FLAG -fvisibility=hidden SANIT
if(NOT COMPILER_RT_HAS_FVISIBILITY_HIDDEN_FLAG)
append_list_if(COMPILER_RT_HAS_FVISIBILITY_INLINES_HIDDEN_FLAG -fvisibility-inlines-hidden SANITIZER_COMMON_CFLAGS)
endif()
-if(NOT "${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "amdgcn|nvptx")
+if(NOT "${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "amdgcn|nvptx|spirv64")
append_list_if(COMPILER_RT_HAS_FNO_LTO_FLAG -fno-lto SANITIZER_COMMON_CFLAGS)
endif()
diff --git a/compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake b/compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake
index 761e26ce3e7d8..0cc4165c8dbd5 100644
--- a/compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake
+++ b/compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake
@@ -15,6 +15,7 @@ set(RISCV64 riscv64)
set(S390X s390x)
set(SPARC sparc)
set(SPARCV9 sparcv9)
+set(SPIRV64 spirv64)
set(WASM32 wasm32)
set(WASM64 wasm64)
set(VE ve)
@@ -105,7 +106,7 @@ endif()
set(ALL_TYSAN_SUPPORTED_ARCH ${X86_64} ${ARM64} ${S390X} ${HEXAGON})
set(ALL_UBSAN_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64} ${RISCV64}
${MIPS32} ${MIPS64} ${PPC64} ${S390X} ${SPARC} ${SPARCV9} ${HEXAGON}
- ${LOONGARCH64} ${AMDGPU} ${NVPTX})
+ ${LOONGARCH64} ${AMDGPU} ${NVPTX} ${SPIRV64})
if (OS_NAME MATCHES "FreeBSD")
set(ALL_SAFESTACK_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM64})
else()
diff --git a/compiler-rt/cmake/base-config-ix.cmake b/compiler-rt/cmake/base-config-ix.cmake
index 4898e3428ebb0..72f7b94f02603 100644
--- a/compiler-rt/cmake/base-config-ix.cmake
+++ b/compiler-rt/cmake/base-config-ix.cmake
@@ -290,6 +290,8 @@ macro(test_targets)
endif()
elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "nvptx")
test_target_arch(nvptx64 "" "--nvptx64-nvidia-cuda" "-nogpulib" "-flto" "-c")
+ elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "spirv64")
+ test_target_arch(spirv64 "" "--spirv64-unknown-unknown" "-nogpulib" "-flto" "-c")
elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "arm")
if(WIN32)
test_target_arch(arm "" "" "")
diff --git a/compiler-rt/cmake/config-ix.cmake b/compiler-rt/cmake/config-ix.cmake
index 9909783d7bb57..ad5497ba81b5b 100644
--- a/compiler-rt/cmake/config-ix.cmake
+++ b/compiler-rt/cmake/config-ix.cmake
@@ -894,7 +894,7 @@ endif()
if (UBSAN_SUPPORTED_ARCH AND
(OS_NAME MATCHES "Linux|FreeBSD|NetBSD|Android|Darwin|SunOS" OR
- "${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "amdgcn|nvptx"))
+ "${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "amdgcn|nvptx|spirv64"))
set(COMPILER_RT_HAS_UBSAN_MINIMAL TRUE)
else()
set(COMPILER_RT_HAS_UBSAN_MINIMAL FALSE)
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform.h
index a1f3cf799e344..2c70fb7712597 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_platform.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform.h
@@ -15,7 +15,8 @@
#if !defined(__linux__) && !defined(__FreeBSD__) && !defined(__NetBSD__) && \
!defined(__APPLE__) && !defined(_WIN32) && !defined(__Fuchsia__) && \
!(defined(__sun__) && defined(__svr4__)) && !defined(__HAIKU__) && \
- !defined(__wasi__) && !defined(__NVPTX__) && !defined(__AMDGPU__)
+ !defined(__wasi__) && !defined(__NVPTX__) && !defined(__AMDGPU__) && \
+ !defined(__SPIRV__)
# error "This operating system is not supported"
#endif
@@ -314,6 +315,12 @@
# define SANITIZER_NVPTX 0
#endif
+#if defined(__SPIRV__)
+# define SANITIZER_SPIRV 1
+#else
+# define SANITIZER_SPIRV 0
+#endif
+
// By default we allow to use SizeClassAllocator64 on 64-bit platform.
// But in some cases SizeClassAllocator64 does not work well and we need to
// fallback to SizeClassAllocator32.
diff --git a/compiler-rt/lib/ubsan_minimal/ubsan_minimal_handlers.cpp b/compiler-rt/lib/ubsan_minimal/ubsan_minimal_handlers.cpp
index 6d6638c26ce19..9a6cca3796729 100644
--- a/compiler-rt/lib/ubsan_minimal/ubsan_minimal_handlers.cpp
+++ b/compiler-rt/lib/ubsan_minimal/ubsan_minimal_handlers.cpp
@@ -13,6 +13,12 @@ template <typename... Args>
static void message(const char *msg, Args &&...args) {
fprintf(stderr, msg, args...);
}
+#elif SANITIZER_SPIRV
+extern "C" int printf(const char *fmt, ...);
+template <typename... Args>
+static void message(const char *msg, Args &&...args) {
+ printf(msg, args...);
+}
#else
#include <unistd.h>
static void message(const char *msg) { (void)write(2, msg, strlen(msg)); }
@@ -69,7 +75,7 @@ static void format_msg(const char *kind, uintptr_t caller, char *buf,
}
static void format(const char *kind, uintptr_t caller) {
-#if SANITIZER_AMDGPU || SANITIZER_NVPTX
+#if SANITIZER_AMDGPU || SANITIZER_NVPTX || SANITIZER_SPIRV
(void)format_msg;
message("ubsan: %s by %p\n", kind, reinterpret_cast<void *>(caller));
#else
@@ -151,6 +157,19 @@ static void abort_with_message(const char *kind, uintptr_t caller) {
static void abort_with_message(const char *kind, uintptr_t caller) {
__builtin_verbose_trap("ubsan", "unrecoverable error");
}
+#elif SANITIZER_SPIRV
+struct __ubsan_abort_info_t {
+ const char *fmt;
+ const char *kind;
+ const void *caller;
+};
+[[noreturn]] void __spirv_AbortKHR(__ubsan_abort_info_t info);
+[[noreturn]] static void abort_with_message(const char *kind,
+ uintptr_t caller) {
+ __ubsan_abort_info_t info = {"ubsan: %s by %p\n", kind,
+ reinterpret_cast<void *>(caller)};
+ __spirv_AbortKHR(info);
+}
#else
static void abort_with_message(const char *kind, uintptr_t caller) { abort(); }
#endif
More information about the llvm-commits
mailing list