Skip to content

[OpenMP 6.0] Allow only byref arguments with need_device_addr modifier on adjust_args clause #149586

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 2 commits into from
Jul 23, 2025
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: 3 additions & 0 deletions clang/docs/OpenMPSupport.rst
Original file line number Diff line number Diff line change
Expand Up @@ -467,6 +467,9 @@ implementation.
+-------------------------------------------------------------+---------------------------+---------------------------+--------------------------------------------------------------------------+
| Non-const do_not_sync for nowait/nogroup | :none:`unclaimed` | :none:`unclaimed` | |
+-------------------------------------------------------------+---------------------------+---------------------------+--------------------------------------------------------------------------+
| need_device_addr modifier for adjust_args clause | :part:`partial` | :none:`unclaimed` | Parsing/Sema: https://github.com/llvm/llvm-project/pull/143442 |
| | | | https://github.com/llvm/llvm-project/pull/149586 |
+-------------------------------------------------------------+---------------------------+---------------------------+--------------------------------------------------------------------------+

OpenMP Extensions
=================
Expand Down
2 changes: 2 additions & 0 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1311,6 +1311,8 @@ OpenMP Support
mappers, by using compiler-generated default mappers for the outer structs for
such maps.
- Deprecation warning has been emitted for deprecated delimited form of ``declare target``.
- Added parsing and semantic analysis support for the 'need_device_addr'
modifier in the 'adjust_args' clause.

Improvements
^^^^^^^^^^^^
Expand Down
3 changes: 3 additions & 0 deletions clang/include/clang/Basic/DiagnosticParseKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -1594,6 +1594,9 @@ def err_omp_unknown_adjust_args_op
def err_omp_declare_variant_wrong_clause : Error<
"expected %select{'match'|'match', 'adjust_args', or 'append_args'}0 clause "
"on 'omp declare variant' directive">;
def err_omp_non_by_ref_need_device_addr_modifier_argument
: Error<"expected reference type argument on 'adjust_args' clause with "
"'need_device_addr' modifier">;
def err_omp_declare_variant_duplicate_nested_trait : Error<
"nested OpenMP context selector contains duplicated trait '%0'"
" in selector '%1' and set '%2' with different score">;
Expand Down
17 changes: 17 additions & 0 deletions clang/lib/Sema/SemaOpenMP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7612,6 +7612,23 @@ void SemaOpenMP::ActOnOpenMPDeclareVariantDirective(
return;
}

// OpenMP 6.0 [9.6.2 (page 332, line 31-33, adjust_args clause, Restrictions]
// If the `need_device_addr` adjust-op modifier is present, each list item
// that appears in the clause must refer to an argument in the declaration of
// the function variant that has a reference type
if (getLangOpts().OpenMP >= 60) {
for (Expr *E : AdjustArgsNeedDeviceAddr) {
E = E->IgnoreParenImpCasts();
if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) {
if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl())) {
if (!VD->getType()->isReferenceType())
Diag(E->getExprLoc(),
diag::err_omp_non_by_ref_need_device_addr_modifier_argument);
}
}
}
}

auto *NewAttr = OMPDeclareVariantAttr::CreateImplicit(
getASTContext(), VariantRef, &TI,
const_cast<Expr **>(AdjustArgsNothing.data()), AdjustArgsNothing.size(),
Expand Down
26 changes: 13 additions & 13 deletions clang/test/OpenMP/declare_variant_clauses_ast_print.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,11 @@
#ifndef HEADER
#define HEADER

void foo_v1(float *AAA, float *BBB, int *I) {return;}
void foo_v2(float *AAA, float *BBB, int *I) {return;}
void foo_v3(float *AAA, float *BBB, int *I) {return;}
void foo_v1(float *AAA, float *BBB, int &CCC, int *I) {return;}
void foo_v2(float *AAA, float *BBB, int &CCC, int *I) {return;}
void foo_v3(float *AAA, float *BBB, int &CCC, int *I) {return;}

//DUMP: FunctionDecl{{.*}} foo 'void (float *, float *, int *)'
//DUMP: FunctionDecl{{.*}} foo 'void (float *, float *, int &, int *)'
//DUMP: OMPDeclareVariantAttr{{.*}}device={arch(x86, x86_64)}
//DUMP: DeclRefExpr{{.*}}Function{{.*}}foo_v3
//DUMP: DeclRefExpr{{.*}}ParmVar{{.*}}'I'
Expand All @@ -54,9 +54,9 @@ void foo_v3(float *AAA, float *BBB, int *I) {return;}
//DUMP: DeclRefExpr{{.*}}Function{{.*}}foo_v1
//DUMP: DeclRefExpr{{.*}}ParmVar{{.*}}'AAA'
//DUMP: DeclRefExpr{{.*}}ParmVar{{.*}}'BBB'
//PRINT: #pragma omp declare variant(foo_v3) match(construct={dispatch}, device={arch(x86, x86_64)}) adjust_args(nothing:I) adjust_args(need_device_ptr:BBB) adjust_args(need_device_addr:AAA)
//PRINT: #pragma omp declare variant(foo_v3) match(construct={dispatch}, device={arch(x86, x86_64)}) adjust_args(nothing:I) adjust_args(need_device_ptr:BBB) adjust_args(need_device_addr:CCC)

//PRINT: #pragma omp declare variant(foo_v2) match(construct={dispatch}, device={arch(ppc)}) adjust_args(need_device_ptr:AAA) adjust_args(need_device_addr:BBB)
//PRINT: #pragma omp declare variant(foo_v2) match(construct={dispatch}, device={arch(ppc)}) adjust_args(need_device_ptr:AAA) adjust_args(need_device_addr:CCC)

//PRINT: omp declare variant(foo_v1) match(construct={dispatch}, device={arch(arm)}) adjust_args(need_device_ptr:AAA,BBB)

Expand All @@ -67,33 +67,33 @@ void foo_v3(float *AAA, float *BBB, int *I) {return;}
#pragma omp declare variant(foo_v2) \
match(construct={dispatch}, device={arch(ppc)}), \
adjust_args(need_device_ptr:AAA) \
adjust_args(need_device_addr:BBB)
adjust_args(need_device_addr:CCC)

#pragma omp declare variant(foo_v3) \
adjust_args(need_device_ptr:BBB) adjust_args(nothing:I) \
adjust_args(need_device_addr:AAA) \
adjust_args(need_device_addr:CCC) \
match(construct={dispatch}, device={arch(x86,x86_64)})

void foo(float *AAA, float *BBB, int *I) {return;}
void foo(float *AAA, float *BBB, int &CCC, int *I) {return;}

void Foo_Var(float *AAA, float *BBB, float *CCC) {return;}
void Foo_Var(float *AAA, float *BBB, float *&CCC) {return;}

#pragma omp declare variant(Foo_Var) \
match(construct={dispatch}, device={arch(x86_64)}) \
adjust_args(need_device_ptr:AAA) adjust_args(nothing:BBB) \
adjust_args(need_device_addr:CCC)
template<typename T>
void Foo(T *AAA, T *BBB, T *CCC) {return;}
void Foo(T *AAA, T *BBB, T *&CCC) {return;}

//PRINT: #pragma omp declare variant(Foo_Var) match(construct={dispatch}, device={arch(x86_64)}) adjust_args(nothing:BBB) adjust_args(need_device_ptr:AAA) adjust_args(need_device_addr:CCC)
//DUMP: FunctionDecl{{.*}} Foo 'void (T *, T *, T *)'
//DUMP: FunctionDecl{{.*}} Foo 'void (T *, T *, T *&)'
//DUMP: OMPDeclareVariantAttr{{.*}}device={arch(x86_64)}
//DUMP: DeclRefExpr{{.*}}Function{{.*}}Foo_Var
//DUMP: DeclRefExpr{{.*}}ParmVar{{.*}}'BBB'
//DUMP: DeclRefExpr{{.*}}ParmVar{{.*}}'AAA'
//DUMP: DeclRefExpr{{.*}}ParmVar{{.*}}'CCC'
//
//DUMP: FunctionDecl{{.*}} Foo 'void (float *, float *, float *)'
//DUMP: FunctionDecl{{.*}} Foo 'void (float *, float *, float *&)'
//DUMP: OMPDeclareVariantAttr{{.*}}device={arch(x86_64)}
//DUMP: DeclRefExpr{{.*}}Function{{.*}}Foo_Var
//DUMP: DeclRefExpr{{.*}}ParmVar{{.*}}'BBB'
Expand Down
12 changes: 12 additions & 0 deletions clang/test/OpenMP/declare_variant_clauses_messages.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ void foo_v1(float *AAA, float *BBB, int *I) { return; }
void foo_v2(float *AAA, float *BBB, int *I) { return; }
void foo_v3(float *AAA, float *BBB, int *I) { return; }
void foo_v4(float *AAA, float *BBB, int *I, omp_interop_t IOp) { return; }
void foo_v5(float *AAA, float *BBB, int I) { return; }

#if _OPENMP >= 202011 // At least OpenMP 5.1
void vararg_foo(const char *fmt, omp_interop_t it, ...);
Expand Down Expand Up @@ -129,6 +130,11 @@ void vararg_bar2(const char *fmt) { return; }
adjust_args(nothing:J) \
match(construct={dispatch}, device={arch(x86,x86_64)})

// expected-error@+2 {{expected reference type argument on 'adjust_args' clause with 'need_device_addr' modifier}}
#pragma omp declare variant(foo_v1) \
adjust_args(need_device_addr:AAA) \
match(construct={dispatch}, device={arch(x86,x86_64)})

// expected-error@+2 {{expected reference to one of the parameters of function 'foo'}}
#pragma omp declare variant(foo_v3) \
adjust_args(nothing:Other) \
Expand Down Expand Up @@ -218,6 +224,12 @@ void vararg_bar2(const char *fmt) { return; }

void foo(float *AAA, float *BBB, int *I) { return; }

// expected-error@+2 {{expected reference type argument on 'adjust_args' clause with 'need_device_addr' modifier}}
#pragma omp declare variant(foo_v5) \
adjust_args(need_device_addr:I) \
match(construct={dispatch}, device={arch(x86,x86_64)})
void foo5(float *AAA, float *BBB, int I) { return; }

#endif // NO_INTEROP_T_DEF

#ifdef C
Expand Down