From d8e0ae9a76a62bdc6117630d59bf9967ac9bb4ea Mon Sep 17 00:00:00 2001 From: Erich Keane Date: Wed, 2 Jun 2021 12:50:52 -0700 Subject: [PATCH] [SYCL] Fix __builtin_sycl_unique_stable_name to work on windows/spir In the case where the device is an itanium target, and the host is a windows target, we were getting the names wrong, since in the itanium case we filter by lambda-signature. The fix is to always filter by the signature rather than just on non-windows builds. I considered doing the reverse (that is, checking the aux-triple), but doing so would result in duplicate lambda mangling numbers (from linux reusing the same number for different signatures). --- clang/lib/AST/ASTContext.cpp | 7 +-- .../unique_stable_name_windows_diff.cpp | 44 +++++++++++++++++++ 2 files changed, 45 insertions(+), 6 deletions(-) create mode 100644 clang/test/CodeGenSYCL/unique_stable_name_windows_diff.cpp diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index e96f52920521..76f84c728bc6 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -11750,12 +11750,7 @@ unsigned ASTContext::GetSYCLKernelNamingIndex(const NamedDecl *ND) { llvm::SmallVector Decls{Set.begin(), Set.end()}; - // If we are in an itanium situation, the mangling-numbers for a lambda depend - // on the mangled signature, so sort by that. Only TargetCXXABI::Microsoft - // doesn't use the itanium mangler, and just sets the lambda mangling number - // incrementally, with no consideration to the signature. - if (Target->getCXXABI().getKind() != TargetCXXABI::Microsoft) - FilterSYCLKernelNamingDecls(RD, Decls); + FilterSYCLKernelNamingDecls(RD, Decls); llvm::sort(Decls, [](const CXXRecordDecl *LHS, const CXXRecordDecl *RHS) { return LHS->getLambdaManglingNumber() < RHS->getLambdaManglingNumber(); diff --git a/clang/test/CodeGenSYCL/unique_stable_name_windows_diff.cpp b/clang/test/CodeGenSYCL/unique_stable_name_windows_diff.cpp new file mode 100644 index 000000000000..ecdc1d50abbe --- /dev/null +++ b/clang/test/CodeGenSYCL/unique_stable_name_windows_diff.cpp @@ -0,0 +1,44 @@ +// RUN: %clang_cc1 -triple spir64-unknown-unknown-sycldevice -aux-triple x86_64-pc-windows-msvc -fsycl-is-device -disable-llvm-passes -fsycl-is-device -emit-llvm %s -o - | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-pc-windows-msvc -fsycl-is-device -disable-llvm-passes -fsycl-is-device -emit-llvm %s -o - | FileCheck %s + + +template +__attribute__((sycl_kernel)) void kernel(Func F){ + F(); +} + +template +__attribute__((sycl_kernel)) void kernel2(Func F){ + F(1); +} + +template +__attribute__((sycl_kernel)) void kernel3(Func F){ + F(1.1); +} + +int main() { + int i; + double d; + float f; + auto lambda1 = [](){}; + auto lambda2 = [](int){}; + auto lambda3 = [](double){}; + + kernel(lambda1); + kernel2(lambda2); + kernel3(lambda3); + + // Ensure the kernels are named the same between the device and host + // invocations. + (void)__builtin_sycl_unique_stable_name(decltype(lambda1)); + (void)__builtin_sycl_unique_stable_name(decltype(lambda2)); + (void)__builtin_sycl_unique_stable_name(decltype(lambda3)); + + // Make sure the following 3 are the same between the host and device compile. + // Note that these are NOT the same value as eachother, they differ by the + // signature. + // CHECK: private unnamed_addr constant [22 x i8] c"_ZTSZ4mainEUlvE10000_\00" + // CHECK: private unnamed_addr constant [22 x i8] c"_ZTSZ4mainEUliE10000_\00" + // CHECK: private unnamed_addr constant [22 x i8] c"_ZTSZ4mainEUldE10000_\00" +}