[OpenACC] Allow sub-arrays in declare/use_device as an extension
These two both allow arrays as their variable references, but it is a common thing to use sub-arrays as a way to get a pointer to act as an array with other compilers. This patch adds these, with an extension-warning.
This commit is contained in:
parent
284a5c2c0b
commit
3e1392fb4b
@ -13257,6 +13257,11 @@ def err_acc_not_a_var_ref
|
||||
def err_acc_not_a_var_ref_use_device_declare
|
||||
: Error<"OpenACC variable %select{in 'use_device' clause|on 'declare' "
|
||||
"construct}0 is not a valid variable name or array name">;
|
||||
def ext_acc_array_section_use_device_declare
|
||||
: Extension<
|
||||
"sub-array as a variable %select{in 'use_device' clause|on "
|
||||
"'declare' construct}0 is not a valid variable name or array name">,
|
||||
InGroup<DiagGroup<"openacc-extension">>;
|
||||
def err_acc_not_a_var_ref_cache
|
||||
: Error<"OpenACC variable in 'cache' directive is not a valid sub-array or "
|
||||
"array element">;
|
||||
|
@ -699,12 +699,20 @@ ExprResult SemaOpenACC::ActOnVar(OpenACCDirectiveKind DK, OpenACCClauseKind CK,
|
||||
// OpenACC3.3 2.13:
|
||||
// A 'var' in a 'declare' directive must be a variable or array name.
|
||||
if ((CK == OpenACCClauseKind::UseDevice ||
|
||||
DK == OpenACCDirectiveKind::Declare) &&
|
||||
isa<ArraySectionExpr, ArraySubscriptExpr>(CurVarExpr)) {
|
||||
Diag(VarExpr->getExprLoc(), diag::err_acc_not_a_var_ref_use_device_declare)
|
||||
DK == OpenACCDirectiveKind::Declare)) {
|
||||
if (isa<ArraySubscriptExpr>(CurVarExpr)) {
|
||||
Diag(VarExpr->getExprLoc(),
|
||||
diag::err_acc_not_a_var_ref_use_device_declare)
|
||||
<< (DK == OpenACCDirectiveKind::Declare);
|
||||
return ExprError();
|
||||
}
|
||||
// As an extension, we allow 'array sections'/'sub-arrays' here, as that is
|
||||
// effectively defining an array, and are in common use.
|
||||
if (isa<ArraySectionExpr>(CurVarExpr))
|
||||
Diag(VarExpr->getExprLoc(),
|
||||
diag::ext_acc_array_section_use_device_declare)
|
||||
<< (DK == OpenACCDirectiveKind::Declare);
|
||||
}
|
||||
|
||||
// Sub-arrays/subscript-exprs are fine as long as the base is a
|
||||
// VarExpr/MemberExpr. So strip all of those off.
|
||||
|
@ -2254,7 +2254,13 @@ bool SemaOpenACC::CheckDeclareClause(SemaOpenACC::OpenACCParsedClause &Clause,
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
const auto *DRE = cast<DeclRefExpr>(VarExpr);
|
||||
|
||||
const Expr *VarExprTemp = VarExpr;
|
||||
|
||||
while (const auto *ASE = dyn_cast<ArraySectionExpr>(VarExprTemp))
|
||||
VarExprTemp = ASE->getBase()->IgnoreParenImpCasts();
|
||||
|
||||
const auto *DRE = cast<DeclRefExpr>(VarExprTemp);
|
||||
if (const auto *Var = dyn_cast<VarDecl>(DRE->getDecl())) {
|
||||
CurDecl = Var->getCanonicalDecl();
|
||||
|
||||
|
@ -1,13 +1,15 @@
|
||||
// RUN: %clang_cc1 -fopenacc -Wno-openacc-self-if-potential-conflict -emit-cir -fclangir %s -o - | FileCheck %s
|
||||
|
||||
void acc_host_data(int cond, int var1, int var2) {
|
||||
// CHECK: cir.func{{.*}} @acc_host_data(%[[ARG_COND:.*]]: !s32i {{.*}}, %[[ARG_V1:.*]]: !s32i {{.*}}, %[[ARG_V2:.*]]: !s32i {{.*}}) {
|
||||
void acc_host_data(int cond, int var1, int var2, int *arr) {
|
||||
// CHECK: cir.func{{.*}} @acc_host_data(%[[ARG_COND:.*]]: !s32i {{.*}}, %[[ARG_V1:.*]]: !s32i {{.*}}, %[[ARG_V2:.*]]: !s32i {{.*}}, %[[ARG_ARR:.*]]: !cir.ptr<!s32i> {{.*}}) {
|
||||
// CHECK-NEXT: %[[COND:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["cond", init]
|
||||
// CHECK-NEXT: %[[V1:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["var1", init]
|
||||
// CHECK-NEXT: %[[V2:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["var2", init]
|
||||
// CHECK-NEXT: %[[ARR:.*]] = cir.alloca !cir.ptr<!s32i>, !cir.ptr<!cir.ptr<!s32i>>, ["arr", init]
|
||||
// CHECK-NEXT: cir.store %[[ARG_COND]], %[[COND]] : !s32i, !cir.ptr<!s32i>
|
||||
// CHECK-NEXT: cir.store %[[ARG_V1]], %[[V1]] : !s32i, !cir.ptr<!s32i>
|
||||
// CHECK-NEXT: cir.store %[[ARG_V2]], %[[V2]] : !s32i, !cir.ptr<!s32i>
|
||||
// CHECK-NEXT: cir.store %[[ARG_ARR]], %[[ARR]] : !cir.ptr<!s32i>, !cir.ptr<!cir.ptr<!s32i>>
|
||||
|
||||
#pragma acc host_data use_device(var1)
|
||||
{}
|
||||
@ -52,4 +54,18 @@ void acc_host_data(int cond, int var1, int var2) {
|
||||
// CHECK-NEXT: acc.host_data if(%[[COND_CAST]]) dataOperands(%[[USE_DEV1]], %[[USE_DEV2]] : !cir.ptr<!s32i>, !cir.ptr<!s32i>) {
|
||||
// CHECK-NEXT: acc.terminator
|
||||
// CHECK-NEXT: } attributes {ifPresent}
|
||||
|
||||
#pragma acc host_data use_device(arr[0:var1])
|
||||
{}
|
||||
// CHECK-NEXT: %[[ZERO:.*]] = cir.const #cir.int<0>
|
||||
// CHECK-NEXT: %[[ZERO_CAST:.*]] = builtin.unrealized_conversion_cast %[[ZERO]] : !s32i to si32
|
||||
// CHECK-NEXT: %[[VAR1_LOAD:.*]] = cir.load{{.*}} %[[V1]] : !cir.ptr<!s32i>, !s32i
|
||||
// CHECK-NEXT: %[[VAR1_CAST:.*]] = builtin.unrealized_conversion_cast %[[VAR1_LOAD]] : !s32i to si32
|
||||
// CHECK-NEXT: %[[CONST_ZERO:.*]] = arith.constant 0
|
||||
// CHECK-NEXT: %[[CONST_ONE:.*]] = arith.constant 1
|
||||
// CHECK-NEXT: %[[BOUNDS:.*]] = acc.bounds lowerbound(%[[ZERO_CAST]] : si32) extent(%[[VAR1_CAST]] : si32) stride(%[[CONST_ONE]] : i64) startIdx(%[[CONST_ZERO]] : i64)
|
||||
// CHECK-NEXT: %[[USE_DEV1:.*]] = acc.use_device varPtr(%[[ARR]] : !cir.ptr<!cir.ptr<!s32i>>) bounds(%[[BOUNDS]]) -> !cir.ptr<!cir.ptr<!s32i>> {name = "arr[0:var1]"}
|
||||
// CHECK-NEXT: acc.host_data dataOperands(%[[USE_DEV1]] : !cir.ptr<!cir.ptr<!s32i>>)
|
||||
// CHECK-NEXT: acc.terminator
|
||||
// CHECK-NEXT: } loc
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
// RUN: %clang_cc1 %s -fopenacc -verify
|
||||
// RUN: %clang_cc1 %s -fopenacc -verify -Wopenacc-extension
|
||||
|
||||
typedef struct IsComplete {
|
||||
struct S { int A; } CompositeMember;
|
||||
@ -23,7 +23,7 @@ void uses(int IntParam, short *PointerParam, float ArrayParam[5], Complete Compo
|
||||
#pragma acc host_data use_device(LocalComposite.ScalarMember, LocalComposite.ScalarMember)
|
||||
;
|
||||
|
||||
// expected-error@+1{{OpenACC variable in 'use_device' clause is not a valid variable name or array name}}
|
||||
// expected-warning@+1{{sub-array as a variable in 'use_device' clause is not a valid variable name or array name}}
|
||||
#pragma acc host_data use_device(LocalArray[2:1])
|
||||
|
||||
// expected-error@+1{{OpenACC variable in 'use_device' clause is not a valid variable name or array name}}
|
||||
@ -35,12 +35,12 @@ void uses(int IntParam, short *PointerParam, float ArrayParam[5], Complete Compo
|
||||
;
|
||||
|
||||
// expected-error@+2{{OpenACC sub-array length is unspecified and cannot be inferred because the subscripted value is not an array}}
|
||||
// expected-error@+1{{OpenACC variable in 'use_device' clause is not a valid variable name or array name}}
|
||||
// expected-warning@+1{{sub-array as a variable in 'use_device' clause is not a valid variable name or array name}}
|
||||
#pragma acc host_data use_device(PointerParam[2:])
|
||||
;
|
||||
|
||||
// expected-error@+2{{OpenACC sub-array specified range [2:5] would be out of the range of the subscripted array size of 5}}
|
||||
// expected-error@+1{{OpenACC variable in 'use_device' clause is not a valid variable name or array name}}
|
||||
// expected-warning@+1{{sub-array as a variable in 'use_device' clause is not a valid variable name or array name}}
|
||||
#pragma acc host_data use_device(ArrayParam[2:5])
|
||||
;
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
// RUN: %clang_cc1 %s -fopenacc -verify -Wno-empty-body -Wno-unused-value
|
||||
// RUN: %clang_cc1 %s -fopenacc -verify -Wno-empty-body -Wno-unused-value -Wopenacc-extension
|
||||
|
||||
void HasStmt() {
|
||||
{
|
||||
@ -185,7 +185,7 @@ void HostDataRules() {
|
||||
#pragma acc host_data use_device(Array)
|
||||
;
|
||||
|
||||
// expected-error@+1{{OpenACC variable in 'use_device' clause is not a valid variable name or array name}}
|
||||
// expected-warning@+1{{sub-array as a variable in 'use_device' clause is not a valid variable name or array name}}
|
||||
#pragma acc host_data use_device(Array[1:1])
|
||||
;
|
||||
|
||||
|
@ -1,7 +1,8 @@
|
||||
// RUN: %clang_cc1 %s -fopenacc -verify
|
||||
// RUN: %clang_cc1 %s -fopenacc -verify -Wopenacc-extension
|
||||
|
||||
int *Global;
|
||||
int GlobalArray[5];
|
||||
int GlobalArray2[5];
|
||||
// expected-error@+1{{no valid clauses specified in OpenACC 'declare' directive}}
|
||||
#pragma acc declare
|
||||
namespace NS {
|
||||
@ -265,8 +266,8 @@ void use() {
|
||||
|
||||
// expected-error@+1{{OpenACC variable on 'declare' construct is not a valid variable name or array name}}
|
||||
#pragma acc declare create(GlobalArray[0])
|
||||
// expected-error@+1{{OpenACC variable on 'declare' construct is not a valid variable name or array name}}
|
||||
#pragma acc declare create(GlobalArray[0: 1])
|
||||
// expected-warning@+1{{sub-array as a variable on 'declare' construct is not a valid variable name or array name}}
|
||||
#pragma acc declare create(GlobalArray[0: 1]) // #GLOBALARRAYREF
|
||||
|
||||
struct S { int I; };
|
||||
// expected-error@+1{{OpenACC variable on 'declare' construct is not a valid variable name or array name}}
|
||||
@ -288,8 +289,12 @@ void ExternVar() {
|
||||
#pragma acc declare copy(I) copyin(I2), copyout(I3), create(I4), present(I5), deviceptr(I6), device_resident(I7), link(I8)
|
||||
}
|
||||
|
||||
// expected-error@+2{{variable referenced in 'link' clause of OpenACC 'declare' directive was already referenced}}
|
||||
// expected-note@#GLOBALARRAYREF{{previous reference is here}}
|
||||
#pragma acc declare link(GlobalArray)
|
||||
|
||||
// Link can only have global, namespace, or extern vars.
|
||||
#pragma acc declare link(Global, GlobalArray)
|
||||
#pragma acc declare link(Global, GlobalArray2)
|
||||
|
||||
struct Struct2 {
|
||||
static const int StaticMem = 5;
|
||||
|
Loading…
x
Reference in New Issue
Block a user