Skip to content

[SYCL] Report Compiling error for recursion in SYCL kernel #3390

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 7 commits into from
Apr 8, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
3 changes: 0 additions & 3 deletions clang/include/clang/Basic/DiagnosticSemaKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -11293,9 +11293,6 @@ def warn_sycl_implicit_decl
"declaration for a kernel type name; your program may not "
"be portable">,
InGroup<SyclStrict>, ShowInSystemHeader, DefaultIgnore;
def warn_sycl_restrict_recursion
: Warning<"SYCL kernel cannot call a recursive function">,
InGroup<SyclStrict>, DefaultError;
def err_ivdep_duplicate_arg : Error<
"duplicate argument to 'ivdep'; attribute requires one or both of a safelen "
"and array">;
Expand Down
3 changes: 2 additions & 1 deletion clang/lib/Sema/SemaSYCL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -376,7 +376,8 @@ class MarkDeviceFunction : public RecursiveASTVisitor<MarkDeviceFunction> {
// all functions used by kernel have already been parsed and have
// definitions.
if (RecursiveSet.count(Callee) && !ConstexprDepth) {
SemaRef.Diag(e->getExprLoc(), diag::warn_sycl_restrict_recursion);
SemaRef.Diag(e->getExprLoc(), diag::err_sycl_restrict)
<< Sema::KernelCallRecursiveFunction;
SemaRef.Diag(Callee->getSourceRange().getBegin(),
diag::note_sycl_recursive_function_declared_here)
<< Sema::KernelCallRecursiveFunction;
Expand Down
2 changes: 1 addition & 1 deletion clang/test/SemaSYCL/restrict-recursion3.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ template <typename name, typename Func>
__attribute__((sycl_kernel)) void kernel_single_task2(const Func &kernelFunc) {
// expected-note@+1 {{called by 'kernel_single_task2}}
kernelFunc();
// expected-warning@+1 2{{SYCL kernel cannot call a recursive function}}
// expected-error@+1 2{{SYCL kernel cannot call a recursive function}}
Copy link
Contributor

Choose a reason for hiding this comment

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

Why is this diagnostic issued twice?

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 still curious about this.

kernel_single_task2<name, Func>(kernelFunc);
}

Expand Down
4 changes: 2 additions & 2 deletions clang/test/SemaSYCL/restrict-recursion4.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ int fib(int n) {

// expected-note@+1 2{{function implemented using recursion declared here}}
void kernel2(void) {
// expected-warning@+1 {{SYCL kernel cannot call a recursive function}}
// expected-error@+1 {{SYCL kernel cannot call a recursive function}}
kernel2();
}

Expand All @@ -24,7 +24,7 @@ void *operator new(size_t);
void usage2(myFuncDef functionPtr) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Could it be possible to add a test like

void kernel3(void) {
  if constexpr (false)
    kernel3();
  if (false)
    kernel3();
}

and verify it does not fire?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hi, @keryell
I am afraid current implementation can't handle this as we are analyzing the call graph to recognize all recursions and don't know whether the recursive call is in a "dead" branch.
Thanks very much.

Copy link
Contributor

Choose a reason for hiding this comment

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

I think it's reasonable to not diagnose recursion in dead branches, but we should still have test coverage (with comments) that show we've explicitly considered this case.

Copy link
Contributor

Choose a reason for hiding this comment

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

This comment is still unaddressed, btw.

Copy link
Contributor

Choose a reason for hiding this comment

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

@AaronBallman :Note that my patch adds a test for this. See: #3475

// expected-error@+1 {{SYCL kernel cannot allocate storage}}
int *ip = new int;
// expected-warning@+1 {{SYCL kernel cannot call a recursive function}}
// expected-error@+1 {{SYCL kernel cannot call a recursive function}}
kernel2();
}

Expand Down