[compiler-rt] [compiler-rt] Enable minimal ubsan for GPU targets (PR #188289)

Joseph Huber via llvm-commits llvm-commits at lists.llvm.org
Fri Apr 3 09:08:32 PDT 2026


https://github.com/jhuber6 updated https://github.com/llvm/llvm-project/pull/188289

>From eff2347ae33f562cd729173db2bc5bdf403602a1 Mon Sep 17 00:00:00 2001
From: Joseph Huber <huberjn at outlook.com>
Date: Tue, 24 Mar 2026 10:29:08 -0500
Subject: [PATCH] [compiler-rt] Enable minimal ubsan for GPU targets

Summary:
This PR enabled the ubsan-minimal target for the GPU. This should enable
the trivial checks on the GPU-side. I had to make some changes to the
common sanitizer requirements, but I think this is reasonable
considering the common_sanitizer requires a fully hosted environment and
all we needed were the headers.

reenable
---
 compiler-rt/CMakeLists.txt                       | 16 ++++++++++++++--
 compiler-rt/cmake/Modules/AddCompilerRT.cmake    |  6 ++++++
 .../cmake/Modules/AllSupportedArchDefs.cmake     |  2 +-
 compiler-rt/cmake/caches/AMDGPU.cmake            |  3 ++-
 compiler-rt/cmake/config-ix.cmake                |  7 ++++---
 .../lib/sanitizer_common/sanitizer_platform.h    | 14 +++++++++++++-
 .../lib/ubsan_minimal/ubsan_minimal_handlers.cpp |  7 +++++--
 compiler-rt/test/ubsan_minimal/CMakeLists.txt    | 14 ++++++++++++++
 .../ubsan_minimal/TestCases/local_bounds.cpp     |  2 --
 9 files changed, 59 insertions(+), 12 deletions(-)

diff --git a/compiler-rt/CMakeLists.txt b/compiler-rt/CMakeLists.txt
index add0cf0783e66..1a5520d624cd4 100644
--- a/compiler-rt/CMakeLists.txt
+++ b/compiler-rt/CMakeLists.txt
@@ -362,6 +362,16 @@ 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")
+  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)
+  if("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "amdgcn")
+    append_list_if(COMPILER_RT_HAS_CODE_OBJECT_VERSION_FLAG
+                   "SHELL:-Xclang -mcode-object-version=none" SANITIZER_COMMON_CFLAGS)
+  endif()
+endif()
+
 if(NOT WIN32)
   append_list_if(COMPILER_RT_HAS_FPIC_FLAG -fPIC SANITIZER_COMMON_CFLAGS)
 endif()
@@ -377,7 +387,9 @@ 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()
-append_list_if(COMPILER_RT_HAS_FNO_LTO_FLAG -fno-lto SANITIZER_COMMON_CFLAGS)
+if(NOT "${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "amdgcn|nvptx")
+  append_list_if(COMPILER_RT_HAS_FNO_LTO_FLAG -fno-lto SANITIZER_COMMON_CFLAGS)
+endif()
 
 # By default do not instrument or use profdata for compiler-rt.
 if(NOT COMPILER_RT_ENABLE_PGO)
@@ -479,7 +491,7 @@ else()
   set(SANITIZER_LIMIT_FRAME_SIZE FALSE)
 endif()
 
-if(FUCHSIA OR UNIX)
+if(NOT COMPILER_RT_GPU_BUILD AND (FUCHSIA OR UNIX))
   set(SANITIZER_USE_SYMBOLS TRUE)
 else()
   set(SANITIZER_USE_SYMBOLS FALSE)
diff --git a/compiler-rt/cmake/Modules/AddCompilerRT.cmake b/compiler-rt/cmake/Modules/AddCompilerRT.cmake
index d658b7009e859..3548031735f47 100644
--- a/compiler-rt/cmake/Modules/AddCompilerRT.cmake
+++ b/compiler-rt/cmake/Modules/AddCompilerRT.cmake
@@ -185,6 +185,12 @@ function(add_compiler_rt_runtime name type)
     set(NO_LTO_FLAGS "")
   endif()
 
+  # The GPU build does not support shared libraries, just suppress them here as
+  # there is no global config for this.
+  if(COMPILER_RT_GPU_BUILD AND type MATCHES "SHARED")
+    return()
+  endif()
+
   # By default do not instrument or use profdata for compiler-rt.
   set(NO_PGO_FLAGS "")
   if(NOT COMPILER_RT_ENABLE_PGO)
diff --git a/compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake b/compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake
index 3aa037726a482..d57166b7e92fd 100644
--- a/compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake
+++ b/compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake
@@ -105,7 +105,7 @@ endif()
 set(ALL_TYSAN_SUPPORTED_ARCH ${X86_64} ${ARM64} ${S390X})
 set(ALL_UBSAN_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64} ${RISCV64}
     ${MIPS32} ${MIPS64} ${PPC64} ${S390X} ${SPARC} ${SPARCV9} ${HEXAGON}
-    ${LOONGARCH64})
+    ${LOONGARCH64} ${AMDGPU} ${NVPTX})
 if (OS_NAME MATCHES "FreeBSD")
   set(ALL_SAFESTACK_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM64})
 else()
diff --git a/compiler-rt/cmake/caches/AMDGPU.cmake b/compiler-rt/cmake/caches/AMDGPU.cmake
index 7286ec683cf13..f67d0c4c25ef2 100644
--- a/compiler-rt/cmake/caches/AMDGPU.cmake
+++ b/compiler-rt/cmake/caches/AMDGPU.cmake
@@ -6,7 +6,8 @@ set(COMPILER_RT_DEFAULT_TARGET_ONLY ON CACHE BOOL "")
 set(COMPILER_RT_BUILD_BUILTINS ON CACHE BOOL "")
 set(COMPILER_RT_BAREMETAL_BUILD ON CACHE BOOL "")
 set(COMPILER_RT_BUILD_CRT OFF CACHE BOOL "")
-set(COMPILER_RT_BUILD_SANITIZERS OFF CACHE BOOL "")
+set(COMPILER_RT_BUILD_SANITIZERS ON CACHE BOOL "")
+set(COMPILER_RT_SANITIZERS_TO_BUILD "ubsan_minimal" CACHE STRING "")
 set(COMPILER_RT_BUILD_XRAY OFF CACHE BOOL "")
 set(COMPILER_RT_BUILD_LIBFUZZER OFF CACHE BOOL "")
 set(COMPILER_RT_BUILD_PROFILE ON CACHE BOOL "")
diff --git a/compiler-rt/cmake/config-ix.cmake b/compiler-rt/cmake/config-ix.cmake
index 381e2e4b28abd..048ff06fd4a06 100644
--- a/compiler-rt/cmake/config-ix.cmake
+++ b/compiler-rt/cmake/config-ix.cmake
@@ -705,7 +705,7 @@ else()
   filter_available_targets(LSAN_COMMON_SUPPORTED_ARCH
     ${SANITIZER_COMMON_SUPPORTED_ARCH})
   filter_available_targets(UBSAN_COMMON_SUPPORTED_ARCH
-    ${SANITIZER_COMMON_SUPPORTED_ARCH})
+    ${ALL_UBSAN_SUPPORTED_ARCH})
   filter_available_targets(ASAN_SUPPORTED_ARCH ${ALL_ASAN_SUPPORTED_ARCH})
   filter_available_targets(RTSAN_SUPPORTED_ARCH ${ALL_RTSAN_SUPPORTED_ARCH})
   filter_available_targets(FUZZER_SUPPORTED_ARCH ${ALL_FUZZER_SUPPORTED_ARCH})
@@ -891,8 +891,9 @@ else()
   set(COMPILER_RT_HAS_UBSAN FALSE)
 endif()
 
-if (COMPILER_RT_HAS_SANITIZER_COMMON AND UBSAN_SUPPORTED_ARCH AND
-    OS_NAME MATCHES "Linux|FreeBSD|NetBSD|Android|Darwin|SunOS")
+if (UBSAN_SUPPORTED_ARCH AND
+    (OS_NAME MATCHES "Linux|FreeBSD|NetBSD|Android|Darwin|SunOS" OR
+     "${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "amdgcn|nvptx"))
   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 acd2da26117c3..a1f3cf799e344 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_platform.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform.h
@@ -15,7 +15,7 @@
 #if !defined(__linux__) && !defined(__FreeBSD__) && !defined(__NetBSD__) && \
     !defined(__APPLE__) && !defined(_WIN32) && !defined(__Fuchsia__) &&     \
     !(defined(__sun__) && defined(__svr4__)) && !defined(__HAIKU__) &&      \
-    !defined(__wasi__)
+    !defined(__wasi__) && !defined(__NVPTX__) && !defined(__AMDGPU__)
 #  error "This operating system is not supported"
 #endif
 
@@ -302,6 +302,18 @@
 #  define SANITIZER_LOONGARCH64 0
 #endif
 
+#if defined(__AMDGPU__)
+#  define SANITIZER_AMDGPU 1
+#else
+#  define SANITIZER_AMDGPU 0
+#endif
+
+#if defined(__NVPTX__)
+#  define SANITIZER_NVPTX 1
+#else
+#  define SANITIZER_NVPTX 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 6d1a5281b41ff..c8a72c23c9f79 100644
--- a/compiler-rt/lib/ubsan_minimal/ubsan_minimal_handlers.cpp
+++ b/compiler-rt/lib/ubsan_minimal/ubsan_minimal_handlers.cpp
@@ -3,12 +3,15 @@
 #include <stdint.h>
 #include <stdlib.h>
 #include <string.h>
-#include <unistd.h>
 
-#ifdef KERNEL_USE
+#if defined(KERNEL_USE)
 extern "C" void ubsan_message(const char *msg);
 static void message(const char *msg) { ubsan_message(msg); }
+#elif defined(SANITIZER_AMDGPU) || defined(SANITIZER_NVPTX)
+#include <stdio.h>
+static void message(const char *msg) { fprintf(stderr, "%s", msg); }
 #else
+#include <unistd.h>
 static void message(const char *msg) { (void)write(2, msg, strlen(msg)); }
 #endif
 
diff --git a/compiler-rt/test/ubsan_minimal/CMakeLists.txt b/compiler-rt/test/ubsan_minimal/CMakeLists.txt
index 5b722a15e9827..cb59304d00d07 100644
--- a/compiler-rt/test/ubsan_minimal/CMakeLists.txt
+++ b/compiler-rt/test/ubsan_minimal/CMakeLists.txt
@@ -10,8 +10,22 @@ set(UBSAN_TEST_DEPS ${SANITIZER_COMMON_LIT_TEST_DEPS})
 list(APPEND UBSAN_TEST_DEPS ubsan-minimal)
 
 foreach(arch ${UBSAN_TEST_ARCH})
+  set(UBSAN_TEST_TARGET_ARCH ${arch})
   string(TOLOWER "-${arch}-${OS_NAME}" UBSAN_TEST_CONFIG_SUFFIX)
   get_test_cc_for_arch(${arch} UBSAN_TEST_TARGET_CC UBSAN_TEST_TARGET_CFLAGS)
+
+  if(COMPILER_RT_GPU_BUILD)
+    if("${arch}" MATCHES "amdgcn")
+      list(APPEND UBSAN_TEST_TARGET_CFLAGS
+           -Wno-multi-gpu -flto -mcpu=native -nogpulib -startfiles -stdlib)
+    elseif("${arch}" MATCHES "nvptx")
+      list(APPEND UBSAN_TEST_TARGET_CFLAGS
+           -Wno-multi-gpu -flto -march=native -nogpulib -startfiles -stdlib)
+    endif()
+    list(APPEND UBSAN_TEST_TARGET_CFLAGS --target=${COMPILER_RT_DEFAULT_TARGET_TRIPLE})
+    string(REPLACE ";" " " UBSAN_TEST_TARGET_CFLAGS "${UBSAN_TEST_TARGET_CFLAGS}")
+  endif()
+
   set(CONFIG_NAME ${arch})
   if(${arch} IN_LIST CFI_SUPPORTED_ARCH)
     set(UBSAN_TEST_HAS_CFI TRUE)
diff --git a/compiler-rt/test/ubsan_minimal/TestCases/local_bounds.cpp b/compiler-rt/test/ubsan_minimal/TestCases/local_bounds.cpp
index 4b542fa639d42..f34a18a1589f1 100644
--- a/compiler-rt/test/ubsan_minimal/TestCases/local_bounds.cpp
+++ b/compiler-rt/test/ubsan_minimal/TestCases/local_bounds.cpp
@@ -3,8 +3,6 @@
 // RUN: %clangxx_min_runtime -fsanitize=local-bounds -fno-sanitize-trap=local-bounds %s -O3 -o %t && not --crash %run %t 3 2>&1 | FileCheck %s
 // RUN: %clangxx_min_runtime -fsanitize=local-bounds -fno-sanitize-trap=local-bounds -fsanitize-recover=local-bounds %s -O3 -o %t && %run %t 3 2>&1 | FileCheck %s
 
-#include <cstdlib>
-
 struct S {
   int k;
   int l;



More information about the llvm-commits mailing list