[clang] [HIP][SPIRV] Implicit `new`/`delete` should be `cdecl` on host (PR #152023)
Alex Voicu via cfe-commits
cfe-commits at lists.llvm.org
Wed Aug 6 16:47:41 PDT 2025
https://github.com/AlexVlx updated https://github.com/llvm/llvm-project/pull/152023
>From e33787e50ac261d09aa9bcc7b9e25b162abb00d6 Mon Sep 17 00:00:00 2001
From: Alex Voicu <alexandru.voicu at amd.com>
Date: Mon, 4 Aug 2025 21:08:56 +0100
Subject: [PATCH 1/3] Prevent spurious CC clashes.
---
clang/lib/Sema/SemaExprCXX.cpp | 7 +++++
...v-implicit-alloc-function-calling-conv.hip | 26 +++++++++++++++++++
2 files changed, 33 insertions(+)
create mode 100644 clang/test/SemaHIP/amdgcnspirv-implicit-alloc-function-calling-conv.hip
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index 0edfd6015cbd9..5b9cd65c52099 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -3497,6 +3497,13 @@ void Sema::DeclareGlobalAllocationFunction(DeclarationName Name,
}
auto CreateAllocationFunctionDecl = [&](Attr *ExtraAttr) {
+ // The MSVC STL has explicit cdecl on its (host-side) allocation function
+ // specializations for the allocation, so in order to prevent a CC clash
+ // we set cdecl on the host-side implicit decls, knowing these do not get
+ // emitted when compiling for device.
+ if (getLangOpts().CUDAIsDevice && ExtraAttr && isa<CUDAHostAttr>(ExtraAttr)
+ && Context.getTargetInfo().getTriple().isSPIRV())
+ EPI.ExtInfo = EPI.ExtInfo.withCallingConv(CallingConv::CC_C);
QualType FnType = Context.getFunctionType(Return, Params, EPI);
FunctionDecl *Alloc = FunctionDecl::Create(
Context, GlobalCtx, SourceLocation(), SourceLocation(), Name, FnType,
diff --git a/clang/test/SemaHIP/amdgcnspirv-implicit-alloc-function-calling-conv.hip b/clang/test/SemaHIP/amdgcnspirv-implicit-alloc-function-calling-conv.hip
new file mode 100644
index 0000000000000..7e87a904054ce
--- /dev/null
+++ b/clang/test/SemaHIP/amdgcnspirv-implicit-alloc-function-calling-conv.hip
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 %s -fcuda-is-device -std=c++17 -triple spirv32 -verify
+// RUN: %clang_cc1 %s -fcuda-is-device -std=c++17 -triple spirv64 -verify
+// RUN: %clang_cc1 %s -fcuda-is-device -std=c++17 -triple spirv64-amd-amdhsa -verify
+
+// expected-no-diagnostics
+
+namespace std
+{
+ enum class align_val_t : __SIZE_TYPE__ {};
+ struct nothrow_t { explicit nothrow_t() = default; };
+ extern nothrow_t const nothrow;
+}
+
+void* __attribute__((cdecl)) operator new(__SIZE_TYPE__);
+void* __attribute__((cdecl)) operator new[](__SIZE_TYPE__);
+void* __attribute__((cdecl)) operator new(__SIZE_TYPE__, ::std::align_val_t);
+void* __attribute__((cdecl)) operator new[](__SIZE_TYPE__, ::std::align_val_t);
+
+void __attribute__((cdecl)) operator delete(void*) noexcept;
+void __attribute__((cdecl)) operator delete[](void*) noexcept;
+void __attribute__((cdecl)) operator delete(void*, __SIZE_TYPE__) noexcept;
+void __attribute__((cdecl)) operator delete[](void*, __SIZE_TYPE__) noexcept;
+void __attribute__((cdecl)) operator delete(void*, ::std::align_val_t) noexcept;
+void __attribute__((cdecl)) operator delete[](void*, ::std::align_val_t) noexcept;
+void __attribute__((cdecl)) operator delete(void*, __SIZE_TYPE__, ::std::align_val_t) noexcept;
+void __attribute__((cdecl)) operator delete[](void*, __SIZE_TYPE__, ::std::align_val_t) noexcept;
>From 1deb1be3e8dec354be5b83aa58c7c830d9268c9c Mon Sep 17 00:00:00 2001
From: Alex Voicu <alexandru.voicu at amd.com>
Date: Mon, 4 Aug 2025 21:21:21 +0100
Subject: [PATCH 2/3] Fix formatting.
---
clang/lib/Sema/SemaExprCXX.cpp | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index 5b9cd65c52099..8884f34a6f71b 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -3501,8 +3501,9 @@ void Sema::DeclareGlobalAllocationFunction(DeclarationName Name,
// specializations for the allocation, so in order to prevent a CC clash
// we set cdecl on the host-side implicit decls, knowing these do not get
// emitted when compiling for device.
- if (getLangOpts().CUDAIsDevice && ExtraAttr && isa<CUDAHostAttr>(ExtraAttr)
- && Context.getTargetInfo().getTriple().isSPIRV())
+ if (getLangOpts().CUDAIsDevice && ExtraAttr &&
+ isa<CUDAHostAttr>(ExtraAttr) &&
+ Context.getTargetInfo().getTriple().isSPIRV())
EPI.ExtInfo = EPI.ExtInfo.withCallingConv(CallingConv::CC_C);
QualType FnType = Context.getFunctionType(Return, Params, EPI);
FunctionDecl *Alloc = FunctionDecl::Create(
>From 4e2c211602535a6969fe4d67b1de1ee9828e8d22 Mon Sep 17 00:00:00 2001
From: Alex Voicu <alexandru.voicu at amd.com>
Date: Thu, 7 Aug 2025 00:47:27 +0100
Subject: [PATCH 3/3] Use target's default CC if available; extend test.
---
clang/lib/Sema/SemaExprCXX.cpp | 13 +++++++++----
...cnspirv-implicit-alloc-function-calling-conv.hip | 6 ++++++
2 files changed, 15 insertions(+), 4 deletions(-)
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index 8884f34a6f71b..9c5554173d262 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -3499,12 +3499,17 @@ void Sema::DeclareGlobalAllocationFunction(DeclarationName Name,
auto CreateAllocationFunctionDecl = [&](Attr *ExtraAttr) {
// The MSVC STL has explicit cdecl on its (host-side) allocation function
// specializations for the allocation, so in order to prevent a CC clash
- // we set cdecl on the host-side implicit decls, knowing these do not get
- // emitted when compiling for device.
+ // we use the host's CC, if available, or CC_C as a fallback, for the
+ // host-side implicit decls, knowing these do not get emitted when compiling
+ // for device.
if (getLangOpts().CUDAIsDevice && ExtraAttr &&
isa<CUDAHostAttr>(ExtraAttr) &&
- Context.getTargetInfo().getTriple().isSPIRV())
- EPI.ExtInfo = EPI.ExtInfo.withCallingConv(CallingConv::CC_C);
+ Context.getTargetInfo().getTriple().isSPIRV()) {
+ if (auto *ATI = Context.getAuxTargetInfo())
+ EPI.ExtInfo = EPI.ExtInfo.withCallingConv(ATI->getDefaultCallingConv());
+ else
+ EPI.ExtInfo = EPI.ExtInfo.withCallingConv(CallingConv::CC_C);
+ }
QualType FnType = Context.getFunctionType(Return, Params, EPI);
FunctionDecl *Alloc = FunctionDecl::Create(
Context, GlobalCtx, SourceLocation(), SourceLocation(), Name, FnType,
diff --git a/clang/test/SemaHIP/amdgcnspirv-implicit-alloc-function-calling-conv.hip b/clang/test/SemaHIP/amdgcnspirv-implicit-alloc-function-calling-conv.hip
index 7e87a904054ce..c3e7e1a5cd59e 100644
--- a/clang/test/SemaHIP/amdgcnspirv-implicit-alloc-function-calling-conv.hip
+++ b/clang/test/SemaHIP/amdgcnspirv-implicit-alloc-function-calling-conv.hip
@@ -1,6 +1,12 @@
// RUN: %clang_cc1 %s -fcuda-is-device -std=c++17 -triple spirv32 -verify
// RUN: %clang_cc1 %s -fcuda-is-device -std=c++17 -triple spirv64 -verify
// RUN: %clang_cc1 %s -fcuda-is-device -std=c++17 -triple spirv64-amd-amdhsa -verify
+// RUN: %clang_cc1 %s -fcuda-is-device -std=c++17 -triple spirv32 -aux-triple x86_64-unknown-linux-gnu -verify
+// RUN: %clang_cc1 %s -fcuda-is-device -std=c++17 -triple spirv64 -aux-triple x86_64-unknown-linux-gnu -verify
+// RUN: %clang_cc1 %s -fcuda-is-device -std=c++17 -triple spirv64-amd-amdhsa -aux-triple x86_64-unknown-linux-gnu -verify
+// RUN: %clang_cc1 %s -fcuda-is-device -std=c++17 -triple spirv32 -aux-triple x86_64-pc-windows-msvc -verify
+// RUN: %clang_cc1 %s -fcuda-is-device -std=c++17 -triple spirv64 -aux-triple x86_64-pc-windows-msvc -verify
+// RUN: %clang_cc1 %s -fcuda-is-device -std=c++17 -triple spirv64-amd-amdhsa -aux-triple x86_64-pc-windows-msvc -verify
// expected-no-diagnostics
More information about the cfe-commits
mailing list