llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: Arseniy Obolenskiy (aobolensk) <details> <summary>Changes</summary> On amdgcnspirv, __cdecl has no device-side equivalent, so it needs to be normalized to the device default CC to match plain function type --- Full diff: https://github.com/llvm/llvm-project/pull/210882.diff 2 Files Affected: - (modified) clang/lib/Sema/SemaType.cpp (+13) - (added) clang/test/SemaHIP/amdgcnspirv-host-cconv-in-abstract-type.hip (+35) ``````````diff 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"); `````````` </details> https://github.com/llvm/llvm-project/pull/210882 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
