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

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.

Reference:
OpenMP 6.0 [Sec 9.6.2, page 332, line 31-33, adjust_args clause,
Restrictions]
This commit is contained in:
Fazlay Rabbi 2025-07-23 09:38:13 -07:00 committed by GitHub
parent 317dae1a7e
commit 5daaaf8d7d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 50 additions and 13 deletions

View File

@ -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
=================

View File

@ -1314,6 +1314,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
^^^^^^^^^^^^

View File

@ -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">;

View File

@ -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(),

View File

@ -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'
@ -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)
@ -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'

View File

@ -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, ...);
@ -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) \
@ -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