Author: Nick Sarnie Date: 2025-04-18T15:28:46Z New Revision: 257b72758424f56103d38e3d016cfb6baa4da613
URL: https://github.com/llvm/llvm-project/commit/257b72758424f56103d38e3d016cfb6baa4da613 DIFF: https://github.com/llvm/llvm-project/commit/257b72758424f56103d38e3d016cfb6baa4da613.diff LOG: [clang][Sema][SYCL] Fix MSVC STL usage on AMDGPU (#135979) The MSVC STL includes specializations of `_Is_memfunptr` for every function pointer type, including every calling convention. The problem is the AMDGPU target doesn't support the x86 `vectorcall` calling convention so clang sets it to the default CC. This ends up clashing with the already-existing overload for the default CC, so we get a duplicate definition error when including `type_traits` (which we heavily use in the SYCL STL) and compiling for AMDGPU on Windows. This doesn't happen for pure AMDGPU non-SYCL because it doesn't include the C++ STL, and it doesn't happen for CUDA/HIP because a similar workaround was done [here](https://github.com/llvm/llvm-project/commit/fa49c3a888e816969b5ed68cd5c47efc3eb9419f). I am not an expert in Sema, so I did a kinda of hardcoded fix, please let me know if there is a better way to fix this. As far as I can tell we can't do exactly the same fix that was done for CUDA because we can't differentiate between device and host code so easily. --------- Signed-off-by: Sarnie, Nick <nick.sar...@intel.com> Added: clang/test/SemaSYCL/Inputs/vectorcall.hpp clang/test/SemaSYCL/sycl-cconv-win.cpp Modified: clang/lib/Sema/SemaDeclAttr.cpp Removed: ################################################################################ diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index 7dd20a8795fc9..cb230774d56fc 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -5495,12 +5495,12 @@ bool Sema::CheckCallingConvAttr(const ParsedAttr &Attrs, CallingConv &CC, TargetInfo::CallingConvCheckResult A = TargetInfo::CCCR_OK; const TargetInfo &TI = Context.getTargetInfo(); + auto *Aux = Context.getAuxTargetInfo(); // CUDA functions may have host and/or device attributes which indicate // their targeted execution environment, therefore the calling convention // of functions in CUDA should be checked against the target deduced based // on their host/device attributes. if (LangOpts.CUDA) { - auto *Aux = Context.getAuxTargetInfo(); assert(FD || CFT != CUDAFunctionTarget::InvalidTarget); auto CudaTarget = FD ? CUDA().IdentifyTarget(FD) : CFT; bool CheckHost = false, CheckDevice = false; @@ -5525,6 +5525,15 @@ bool Sema::CheckCallingConvAttr(const ParsedAttr &Attrs, CallingConv &CC, A = HostTI->checkCallingConvention(CC); if (A == TargetInfo::CCCR_OK && CheckDevice && DeviceTI) A = DeviceTI->checkCallingConvention(CC); + } else if (LangOpts.SYCLIsDevice && TI.getTriple().isAMDGPU() && + CC == CC_X86VectorCall) { + // Assuming SYCL Device AMDGPU CC_X86VectorCall functions are always to be + // emitted on the host. The MSVC STL has CC-based specializations so we + // cannot change the CC to be the default as that will cause a clash with + // another specialization. + A = TI.checkCallingConvention(CC); + if (Aux && A != TargetInfo::CCCR_OK) + A = Aux->checkCallingConvention(CC); } else { A = TI.checkCallingConvention(CC); } diff --git a/clang/test/SemaSYCL/Inputs/vectorcall.hpp b/clang/test/SemaSYCL/Inputs/vectorcall.hpp new file mode 100644 index 0000000000000..566a48dd24c30 --- /dev/null +++ b/clang/test/SemaSYCL/Inputs/vectorcall.hpp @@ -0,0 +1,18 @@ + +template <typename F> struct A{}; + +template <typename Ret, typename C, typename... Args> struct A<Ret ( C::*)(Args...) noexcept> { static constexpr int value = 0; }; +template <typename Ret, typename C, typename... Args> struct A<Ret (__vectorcall C::*)(Args...) noexcept> { static constexpr int value = 1; }; + +template <typename F> constexpr int A_v = A<F>::value; + +struct B +{ + void f() noexcept {} + void __vectorcall g() noexcept {} +}; + +int main() +{ + return A_v<decltype(&B::f)> + A_v<decltype(&B::g)>; +} diff --git a/clang/test/SemaSYCL/sycl-cconv-win.cpp b/clang/test/SemaSYCL/sycl-cconv-win.cpp new file mode 100644 index 0000000000000..f0c22a2ed3921 --- /dev/null +++ b/clang/test/SemaSYCL/sycl-cconv-win.cpp @@ -0,0 +1,5 @@ +// RUN: %clang_cc1 -isystem %S/Inputs/ -fsycl-is-device -triple amdgcn-amd-hsa -aux-triple x86_64-pc-windows-msvc -fsyntax-only -verify %s + +// expected-no-diagnostics + +#include <vectorcall.hpp> _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits