Skip to content

[SYCL][NATIVECPU] Fix assert in MS name mangler #11103

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 19 commits into from
Oct 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
d6329e7
(SYCLNATIVECPU) fixed MS mangler assert on CC_OpenCLKernel convention
uwedolinsky Sep 7, 2023
fadb828
Merge remote-tracking branch 'origin/sycl' into uwe/msmanglingassert
uwedolinsky Sep 7, 2023
75f9f06
(SYCLNATIVECPU) handle CC_OpenCLKernel only on NativeCPU
uwedolinsky Sep 7, 2023
f9abe5d
Merge remote-tracking branch 'gitlab/uwe/msmanglingassert' into uwe/m…
uwedolinsky Sep 7, 2023
2141df3
[SYCLNATIVECPU] clang-format
uwedolinsky Sep 7, 2023
e1fb680
Merge remote-tracking branch 'gitlab/uwe/msmanglingassert' into uwe/m…
uwedolinsky Sep 7, 2023
0f13fda
Merge remote-tracking branch 'origin/sycl' into uwe/msmanglingassert
uwedolinsky Sep 7, 2023
dbea0b8
(SYCLNATIVECPU) changed cc1 invocation in new test
uwedolinsky Sep 7, 2023
0794299
Merge remote-tracking branch 'gitlab/uwe/msmanglingassert' into uwe/m…
uwedolinsky Sep 7, 2023
3529bfb
(SYCLNATIVECPU) moved mangling test
uwedolinsky Sep 8, 2023
fa0d48f
Merge remote-tracking branch 'gitlab/uwe/msmanglingassert' into uwe/m…
uwedolinsky Sep 8, 2023
a077a5d
(SYCLNATIVECPU) removed driver invocation from codegen test
uwedolinsky Sep 8, 2023
0d5063b
Merge remote-tracking branch 'gitlab/uwe/msmanglingassert' into uwe/m…
uwedolinsky Sep 8, 2023
18a1a6b
(SYCLNATIVECPU) added mangling test as frontend test
uwedolinsky Sep 8, 2023
16f9ef2
Merge remote-tracking branch 'gitlab/uwe/msmanglingassert' into uwe/m…
uwedolinsky Sep 8, 2023
025ab39
(SYCLNATIVECPU) moved mangling test to CodeGenSYCL
uwedolinsky Sep 11, 2023
f32f4e4
Merge remote-tracking branch 'gitlab/uwe/msmanglingassert' into uwe/m…
uwedolinsky Sep 11, 2023
9475b9d
(SYCLNATIVECPU) reproduced mangler assert with mock api
uwedolinsky Sep 11, 2023
d22971d
Merge remote-tracking branch 'gitlab/uwe/msmanglingassert' into uwe/m…
uwedolinsky Sep 11, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions clang/lib/AST/MicrosoftMangle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2902,6 +2902,17 @@ void MicrosoftCXXNameMangler::mangleCallingConvention(CallingConv CC) {
else
Out << "w";
break;
case CC_OpenCLKernel:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks ok to me but @premanandrao can you also please take a look?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have a lot to learn in this area. I don't understand why OpenCL is relevant for the added test case. Is OpenCL always used for -fsycl-is-native-cpu?

Mangling also seems to be missing for IA64 ABIs. See CXXNameMangler::getCallingConvQualifierName() in clang/lib/AST/ItaniumMangle.cpp. Why isn't a similar change needed there? The test exercises Linux as well.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Has anyone tried to determine what, if any, mangling is used by MSVC for OpenCL kernels?

Copy link
Contributor

@elizabethandrews elizabethandrews Sep 19, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have a lot to learn in this area. I don't understand why OpenCL is relevant for the added test case. Is OpenCL always used for -fsycl-is-native-cpu?

My understanding was that this is the calling convention for kernel. I think that when using -fsycl-is-native-cpu device compilation is done with the host triple and this results in us entering MS mangler for the kernel. @uwedolinsky did I get that correct?

Mangling also seems to be missing for IA64 ABIs. See CXXNameMangler::getCallingConvQualifierName() in clang/lib/AST/ItaniumMangle.cpp. Why isn't a similar change needed there? The test exercises Linux as well.

This is a good point. Why is this not an issue for Linux?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand why OpenCL is relevant for the added test case.

OpenCL is not relevant for this test, but since the frontend attaches the clang CC_OpenCLKernel convention (independent from C++ ABI and target) to the kernel declaration here, we need to handle that convention in the currently used name mangler (which is the MS mangler when targeting Windows).

Is OpenCL always used for -fsycl-is-native-cpu?

-fsycl-is-native-cpu does not use or enable OpenCL in compiler or runtime. NativeCPU has no dependency on OpenCL.

Mangling also seems to be missing for IA64 ABIs. See CXXNameMangler::getCallingConvQualifierName() in clang/lib/AST/ItaniumMangle.cpp. Why isn't a similar change needed there?

CXXNameMangler::getCallingConvQualifierName() already handles the CC_OpenCLKernel and other conventions here (without providing mangling), but this doesn't even seem to be called on SYCL kernels when targeting the IA64 ABI, so that problem will not occur on that ABI.

The test exercises Linux as well.

We wanted the test to also cover other ABIs and different combinations of cpu triples (for possible cross compilation) to ensure they don't have similar problems. Some of these invocations may not exercise the fix but are still worth testing.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for explaining. I think I'm convinced this change is ok.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It still isn't clear to me that this is the right change. Why is the CC_OpenCLKernel attached to SYCL kernels in the first place? Can we just stop attaching them to SYCL kernels? I think we should understand why they are needed before choosing to ignore them.

MSVC doesn't directly support the OpenCL language. From what I can tell, OpenCL kernels are always resolved by a call to clCreateKernel() that passes the name of the kernel as a string. Overloaded kernels are supported (at least by some implementations) by allowing a custom mangled name to be specified via an attribute. It seems any kind of mangling is therefore implementation dependent and thus, the Microsoft ABI doesn't specify one.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It still isn't clear to me that this is the right change. Why is the CC_OpenCLKernel attached to SYCL kernels in the first place?

Probably because of historical reasons since SYCL initially targeted OpenCL, many data structures and identifiers may have been inspired by it and SYCL kernels were implemented as OpenCL kernels. Also, querying the calling convention is one way to identify kernels.

Can we just stop attaching them to SYCL kernels?

Probably, but that would likely lead to a much larger, potentially intrusive SYCL frontend change I mentioned previously and I was trying to avoid that. If NativeCPU is the only SYCL target that has this issue, and there are no other issues elsewhere with using this convention "under the hood", it may not be worth making that large a change and instead it may be easier to just handle the assert.

MSVC doesn't directly support the OpenCL language. From what I can tell, OpenCL kernels are always resolved by a call to clCreateKernel() that passes the name of the kernel as a string. Overloaded kernels are supported (at least by some implementations) by allowing a custom mangled name to be specified via an attribute. It seems any kind of mangling is therefore implementation dependent and thus, the Microsoft ABI doesn't specify one.

Please note that this PR does not specify any MS mangling, it merely prevents the assert in the MS mangler triggered for the CC_OpenCLKernel convention.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for being responsive to my comments. I won't hold this review up further; the change seems unlikely to cause any problems in the short term. However, we will have to revisit all of this as part of the SYCL upstreaming effort as the reuse of CC_OpenCLKernel for SYCL here is quite confusing.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, if the clang infrastructure for OpenCL isn't used to implement SYCL kernels (not even when targeting OpenCL), then this "reuse" of CC_OpenCLKernel could probably be avoided. It may be possible to instead use the information from SYCLKernelAttr or other SYCL-related clang attributes that are currently attached to SYCL kernels in the AST. But such potentially larger refactoring is probably better done as a separate PR.

// This can occur on the SYCl NativeCPU device
// where device code is compiled with the same
// target triple (eg for Windows) as host code.
// FIXME: 1.) provide mangling if needed
// 2.) check if other conventions need to be handled.
if (!getASTContext().getLangOpts().SYCLIsNativeCPU)
// Currently we only allow this convention in
// SYCLNativeCPU and raise the usual error otherwise.
llvm_unreachable("Unsupported CC for mangling");
break;
}
}
void MicrosoftCXXNameMangler::mangleCallingConvention(const FunctionType *T) {
Expand Down
18 changes: 18 additions & 0 deletions clang/test/CodeGenSYCL/native_cpu_mangling.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// This test ensures the native-cpu device generates the expected kernel names,
// and that the MS mangler doesn't assert on the code below.

// RUN: %clang_cc1 -triple x86_64-pc-windows-msvc -aux-triple x86_64-pc-windows-msvc -I %S/Inputs -fsycl-is-device -fsycl-is-native-cpu -emit-llvm -o - -x c++ %s | FileCheck %s
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -aux-triple x86_64-unknown-linux-gnu -I %S/Inputs -fsycl-is-device -fsycl-is-native-cpu -emit-llvm -o - -x c++ %s | FileCheck %s
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -aux-triple x86_64-pc-windows-msvc -I %S/Inputs -fsycl-is-device -fsycl-is-native-cpu -emit-llvm -o - -x c++ %s | FileCheck %s
// RUN: %clang_cc1 -triple x86_64-pc-windows-msvc -aux-triple x86_64-unknown-linux-gnu -I %S/Inputs -fsycl-is-device -fsycl-is-native-cpu -emit-llvm -o - -x c++ %s | FileCheck %s
// Todo: check other cpus

#include "sycl.hpp"

struct name1;

void test(sycl::handler &h) {
h.parallel_for_work_group<name1>(sycl::range<1>(2),sycl::range<1>(1), [=](sycl::group<1> G) {});
}

// CHECK: void @_ZTS5name1(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

_ZTS5name1 is an Itanium mangled name. Shouldn't there be a check for a Microsoft mangled name? How does this check pass on Windows?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All SYCL targets need to generate the same name for a kernel to enable lookup in different device binaries. All SYCL targets in DPC++ use the Itanium mangling for kernel names.

We still need the MS mangler fix though because when targeting NativeCPU to Windows the MS C++ ABI is used (causing the assert), but subsequently SemaSYCL generates the unique Itanium-mangled name for each kernel.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure I'm following. We generate a mangled name for the MS C++ ABI that is never used? If so, wouldn't a better fix be to skip generating such a mangled name in the first place?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure I'm following. We generate a mangled name for the MS C++ ABI that is never used? If so, wouldn't a better fix be to skip generating such a mangled name in the first place?

We were considering this but it would probably be more intrusive to query/skip/change the kernel name mangling only for NativeCPU kernels targeting Windows than just handling the CC_OpenCLKernel convention which is already in core clang. We wanted to avoid changing mangling in the core clang Windows pipeline just for NativeCPU.

Also, SemaSYCL currently always generates a "stable name" (using the Itanium mangling) irrespective of what C++ ABI is used. NativeCPU just selects that existing name - it doesn't create a new name.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to close out this thread... I've still been struggling to follow these explanations, but as mentioned elsewhere, I won't hold this review up since the change should be harmless, but we'll need to revisit this as part of SYCL upstreaming; the use of CC_OpenCLKernel in this context just doesn't make sense.