[OpenMP 6.0] Allow only byref arguments with need_device_addr modifier on adjust_args clause by mdfazlay · Pull Request #149586 · llvm/llvm-project (original) (raw)
@llvm/pr-subscribers-clang
Author: Fazlay Rabbi (mdfazlay)
Changes
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]
Full diff: https://github.com/llvm/llvm-project/pull/149586.diff
4 Files Affected:
- (modified) clang/include/clang/Basic/DiagnosticParseKinds.td (+3)
- (modified) clang/lib/Sema/SemaOpenMP.cpp (+15)
- (modified) clang/test/OpenMP/declare_variant_clauses_ast_print.cpp (+13-13)
- (modified) clang/test/OpenMP/declare_variant_clauses_messages.cpp (+12)
diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td index 35903af998fbe..165f01514e2b1 100644 --- a/clang/include/clang/Basic/DiagnosticParseKinds.td +++ b/clang/include/clang/Basic/DiagnosticParseKinds.td @@ -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">; diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index 4ecc9b0d4c5c8..a26f8f1691435 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -7612,6 +7612,21 @@ void SemaOpenMP::ActOnOpenMPDeclareVariantDirective( return; }
- // OpenMP 6.0 [9.6.2 (page 332, line 31-33, adjust_args clause, Restrictions]
- // If the
need_device_addradjust-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
- for (Expr *E : AdjustArgsNeedDeviceAddr) {
- E = E->IgnoreParenImpCasts();
- if (const auto *DRE = dyn_cast(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(),
diff --git a/clang/test/OpenMP/declare_variant_clauses_ast_print.cpp b/clang/test/OpenMP/declare_variant_clauses_ast_print.cpp index c14e19cc8b7ec..e98a23e865cf8 100644 --- a/clang/test/OpenMP/declare_variant_clauses_ast_print.cpp +++ b/clang/test/OpenMP/declare_variant_clauses_ast_print.cpp @@ -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
-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' diff --git a/clang/test/OpenMP/declare_variant_clauses_messages.cpp b/clang/test/OpenMP/declare_variant_clauses_messages.cpp index bca91481220ff..916d15fde9ff2 100644 --- a/clang/test/OpenMP/declare_variant_clauses_messages.cpp +++ b/clang/test/OpenMP/declare_variant_clauses_messages.cpp @@ -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