[clang] [Clang] [CUDA] Provide device-side definitions of `__cxa_[pure|deleted]_virtual()` (PR #217427)
https://github.com/Sirraide closed https://github.com/llvm/llvm-project/pull/217427 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] [CUDA] Provide device-side definitions of `__cxa_[pure|deleted]_virtual()` (PR #217427)
https://github.com/jhuber6 approved this pull request. Sure https://github.com/llvm/llvm-project/pull/217427 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] [CUDA] Provide device-side definitions of `__cxa_[pure|deleted]_virtual()` (PR #217427)
https://github.com/Sirraide edited https://github.com/llvm/llvm-project/pull/217427 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] [CUDA] Provide device-side definitions of `__cxa_[pure|deleted]_virtual()` (PR #217427)
Sirraide wrote: @jhuber6 @yxsamliu Are you fine w/ leaving any updates to the OpenMP libraries to a separate patch? https://github.com/llvm/llvm-project/pull/217427 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] [CUDA] Provide device-side definitions of `__cxa_[pure|deleted]_virtual()` (PR #217427)
Sirraide wrote: Aarch64 failures look unrelated https://github.com/llvm/llvm-project/pull/217427 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] [CUDA] Provide device-side definitions of `__cxa_[pure|deleted]_virtual()` (PR #217427)
@@ -11,7 +11,8 @@
// CHECK-NOT: class_type_info
// CHECK-DAG: @_ZTV7Derived = linkonce_odr protected unnamed_addr constant {
[3 x ptr] } { [3 x ptr] [ptr null, ptr null, ptr @_ZN7Derived3fooEv] }
-// CHECK-DAG: @_ZTV4Base = linkonce_odr protected unnamed_addr constant { [3 x
ptr] } zeroinitializer
+// CHECK-DAG: @_ZTV4Base = linkonce_odr protected unnamed_addr constant { [3 x
ptr] } { [3 x ptr] [ptr null, ptr null, ptr @__cxa_pure_virtual] }
+// CHECK-DAG: define weak{{.*}} void @__cxa_pure_virtual()
Sirraide wrote:
Done
https://github.com/llvm/llvm-project/pull/217427
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] [CUDA] Provide device-side definitions of `__cxa_[pure|deleted]_virtual()` (PR #217427)
https://github.com/Sirraide updated
https://github.com/llvm/llvm-project/pull/217427
>From 9bfbb8f727a0457c83821d453a2500371cd68377 Mon Sep 17 00:00:00 2001
From: Ambrose Leeb
Date: Wed, 19 Aug 2026 20:29:26 +0200
Subject: [PATCH 1/8] [Clang] [CUDA] Provide device-side definitions of
__cxa_[pure|deleted]_virtual()
Update our `__clang_*` headers to provide weak symbols for these like
we're already doing for HIP (in fact, I just moved those exact
definitions into a separate header that is now used for both CUDA and
HIP).
The issues that this fixes reported a `ptxas` error, but I don't think
our lit infrastructure supports checking if `ptxas` is even available in
the `PATH`, so instead, I just added a test that checks that the definitions
make it into the device-side IR.
Fixes #49183, fixes #67533.
---
clang/docs/ReleaseNotes.md| 5 +++
clang/lib/Headers/CMakeLists.txt | 1 +
.../Headers/__clang_cuda_runtime_wrapper.h| 1 +
.../Headers/__clang_gpu_device_virtual_trap.h | 39 +++
.../lib/Headers/__clang_hip_runtime_wrapper.h | 17 +---
.../test/CodeGenCUDA/pure_deleted_virtual.cu | 9 +
6 files changed, 56 insertions(+), 16 deletions(-)
create mode 100644 clang/lib/Headers/__clang_gpu_device_virtual_trap.h
create mode 100644 clang/test/CodeGenCUDA/pure_deleted_virtual.cu
diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md
index e4a6f72f8fec5..924fe8b373808 100644
--- a/clang/docs/ReleaseNotes.md
+++ b/clang/docs/ReleaseNotes.md
@@ -548,6 +548,11 @@ features cannot lower the translation-unit ABI level;
- Added `--cuda-emit-nvcc-abi` to emit the NVCC-compatible host registration
ABI
(`__cudaRegisterLinkedBinary`).
+- Clang now provides device-side definitions of `__cxa_pure_virtual()` and
+ `__cxa_deleted_virtual()`; previously, any (potential) call to a pure/deleted
+ virtual function that could not be optimised out would cause the program to
+ fail to assemble. This is now fixed. (#GH49183) (#GH67533)
+
AIX Support
NetBSD Support
diff --git a/clang/lib/Headers/CMakeLists.txt b/clang/lib/Headers/CMakeLists.txt
index 21b6eb5e38052..cb6567c22f0cd 100644
--- a/clang/lib/Headers/CMakeLists.txt
+++ b/clang/lib/Headers/CMakeLists.txt
@@ -311,6 +311,7 @@ set(gpu_files
__clang_gpu_device_functions.h
__clang_gpu_intrinsics.h
__clang_gpu_runtime_wrapper.h
+ __clang_gpu_device_virtual_trap.h
)
set(gpu_hip_wrapper_files
diff --git a/clang/lib/Headers/__clang_cuda_runtime_wrapper.h
b/clang/lib/Headers/__clang_cuda_runtime_wrapper.h
index 29178bf0db8a1..efd5016c2847d 100644
--- a/clang/lib/Headers/__clang_cuda_runtime_wrapper.h
+++ b/clang/lib/Headers/__clang_cuda_runtime_wrapper.h
@@ -491,6 +491,7 @@ __device__ inline __cuda_builtin_gridDim_t::operator
uint3() const {
#include <__clang_cuda_cmath.h>
#include <__clang_cuda_intrinsics.h>
#include <__clang_cuda_complex_builtins.h>
+#include <__clang_gpu_device_virtual_trap.h>
// curand_mtgp32_kernel helpfully redeclares blockDim and threadIdx in host
// mode, giving them their "proper" types of dim3 and uint3. This is
diff --git a/clang/lib/Headers/__clang_gpu_device_virtual_trap.h
b/clang/lib/Headers/__clang_gpu_device_virtual_trap.h
new file mode 100644
index 0..0f212d7bc3994
--- /dev/null
+++ b/clang/lib/Headers/__clang_gpu_device_virtual_trap.h
@@ -0,0 +1,39 @@
+//=== __clang_gpu_device_virtual_trap.h - Virtual Trap Functions
===
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+// This file provides device-side definitions of __cxa_pure_virtual() and
+// __cxa_deleted_virtual().
+//
+//===--===//
+
+#ifndef __CLANG_GPU_DEVICE_VIRTUAL_TRAP_H__
+#define __CLANG_GPU_DEVICE_VIRTUAL_TRAP_H__
+
+#if defined(__CUDA__) || defined(__HIP__)
+
+#ifdef __cplusplus
+extern "C" {
+__attribute__((__visibility__("default")))
+__attribute__((weak))
+__attribute__((noreturn))
+__device__ void __cxa_pure_virtual(void) {
+ __builtin_trap();
+}
+
+__attribute__((__visibility__("default")))
+__attribute__((weak))
+__attribute__((noreturn))
+__device__ void __cxa_deleted_virtual(void) {
+ __builtin_trap();
+}
+} // extern "C"
+#endif //__cplusplus
+
+#endif // defined(__HIP__) || defined(__CUDA__)
+
+#endif // __CLANG_GPU_DEVICE_VIRTUAL_TRAP_H__
diff --git a/clang/lib/Headers/__clang_hip_runtime_wrapper.h
b/clang/lib/Headers/__clang_hip_runtime_wrapper.h
index 4b8cffd86f044..a94acf375b20e 100644
--- a/clang/lib/Headers/__clang_hip_runtime_wrapper.h
+++ b/clang/lib/Headers/__clang_hip_runtime_wrapper.h
@@ -32,22 +32,7 @@
#define nullptr NULL;
#endif
-#ifdef __cplusplus
-extern "C" {
-
[clang] [Clang] [CUDA] Provide device-side definitions of `__cxa_[pure|deleted]_virtual()` (PR #217427)
@@ -829,18 +829,33 @@ void CodeGenVTables::addVTableComponent(ConstantArrayBuilder &builder, if (RelativeCXXABIVTables) return llvm::ConstantPointerNull::get(CGM.GlobalsInt8PtrTy); - // For NVPTX devices in OpenMP emit special functon as null pointers, - // otherwise linking ends up with unresolved references. - if (CGM.getLangOpts().OpenMP && CGM.getLangOpts().OpenMPIsTargetDevice && - CGM.getTriple().isNVPTX()) -return llvm::ConstantPointerNull::get(CGM.GlobalsInt8PtrTy); llvm::FunctionType *fnTy = llvm::FunctionType::get(CGM.VoidTy, /*isVarArg=*/false); - llvm::Constant *fn = cast( + auto *F = cast( CGM.CreateRuntimeFunction(fnTy, name).getCallee()); - if (auto f = dyn_cast(fn)) -f->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global); - return fn; + F->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global); + + // The Microsoft ABI uses the same function name for pure and deleted + // virtual functions. + if (!F->empty()) +return F; + + // For NVPTX devices in OpenMP and CUDA, provide a weak definition that + // traps, otherwise linking ends up with unresolved references. + if ((CGM.getLangOpts().OpenMP && Sirraide wrote: Ok, did that and I also added a RUN line for HIP. https://github.com/llvm/llvm-project/pull/217427 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] [CUDA] Provide device-side definitions of `__cxa_[pure|deleted]_virtual()` (PR #217427)
https://github.com/Sirraide updated
https://github.com/llvm/llvm-project/pull/217427
>From 9bfbb8f727a0457c83821d453a2500371cd68377 Mon Sep 17 00:00:00 2001
From: Ambrose Leeb
Date: Wed, 19 Aug 2026 20:29:26 +0200
Subject: [PATCH 1/6] [Clang] [CUDA] Provide device-side definitions of
__cxa_[pure|deleted]_virtual()
Update our `__clang_*` headers to provide weak symbols for these like
we're already doing for HIP (in fact, I just moved those exact
definitions into a separate header that is now used for both CUDA and
HIP).
The issues that this fixes reported a `ptxas` error, but I don't think
our lit infrastructure supports checking if `ptxas` is even available in
the `PATH`, so instead, I just added a test that checks that the definitions
make it into the device-side IR.
Fixes #49183, fixes #67533.
---
clang/docs/ReleaseNotes.md| 5 +++
clang/lib/Headers/CMakeLists.txt | 1 +
.../Headers/__clang_cuda_runtime_wrapper.h| 1 +
.../Headers/__clang_gpu_device_virtual_trap.h | 39 +++
.../lib/Headers/__clang_hip_runtime_wrapper.h | 17 +---
.../test/CodeGenCUDA/pure_deleted_virtual.cu | 9 +
6 files changed, 56 insertions(+), 16 deletions(-)
create mode 100644 clang/lib/Headers/__clang_gpu_device_virtual_trap.h
create mode 100644 clang/test/CodeGenCUDA/pure_deleted_virtual.cu
diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md
index e4a6f72f8fec5..924fe8b373808 100644
--- a/clang/docs/ReleaseNotes.md
+++ b/clang/docs/ReleaseNotes.md
@@ -548,6 +548,11 @@ features cannot lower the translation-unit ABI level;
- Added `--cuda-emit-nvcc-abi` to emit the NVCC-compatible host registration
ABI
(`__cudaRegisterLinkedBinary`).
+- Clang now provides device-side definitions of `__cxa_pure_virtual()` and
+ `__cxa_deleted_virtual()`; previously, any (potential) call to a pure/deleted
+ virtual function that could not be optimised out would cause the program to
+ fail to assemble. This is now fixed. (#GH49183) (#GH67533)
+
AIX Support
NetBSD Support
diff --git a/clang/lib/Headers/CMakeLists.txt b/clang/lib/Headers/CMakeLists.txt
index 21b6eb5e38052..cb6567c22f0cd 100644
--- a/clang/lib/Headers/CMakeLists.txt
+++ b/clang/lib/Headers/CMakeLists.txt
@@ -311,6 +311,7 @@ set(gpu_files
__clang_gpu_device_functions.h
__clang_gpu_intrinsics.h
__clang_gpu_runtime_wrapper.h
+ __clang_gpu_device_virtual_trap.h
)
set(gpu_hip_wrapper_files
diff --git a/clang/lib/Headers/__clang_cuda_runtime_wrapper.h
b/clang/lib/Headers/__clang_cuda_runtime_wrapper.h
index 29178bf0db8a1..efd5016c2847d 100644
--- a/clang/lib/Headers/__clang_cuda_runtime_wrapper.h
+++ b/clang/lib/Headers/__clang_cuda_runtime_wrapper.h
@@ -491,6 +491,7 @@ __device__ inline __cuda_builtin_gridDim_t::operator
uint3() const {
#include <__clang_cuda_cmath.h>
#include <__clang_cuda_intrinsics.h>
#include <__clang_cuda_complex_builtins.h>
+#include <__clang_gpu_device_virtual_trap.h>
// curand_mtgp32_kernel helpfully redeclares blockDim and threadIdx in host
// mode, giving them their "proper" types of dim3 and uint3. This is
diff --git a/clang/lib/Headers/__clang_gpu_device_virtual_trap.h
b/clang/lib/Headers/__clang_gpu_device_virtual_trap.h
new file mode 100644
index 0..0f212d7bc3994
--- /dev/null
+++ b/clang/lib/Headers/__clang_gpu_device_virtual_trap.h
@@ -0,0 +1,39 @@
+//=== __clang_gpu_device_virtual_trap.h - Virtual Trap Functions
===
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+// This file provides device-side definitions of __cxa_pure_virtual() and
+// __cxa_deleted_virtual().
+//
+//===--===//
+
+#ifndef __CLANG_GPU_DEVICE_VIRTUAL_TRAP_H__
+#define __CLANG_GPU_DEVICE_VIRTUAL_TRAP_H__
+
+#if defined(__CUDA__) || defined(__HIP__)
+
+#ifdef __cplusplus
+extern "C" {
+__attribute__((__visibility__("default")))
+__attribute__((weak))
+__attribute__((noreturn))
+__device__ void __cxa_pure_virtual(void) {
+ __builtin_trap();
+}
+
+__attribute__((__visibility__("default")))
+__attribute__((weak))
+__attribute__((noreturn))
+__device__ void __cxa_deleted_virtual(void) {
+ __builtin_trap();
+}
+} // extern "C"
+#endif //__cplusplus
+
+#endif // defined(__HIP__) || defined(__CUDA__)
+
+#endif // __CLANG_GPU_DEVICE_VIRTUAL_TRAP_H__
diff --git a/clang/lib/Headers/__clang_hip_runtime_wrapper.h
b/clang/lib/Headers/__clang_hip_runtime_wrapper.h
index 4b8cffd86f044..a94acf375b20e 100644
--- a/clang/lib/Headers/__clang_hip_runtime_wrapper.h
+++ b/clang/lib/Headers/__clang_hip_runtime_wrapper.h
@@ -32,22 +32,7 @@
#define nullptr NULL;
#endif
-#ifdef __cplusplus
-extern "C" {
-
[clang] [Clang] [CUDA] Provide device-side definitions of `__cxa_[pure|deleted]_virtual()` (PR #217427)
@@ -829,18 +829,33 @@ void CodeGenVTables::addVTableComponent(ConstantArrayBuilder &builder, if (RelativeCXXABIVTables) return llvm::ConstantPointerNull::get(CGM.GlobalsInt8PtrTy); - // For NVPTX devices in OpenMP emit special functon as null pointers, - // otherwise linking ends up with unresolved references. - if (CGM.getLangOpts().OpenMP && CGM.getLangOpts().OpenMPIsTargetDevice && - CGM.getTriple().isNVPTX()) -return llvm::ConstantPointerNull::get(CGM.GlobalsInt8PtrTy); llvm::FunctionType *fnTy = llvm::FunctionType::get(CGM.VoidTy, /*isVarArg=*/false); - llvm::Constant *fn = cast( + auto *F = cast( CGM.CreateRuntimeFunction(fnTy, name).getCallee()); - if (auto f = dyn_cast(fn)) -f->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global); - return fn; + F->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global); + + // The Microsoft ABI uses the same function name for pure and deleted + // virtual functions. + if (!F->empty()) +return F; + + // For NVPTX devices in OpenMP and CUDA, provide a weak definition that + // traps, otherwise linking ends up with unresolved references. + if ((CGM.getLangOpts().OpenMP && Sirraide wrote: Found `LangOptions::isTargetDevice()`; I’ll use that https://github.com/llvm/llvm-project/pull/217427 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] [CUDA] Provide device-side definitions of `__cxa_[pure|deleted]_virtual()` (PR #217427)
Sirraide wrote: Added codegen for these functions; this patch now uses a helper that I’m adding in a separate NFC patch (#221022), so CI will fail until that patch is merged. https://github.com/llvm/llvm-project/pull/217427 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] [CUDA] Provide device-side definitions of `__cxa_[pure|deleted]_virtual()` (PR #217427)
https://github.com/Sirraide updated
https://github.com/llvm/llvm-project/pull/217427
>From 9bfbb8f727a0457c83821d453a2500371cd68377 Mon Sep 17 00:00:00 2001
From: Ambrose Leeb
Date: Wed, 19 Aug 2026 20:29:26 +0200
Subject: [PATCH 1/4] [Clang] [CUDA] Provide device-side definitions of
__cxa_[pure|deleted]_virtual()
Update our `__clang_*` headers to provide weak symbols for these like
we're already doing for HIP (in fact, I just moved those exact
definitions into a separate header that is now used for both CUDA and
HIP).
The issues that this fixes reported a `ptxas` error, but I don't think
our lit infrastructure supports checking if `ptxas` is even available in
the `PATH`, so instead, I just added a test that checks that the definitions
make it into the device-side IR.
Fixes #49183, fixes #67533.
---
clang/docs/ReleaseNotes.md| 5 +++
clang/lib/Headers/CMakeLists.txt | 1 +
.../Headers/__clang_cuda_runtime_wrapper.h| 1 +
.../Headers/__clang_gpu_device_virtual_trap.h | 39 +++
.../lib/Headers/__clang_hip_runtime_wrapper.h | 17 +---
.../test/CodeGenCUDA/pure_deleted_virtual.cu | 9 +
6 files changed, 56 insertions(+), 16 deletions(-)
create mode 100644 clang/lib/Headers/__clang_gpu_device_virtual_trap.h
create mode 100644 clang/test/CodeGenCUDA/pure_deleted_virtual.cu
diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md
index e4a6f72f8fec5..924fe8b373808 100644
--- a/clang/docs/ReleaseNotes.md
+++ b/clang/docs/ReleaseNotes.md
@@ -548,6 +548,11 @@ features cannot lower the translation-unit ABI level;
- Added `--cuda-emit-nvcc-abi` to emit the NVCC-compatible host registration
ABI
(`__cudaRegisterLinkedBinary`).
+- Clang now provides device-side definitions of `__cxa_pure_virtual()` and
+ `__cxa_deleted_virtual()`; previously, any (potential) call to a pure/deleted
+ virtual function that could not be optimised out would cause the program to
+ fail to assemble. This is now fixed. (#GH49183) (#GH67533)
+
AIX Support
NetBSD Support
diff --git a/clang/lib/Headers/CMakeLists.txt b/clang/lib/Headers/CMakeLists.txt
index 21b6eb5e38052..cb6567c22f0cd 100644
--- a/clang/lib/Headers/CMakeLists.txt
+++ b/clang/lib/Headers/CMakeLists.txt
@@ -311,6 +311,7 @@ set(gpu_files
__clang_gpu_device_functions.h
__clang_gpu_intrinsics.h
__clang_gpu_runtime_wrapper.h
+ __clang_gpu_device_virtual_trap.h
)
set(gpu_hip_wrapper_files
diff --git a/clang/lib/Headers/__clang_cuda_runtime_wrapper.h
b/clang/lib/Headers/__clang_cuda_runtime_wrapper.h
index 29178bf0db8a1..efd5016c2847d 100644
--- a/clang/lib/Headers/__clang_cuda_runtime_wrapper.h
+++ b/clang/lib/Headers/__clang_cuda_runtime_wrapper.h
@@ -491,6 +491,7 @@ __device__ inline __cuda_builtin_gridDim_t::operator
uint3() const {
#include <__clang_cuda_cmath.h>
#include <__clang_cuda_intrinsics.h>
#include <__clang_cuda_complex_builtins.h>
+#include <__clang_gpu_device_virtual_trap.h>
// curand_mtgp32_kernel helpfully redeclares blockDim and threadIdx in host
// mode, giving them their "proper" types of dim3 and uint3. This is
diff --git a/clang/lib/Headers/__clang_gpu_device_virtual_trap.h
b/clang/lib/Headers/__clang_gpu_device_virtual_trap.h
new file mode 100644
index 0..0f212d7bc3994
--- /dev/null
+++ b/clang/lib/Headers/__clang_gpu_device_virtual_trap.h
@@ -0,0 +1,39 @@
+//=== __clang_gpu_device_virtual_trap.h - Virtual Trap Functions
===
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+// This file provides device-side definitions of __cxa_pure_virtual() and
+// __cxa_deleted_virtual().
+//
+//===--===//
+
+#ifndef __CLANG_GPU_DEVICE_VIRTUAL_TRAP_H__
+#define __CLANG_GPU_DEVICE_VIRTUAL_TRAP_H__
+
+#if defined(__CUDA__) || defined(__HIP__)
+
+#ifdef __cplusplus
+extern "C" {
+__attribute__((__visibility__("default")))
+__attribute__((weak))
+__attribute__((noreturn))
+__device__ void __cxa_pure_virtual(void) {
+ __builtin_trap();
+}
+
+__attribute__((__visibility__("default")))
+__attribute__((weak))
+__attribute__((noreturn))
+__device__ void __cxa_deleted_virtual(void) {
+ __builtin_trap();
+}
+} // extern "C"
+#endif //__cplusplus
+
+#endif // defined(__HIP__) || defined(__CUDA__)
+
+#endif // __CLANG_GPU_DEVICE_VIRTUAL_TRAP_H__
diff --git a/clang/lib/Headers/__clang_hip_runtime_wrapper.h
b/clang/lib/Headers/__clang_hip_runtime_wrapper.h
index 4b8cffd86f044..a94acf375b20e 100644
--- a/clang/lib/Headers/__clang_hip_runtime_wrapper.h
+++ b/clang/lib/Headers/__clang_hip_runtime_wrapper.h
@@ -32,22 +32,7 @@
#define nullptr NULL;
#endif
-#ifdef __cplusplus
-extern "C" {
-
[clang] [Clang] [CUDA] Provide device-side definitions of `__cxa_[pure|deleted]_virtual()` (PR #217427)
@@ -0,0 +1,9 @@ +// RUN: %clang --cuda-device-only -S -emit-llvm -o - %s 2>&1 | FileCheck %s Sirraide wrote: So see the latest comments by myself and @jhuber6 in case you missed them, but tl;dr I’m going to change these defintions to be emitted by CodeGen instead, so the new header won’t be needed anymore, and at that point I can change this back to being a -cc1 command line https://github.com/llvm/llvm-project/pull/217427 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] [CUDA] Provide device-side definitions of `__cxa_[pure|deleted]_virtual()` (PR #217427)
@@ -0,0 +1,9 @@ +// RUN: %clang --cuda-device-only -S -emit-llvm -o - %s 2>&1 | FileCheck %s yxsamliu wrote: This test currently fails when CUDA is not installed. Could you use `%clang_cc1` with the mocked CUDA headers, like the existing tests under `clang/test/Headers`? It would also be good to include a small pure/deleted virtual class and check that the functions call `llvm.trap`. https://github.com/llvm/llvm-project/pull/217427 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] [CUDA] Provide device-side definitions of `__cxa_[pure|deleted]_virtual()` (PR #217427)
@@ -311,6 +311,7 @@ set(gpu_files __clang_gpu_device_functions.h __clang_gpu_intrinsics.h __clang_gpu_runtime_wrapper.h + __clang_gpu_device_virtual_trap.h yxsamliu wrote: Please also add this new header to `llvm/utils/gn/secondary/clang/lib/Headers/BUILD.gn`. Otherwise, GN builds will not install it. https://github.com/llvm/llvm-project/pull/217427 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] [CUDA] Provide device-side definitions of `__cxa_[pure|deleted]_virtual()` (PR #217427)
Sirraide wrote: @jhuber6 I’m not sure who to ping regarding OpenMP, but it might make sense to also emit these definitions for OpenMP instead of doing something different for OpenMP vs CUDA https://github.com/llvm/llvm-project/pull/217427 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] [CUDA] Provide device-side definitions of `__cxa_[pure|deleted]_virtual()` (PR #217427)
Sirraide wrote: > I think we should just change the emission in `clang` for these targets to > instead be a verbose trap for all similar 'GPU' targets. What do you think? > Possibly just a weak function of the same name so that it can still be > overridden by a 'real' GPU libc++abi. So have clang emit a weak definition of `__cxa_pure_virtual`/`__cxa_deleted_virtual` in device code? That’s what I was going to do but I wasn’t sure if we wanted to go in that direction. But yes, that would also solve the issue of not being able to test this properly w/o including the header (and thereby, these definitions), so I think I’ll do that if no-one is opposed to this approach https://github.com/llvm/llvm-project/pull/217427 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] [CUDA] Provide device-side definitions of `__cxa_[pure|deleted]_virtual()` (PR #217427)
llvmorg-github-actions[bot] wrote:
@llvm/pr-subscribers-backend-x86
Author: Ambrose Leeb (Sirraide)
Changes
Currently, we don't provide definitions of these on the device side, and since
there is also no C++ runtime on the device side, if a call to a pure or deleted
virtual function makes it into the final IR, the program will fail to assemble
because `ptxas` can’t find a definition of `__cxa_pure_virtual()` or
`__cxa_deleted_virtual()`.
This patch updates our `__clang_*` headers to provide weak symbols for these
like we're already doing for HIP (in fact, I just moved those exact definitions
into a separate header that is now used for both CUDA and HIP).
I don't think our lit infrastructure supports checking if `ptxas` is even
available in the `PATH`, so instead, I just added a test that checks that the
definitions make it into the device-side IR.
Fixes #49183, fixes #67533.
---
Full diff: https://github.com/llvm/llvm-project/pull/217427.diff
6 Files Affected:
- (modified) clang/docs/ReleaseNotes.md (+5)
- (modified) clang/lib/Headers/CMakeLists.txt (+1)
- (modified) clang/lib/Headers/__clang_cuda_runtime_wrapper.h (+1)
- (added) clang/lib/Headers/__clang_gpu_device_virtual_trap.h (+39)
- (modified) clang/lib/Headers/__clang_hip_runtime_wrapper.h (+1-16)
- (added) clang/test/CodeGenCUDA/pure_deleted_virtual.cu (+9)
``diff
diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md
index e4a6f72f8fec5..924fe8b373808 100644
--- a/clang/docs/ReleaseNotes.md
+++ b/clang/docs/ReleaseNotes.md
@@ -548,6 +548,11 @@ features cannot lower the translation-unit ABI level;
- Added `--cuda-emit-nvcc-abi` to emit the NVCC-compatible host registration
ABI
(`__cudaRegisterLinkedBinary`).
+- Clang now provides device-side definitions of `__cxa_pure_virtual()` and
+ `__cxa_deleted_virtual()`; previously, any (potential) call to a pure/deleted
+ virtual function that could not be optimised out would cause the program to
+ fail to assemble. This is now fixed. (#GH49183) (#GH67533)
+
AIX Support
NetBSD Support
diff --git a/clang/lib/Headers/CMakeLists.txt b/clang/lib/Headers/CMakeLists.txt
index 21b6eb5e38052..cb6567c22f0cd 100644
--- a/clang/lib/Headers/CMakeLists.txt
+++ b/clang/lib/Headers/CMakeLists.txt
@@ -311,6 +311,7 @@ set(gpu_files
__clang_gpu_device_functions.h
__clang_gpu_intrinsics.h
__clang_gpu_runtime_wrapper.h
+ __clang_gpu_device_virtual_trap.h
)
set(gpu_hip_wrapper_files
diff --git a/clang/lib/Headers/__clang_cuda_runtime_wrapper.h
b/clang/lib/Headers/__clang_cuda_runtime_wrapper.h
index 29178bf0db8a1..efd5016c2847d 100644
--- a/clang/lib/Headers/__clang_cuda_runtime_wrapper.h
+++ b/clang/lib/Headers/__clang_cuda_runtime_wrapper.h
@@ -491,6 +491,7 @@ __device__ inline __cuda_builtin_gridDim_t::operator
uint3() const {
#include <__clang_cuda_cmath.h>
#include <__clang_cuda_intrinsics.h>
#include <__clang_cuda_complex_builtins.h>
+#include <__clang_gpu_device_virtual_trap.h>
// curand_mtgp32_kernel helpfully redeclares blockDim and threadIdx in host
// mode, giving them their "proper" types of dim3 and uint3. This is
diff --git a/clang/lib/Headers/__clang_gpu_device_virtual_trap.h
b/clang/lib/Headers/__clang_gpu_device_virtual_trap.h
new file mode 100644
index 0..0f212d7bc3994
--- /dev/null
+++ b/clang/lib/Headers/__clang_gpu_device_virtual_trap.h
@@ -0,0 +1,39 @@
+//=== __clang_gpu_device_virtual_trap.h - Virtual Trap Functions
===
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+// This file provides device-side definitions of __cxa_pure_virtual() and
+// __cxa_deleted_virtual().
+//
+//===--===//
+
+#ifndef __CLANG_GPU_DEVICE_VIRTUAL_TRAP_H__
+#define __CLANG_GPU_DEVICE_VIRTUAL_TRAP_H__
+
+#if defined(__CUDA__) || defined(__HIP__)
+
+#ifdef __cplusplus
+extern "C" {
+__attribute__((__visibility__("default")))
+__attribute__((weak))
+__attribute__((noreturn))
+__device__ void __cxa_pure_virtual(void) {
+ __builtin_trap();
+}
+
+__attribute__((__visibility__("default")))
+__attribute__((weak))
+__attribute__((noreturn))
+__device__ void __cxa_deleted_virtual(void) {
+ __builtin_trap();
+}
+} // extern "C"
+#endif //__cplusplus
+
+#endif // defined(__HIP__) || defined(__CUDA__)
+
+#endif // __CLANG_GPU_DEVICE_VIRTUAL_TRAP_H__
diff --git a/clang/lib/Headers/__clang_hip_runtime_wrapper.h
b/clang/lib/Headers/__clang_hip_runtime_wrapper.h
index 4b8cffd86f044..a94acf375b20e 100644
--- a/clang/lib/Headers/__clang_hip_runtime_wrapper.h
+++ b/clang/lib/Headers/__clang_hip_runtime_wrapper.h
@@ -32,22 +32,7 @@
#define nullptr NULL;
#endif
-#ifdef __cplusplus
-extern "C" {
-
[clang] [Clang] [CUDA] Provide device-side definitions of `__cxa_[pure|deleted]_virtual()` (PR #217427)
github-actions[bot] wrote:
:warning: C/C++ code formatter, clang-format found issues in your code.
:warning:
You can test this locally with the following command:
``bash
git-clang-format --diff origin/main HEAD --extensions h --
clang/lib/Headers/__clang_gpu_device_virtual_trap.h
clang/lib/Headers/__clang_cuda_runtime_wrapper.h
clang/lib/Headers/__clang_hip_runtime_wrapper.h --diff_from_common_commit
``
:warning:
The reproduction instructions above might return results for more than one PR
in a stack if you are using a stacked PR workflow. You can limit the results by
changing `origin/main` to the base branch/commit you want to compare against.
:warning:
View the diff from clang-format here.
``diff
diff --git a/clang/lib/Headers/__clang_cuda_runtime_wrapper.h
b/clang/lib/Headers/__clang_cuda_runtime_wrapper.h
index efd5016c2..82cb1f6d5 100644
--- a/clang/lib/Headers/__clang_cuda_runtime_wrapper.h
+++ b/clang/lib/Headers/__clang_cuda_runtime_wrapper.h
@@ -489,8 +489,8 @@ __device__ inline __cuda_builtin_gridDim_t::operator
uint3() const {
}
#include <__clang_cuda_cmath.h>
-#include <__clang_cuda_intrinsics.h>
#include <__clang_cuda_complex_builtins.h>
+#include <__clang_cuda_intrinsics.h>
#include <__clang_gpu_device_virtual_trap.h>
// curand_mtgp32_kernel helpfully redeclares blockDim and threadIdx in host
diff --git a/clang/lib/Headers/__clang_gpu_device_virtual_trap.h
b/clang/lib/Headers/__clang_gpu_device_virtual_trap.h
index 0f212d7bc..f7c92e305 100644
--- a/clang/lib/Headers/__clang_gpu_device_virtual_trap.h
+++ b/clang/lib/Headers/__clang_gpu_device_virtual_trap.h
@@ -18,17 +18,15 @@
#ifdef __cplusplus
extern "C" {
-__attribute__((__visibility__("default")))
-__attribute__((weak))
-__attribute__((noreturn))
-__device__ void __cxa_pure_virtual(void) {
+__attribute__((__visibility__("default"))) __attribute__((weak))
+__attribute__((noreturn)) __device__ void
+__cxa_pure_virtual(void) {
__builtin_trap();
}
-__attribute__((__visibility__("default")))
-__attribute__((weak))
-__attribute__((noreturn))
-__device__ void __cxa_deleted_virtual(void) {
+__attribute__((__visibility__("default"))) __attribute__((weak))
+__attribute__((noreturn)) __device__ void
+__cxa_deleted_virtual(void) {
__builtin_trap();
}
} // extern "C"
``
https://github.com/llvm/llvm-project/pull/217427
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] [CUDA] Provide device-side definitions of `__cxa_[pure|deleted]_virtual()` (PR #217427)
https://github.com/Sirraide updated
https://github.com/llvm/llvm-project/pull/217427
>From 9bfbb8f727a0457c83821d453a2500371cd68377 Mon Sep 17 00:00:00 2001
From: Ambrose Leeb
Date: Wed, 19 Aug 2026 20:29:26 +0200
Subject: [PATCH 1/2] [Clang] [CUDA] Provide device-side definitions of
__cxa_[pure|deleted]_virtual()
Update our `__clang_*` headers to provide weak symbols for these like
we're already doing for HIP (in fact, I just moved those exact
definitions into a separate header that is now used for both CUDA and
HIP).
The issues that this fixes reported a `ptxas` error, but I don't think
our lit infrastructure supports checking if `ptxas` is even available in
the `PATH`, so instead, I just added a test that checks that the definitions
make it into the device-side IR.
Fixes #49183, fixes #67533.
---
clang/docs/ReleaseNotes.md| 5 +++
clang/lib/Headers/CMakeLists.txt | 1 +
.../Headers/__clang_cuda_runtime_wrapper.h| 1 +
.../Headers/__clang_gpu_device_virtual_trap.h | 39 +++
.../lib/Headers/__clang_hip_runtime_wrapper.h | 17 +---
.../test/CodeGenCUDA/pure_deleted_virtual.cu | 9 +
6 files changed, 56 insertions(+), 16 deletions(-)
create mode 100644 clang/lib/Headers/__clang_gpu_device_virtual_trap.h
create mode 100644 clang/test/CodeGenCUDA/pure_deleted_virtual.cu
diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md
index e4a6f72f8fec5..924fe8b373808 100644
--- a/clang/docs/ReleaseNotes.md
+++ b/clang/docs/ReleaseNotes.md
@@ -548,6 +548,11 @@ features cannot lower the translation-unit ABI level;
- Added `--cuda-emit-nvcc-abi` to emit the NVCC-compatible host registration
ABI
(`__cudaRegisterLinkedBinary`).
+- Clang now provides device-side definitions of `__cxa_pure_virtual()` and
+ `__cxa_deleted_virtual()`; previously, any (potential) call to a pure/deleted
+ virtual function that could not be optimised out would cause the program to
+ fail to assemble. This is now fixed. (#GH49183) (#GH67533)
+
AIX Support
NetBSD Support
diff --git a/clang/lib/Headers/CMakeLists.txt b/clang/lib/Headers/CMakeLists.txt
index 21b6eb5e38052..cb6567c22f0cd 100644
--- a/clang/lib/Headers/CMakeLists.txt
+++ b/clang/lib/Headers/CMakeLists.txt
@@ -311,6 +311,7 @@ set(gpu_files
__clang_gpu_device_functions.h
__clang_gpu_intrinsics.h
__clang_gpu_runtime_wrapper.h
+ __clang_gpu_device_virtual_trap.h
)
set(gpu_hip_wrapper_files
diff --git a/clang/lib/Headers/__clang_cuda_runtime_wrapper.h
b/clang/lib/Headers/__clang_cuda_runtime_wrapper.h
index 29178bf0db8a1..efd5016c2847d 100644
--- a/clang/lib/Headers/__clang_cuda_runtime_wrapper.h
+++ b/clang/lib/Headers/__clang_cuda_runtime_wrapper.h
@@ -491,6 +491,7 @@ __device__ inline __cuda_builtin_gridDim_t::operator
uint3() const {
#include <__clang_cuda_cmath.h>
#include <__clang_cuda_intrinsics.h>
#include <__clang_cuda_complex_builtins.h>
+#include <__clang_gpu_device_virtual_trap.h>
// curand_mtgp32_kernel helpfully redeclares blockDim and threadIdx in host
// mode, giving them their "proper" types of dim3 and uint3. This is
diff --git a/clang/lib/Headers/__clang_gpu_device_virtual_trap.h
b/clang/lib/Headers/__clang_gpu_device_virtual_trap.h
new file mode 100644
index 0..0f212d7bc3994
--- /dev/null
+++ b/clang/lib/Headers/__clang_gpu_device_virtual_trap.h
@@ -0,0 +1,39 @@
+//=== __clang_gpu_device_virtual_trap.h - Virtual Trap Functions
===
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+// This file provides device-side definitions of __cxa_pure_virtual() and
+// __cxa_deleted_virtual().
+//
+//===--===//
+
+#ifndef __CLANG_GPU_DEVICE_VIRTUAL_TRAP_H__
+#define __CLANG_GPU_DEVICE_VIRTUAL_TRAP_H__
+
+#if defined(__CUDA__) || defined(__HIP__)
+
+#ifdef __cplusplus
+extern "C" {
+__attribute__((__visibility__("default")))
+__attribute__((weak))
+__attribute__((noreturn))
+__device__ void __cxa_pure_virtual(void) {
+ __builtin_trap();
+}
+
+__attribute__((__visibility__("default")))
+__attribute__((weak))
+__attribute__((noreturn))
+__device__ void __cxa_deleted_virtual(void) {
+ __builtin_trap();
+}
+} // extern "C"
+#endif //__cplusplus
+
+#endif // defined(__HIP__) || defined(__CUDA__)
+
+#endif // __CLANG_GPU_DEVICE_VIRTUAL_TRAP_H__
diff --git a/clang/lib/Headers/__clang_hip_runtime_wrapper.h
b/clang/lib/Headers/__clang_hip_runtime_wrapper.h
index 4b8cffd86f044..a94acf375b20e 100644
--- a/clang/lib/Headers/__clang_hip_runtime_wrapper.h
+++ b/clang/lib/Headers/__clang_hip_runtime_wrapper.h
@@ -32,22 +32,7 @@
#define nullptr NULL;
#endif
-#ifdef __cplusplus
-extern "C" {
-
[clang] [Clang] [CUDA] Provide device-side definitions of `__cxa_[pure|deleted]_virtual()` (PR #217427)
https://github.com/Sirraide created
https://github.com/llvm/llvm-project/pull/217427
Currently, we don't provide definitions of these on the device side, and since
there is also no C++ runtime on the device side, if a call to a pure or deleted
virtual function makes it into the final IR, the program will fail to assemble
because `ptxas` can’t find a definition of `__cxa_pure_virtual()` or
`__cxa_deleted_virtual()`.
This patch updates our `__clang_*` headers to provide weak symbols for these
like we're already doing for HIP (in fact, I just moved those exact definitions
into a separate header that is now used for both CUDA and HIP).
I don't think our lit infrastructure supports checking if `ptxas` is even
available in the `PATH`, so instead, I just added a test that checks that the
definitions make it into the device-side IR.
Fixes #49183, fixes #67533.
>From 9bfbb8f727a0457c83821d453a2500371cd68377 Mon Sep 17 00:00:00 2001
From: Ambrose Leeb
Date: Wed, 19 Aug 2026 20:29:26 +0200
Subject: [PATCH] [Clang] [CUDA] Provide device-side definitions of
__cxa_[pure|deleted]_virtual()
Update our `__clang_*` headers to provide weak symbols for these like
we're already doing for HIP (in fact, I just moved those exact
definitions into a separate header that is now used for both CUDA and
HIP).
The issues that this fixes reported a `ptxas` error, but I don't think
our lit infrastructure supports checking if `ptxas` is even available in
the `PATH`, so instead, I just added a test that checks that the definitions
make it into the device-side IR.
Fixes #49183, fixes #67533.
---
clang/docs/ReleaseNotes.md| 5 +++
clang/lib/Headers/CMakeLists.txt | 1 +
.../Headers/__clang_cuda_runtime_wrapper.h| 1 +
.../Headers/__clang_gpu_device_virtual_trap.h | 39 +++
.../lib/Headers/__clang_hip_runtime_wrapper.h | 17 +---
.../test/CodeGenCUDA/pure_deleted_virtual.cu | 9 +
6 files changed, 56 insertions(+), 16 deletions(-)
create mode 100644 clang/lib/Headers/__clang_gpu_device_virtual_trap.h
create mode 100644 clang/test/CodeGenCUDA/pure_deleted_virtual.cu
diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md
index e4a6f72f8fec5..924fe8b373808 100644
--- a/clang/docs/ReleaseNotes.md
+++ b/clang/docs/ReleaseNotes.md
@@ -548,6 +548,11 @@ features cannot lower the translation-unit ABI level;
- Added `--cuda-emit-nvcc-abi` to emit the NVCC-compatible host registration
ABI
(`__cudaRegisterLinkedBinary`).
+- Clang now provides device-side definitions of `__cxa_pure_virtual()` and
+ `__cxa_deleted_virtual()`; previously, any (potential) call to a pure/deleted
+ virtual function that could not be optimised out would cause the program to
+ fail to assemble. This is now fixed. (#GH49183) (#GH67533)
+
AIX Support
NetBSD Support
diff --git a/clang/lib/Headers/CMakeLists.txt b/clang/lib/Headers/CMakeLists.txt
index 21b6eb5e38052..cb6567c22f0cd 100644
--- a/clang/lib/Headers/CMakeLists.txt
+++ b/clang/lib/Headers/CMakeLists.txt
@@ -311,6 +311,7 @@ set(gpu_files
__clang_gpu_device_functions.h
__clang_gpu_intrinsics.h
__clang_gpu_runtime_wrapper.h
+ __clang_gpu_device_virtual_trap.h
)
set(gpu_hip_wrapper_files
diff --git a/clang/lib/Headers/__clang_cuda_runtime_wrapper.h
b/clang/lib/Headers/__clang_cuda_runtime_wrapper.h
index 29178bf0db8a1..efd5016c2847d 100644
--- a/clang/lib/Headers/__clang_cuda_runtime_wrapper.h
+++ b/clang/lib/Headers/__clang_cuda_runtime_wrapper.h
@@ -491,6 +491,7 @@ __device__ inline __cuda_builtin_gridDim_t::operator
uint3() const {
#include <__clang_cuda_cmath.h>
#include <__clang_cuda_intrinsics.h>
#include <__clang_cuda_complex_builtins.h>
+#include <__clang_gpu_device_virtual_trap.h>
// curand_mtgp32_kernel helpfully redeclares blockDim and threadIdx in host
// mode, giving them their "proper" types of dim3 and uint3. This is
diff --git a/clang/lib/Headers/__clang_gpu_device_virtual_trap.h
b/clang/lib/Headers/__clang_gpu_device_virtual_trap.h
new file mode 100644
index 0..0f212d7bc3994
--- /dev/null
+++ b/clang/lib/Headers/__clang_gpu_device_virtual_trap.h
@@ -0,0 +1,39 @@
+//=== __clang_gpu_device_virtual_trap.h - Virtual Trap Functions
===
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+// This file provides device-side definitions of __cxa_pure_virtual() and
+// __cxa_deleted_virtual().
+//
+//===--===//
+
+#ifndef __CLANG_GPU_DEVICE_VIRTUAL_TRAP_H__
+#define __CLANG_GPU_DEVICE_VIRTUAL_TRAP_H__
+
+#if defined(__CUDA__) || defined(__HIP__)
+
+#ifdef __cplusplus
+extern "C" {
+__attribute__((__visibility__("default")))
