https://github.com/aobolensk created 
https://github.com/llvm/llvm-project/pull/210882

On amdgcnspirv, __cdecl has no device-side equivalent, so it needs to be 
normalized to the device default CC to match plain function type

>From 17a63a34403b3cd2620454adf7f898f775301d0f Mon Sep 17 00:00:00 2001
From: Arseniy Obolenskiy <[email protected]>
Date: Tue, 21 Jul 2026 07:54:07 +0200
Subject: [PATCH] [clang][HIP] Normalize __cdecl on abstract function types to
 the device default CC on amdgcnspirv

On amdgcnspirv, __cdecl has no device-side equivalent, so it needs to be 
normalized to the device default CC to match plain function type
---
 clang/lib/Sema/SemaType.cpp                   | 13 +++++++
 ...mdgcnspirv-host-cconv-in-abstract-type.hip | 35 +++++++++++++++++++
 2 files changed, 48 insertions(+)
 create mode 100644 
clang/test/SemaHIP/amdgcnspirv-host-cconv-in-abstract-type.hip

diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index f7789b7475e8e..b994080a58bb4 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -8349,6 +8349,19 @@ static bool handleFunctionTypeAttr(TypeProcessingState 
&state, ParsedAttr &attr,
     return true;
 
   const FunctionType *fn = unwrapped.get();
+
+  // On amdgcnspirv, __cdecl on an abstract function type has no device-side
+  // equivalent, so normalize it to the device default CC to match an
+  // unadorned function type. Skip named decls and variadic types.
+  if (CC == CC_C && S.getLangOpts().CUDAIsDevice &&
+      S.Context.getTargetInfo().getTriple().isSPIRV() &&
+      state.getDeclarator().mayOmitIdentifier()) {
+    const auto *FnP = dyn_cast<FunctionProtoType>(fn);
+    if (!FnP || !FnP->isVariadic())
+      CC = S.Context.getDefaultCallingConvention(/*IsVariadic=*/false,
+                                                 /*IsCXXMethod=*/false);
+  }
+
   CallingConv CCOld = fn->getCallConv();
   Attr *CCAttr = getCCTypeAttr(S.Context, attr);
 
diff --git a/clang/test/SemaHIP/amdgcnspirv-host-cconv-in-abstract-type.hip 
b/clang/test/SemaHIP/amdgcnspirv-host-cconv-in-abstract-type.hip
new file mode 100644
index 0000000000000..a624edc1bf564
--- /dev/null
+++ b/clang/test/SemaHIP/amdgcnspirv-host-cconv-in-abstract-type.hip
@@ -0,0 +1,35 @@
+// RUN: %clang_cc1 %s -fcuda-is-device -std=c++17 -triple spirv32 -aux-triple 
x86_64-pc-windows-msvc -fms-extensions -verify
+// RUN: %clang_cc1 %s -fcuda-is-device -std=c++17 -triple spirv64 -aux-triple 
x86_64-pc-windows-msvc -fms-extensions -verify
+// RUN: %clang_cc1 %s -fcuda-is-device -std=c++17 -triple spirv64-amd-amdhsa 
-aux-triple x86_64-pc-windows-msvc -fms-extensions -verify
+
+// __cdecl on an abstract function type must normalize to the device default
+// so std::function<void()> matches the library specialization keyed on
+// __cdecl on amdgcnspirv Windows.
+
+// expected-no-diagnostics
+
+template <class T> struct classify_fn {
+  static constexpr int value = 0;
+};
+template <class R, class... A> struct classify_fn<R __cdecl(A...)> {
+  static constexpr int value = 1;
+};
+template <class R, class... A> struct classify_fn<R __vectorcall(A...)> {
+  static constexpr int value = 2;
+};
+template <class R> struct classify_fn<R __cdecl(int, ...)> {
+  static constexpr int value = 3;
+};
+
+// Unadorned function types resolve to the __cdecl specialization.
+static_assert(classify_fn<void()>::value == 1, "void() must match __cdecl");
+static_assert(classify_fn<int(double, char)>::value == 1,
+              "int(double,char) must match __cdecl");
+
+// Variadic __cdecl keeps its own specialization, not the device default.
+static_assert(classify_fn<int __cdecl(int, ...)>::value == 3,
+              "variadic __cdecl must match its own specialization");
+
+// __vectorcall must not be folded into the device default alongside __cdecl.
+static_assert(classify_fn<void __vectorcall()>::value == 2,
+              "__vectorcall must match its own specialization, not __cdecl");

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to