Skip to content

Commit 3e1392f

Browse files
committed
[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.
1 parent 284a5c2 commit 3e1392f

File tree

7 files changed

+58
-18
lines changed

7 files changed

+58
-18
lines changed

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13257,6 +13257,11 @@ def err_acc_not_a_var_ref
1325713257
def err_acc_not_a_var_ref_use_device_declare
1325813258
: Error<"OpenACC variable %select{in 'use_device' clause|on 'declare' "
1325913259
"construct}0 is not a valid variable name or array name">;
13260+
def ext_acc_array_section_use_device_declare
13261+
: Extension<
13262+
"sub-array as a variable %select{in 'use_device' clause|on "
13263+
"'declare' construct}0 is not a valid variable name or array name">,
13264+
InGroup<DiagGroup<"openacc-extension">>;
1326013265
def err_acc_not_a_var_ref_cache
1326113266
: Error<"OpenACC variable in 'cache' directive is not a valid sub-array or "
1326213267
"array element">;

clang/lib/Sema/SemaOpenACC.cpp

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -699,11 +699,19 @@ ExprResult SemaOpenACC::ActOnVar(OpenACCDirectiveKind DK, OpenACCClauseKind CK,
699699
// OpenACC3.3 2.13:
700700
// A 'var' in a 'declare' directive must be a variable or array name.
701701
if ((CK == OpenACCClauseKind::UseDevice ||
702-
DK == OpenACCDirectiveKind::Declare) &&
703-
isa<ArraySectionExpr, ArraySubscriptExpr>(CurVarExpr)) {
704-
Diag(VarExpr->getExprLoc(), diag::err_acc_not_a_var_ref_use_device_declare)
705-
<< (DK == OpenACCDirectiveKind::Declare);
706-
return ExprError();
702+
DK == OpenACCDirectiveKind::Declare)) {
703+
if (isa<ArraySubscriptExpr>(CurVarExpr)) {
704+
Diag(VarExpr->getExprLoc(),
705+
diag::err_acc_not_a_var_ref_use_device_declare)
706+
<< (DK == OpenACCDirectiveKind::Declare);
707+
return ExprError();
708+
}
709+
// As an extension, we allow 'array sections'/'sub-arrays' here, as that is
710+
// effectively defining an array, and are in common use.
711+
if (isa<ArraySectionExpr>(CurVarExpr))
712+
Diag(VarExpr->getExprLoc(),
713+
diag::ext_acc_array_section_use_device_declare)
714+
<< (DK == OpenACCDirectiveKind::Declare);
707715
}
708716

709717
// Sub-arrays/subscript-exprs are fine as long as the base is a

clang/lib/Sema/SemaOpenACCClause.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2254,7 +2254,13 @@ bool SemaOpenACC::CheckDeclareClause(SemaOpenACC::OpenACCParsedClause &Clause,
22542254
continue;
22552255
}
22562256
} else {
2257-
const auto *DRE = cast<DeclRefExpr>(VarExpr);
2257+
2258+
const Expr *VarExprTemp = VarExpr;
2259+
2260+
while (const auto *ASE = dyn_cast<ArraySectionExpr>(VarExprTemp))
2261+
VarExprTemp = ASE->getBase()->IgnoreParenImpCasts();
2262+
2263+
const auto *DRE = cast<DeclRefExpr>(VarExprTemp);
22582264
if (const auto *Var = dyn_cast<VarDecl>(DRE->getDecl())) {
22592265
CurDecl = Var->getCanonicalDecl();
22602266

clang/test/CIR/CodeGenOpenACC/host_data.c

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
// RUN: %clang_cc1 -fopenacc -Wno-openacc-self-if-potential-conflict -emit-cir -fclangir %s -o - | FileCheck %s
22

3-
void acc_host_data(int cond, int var1, int var2) {
4-
// CHECK: cir.func{{.*}} @acc_host_data(%[[ARG_COND:.*]]: !s32i {{.*}}, %[[ARG_V1:.*]]: !s32i {{.*}}, %[[ARG_V2:.*]]: !s32i {{.*}}) {
3+
void acc_host_data(int cond, int var1, int var2, int *arr) {
4+
// CHECK: cir.func{{.*}} @acc_host_data(%[[ARG_COND:.*]]: !s32i {{.*}}, %[[ARG_V1:.*]]: !s32i {{.*}}, %[[ARG_V2:.*]]: !s32i {{.*}}, %[[ARG_ARR:.*]]: !cir.ptr<!s32i> {{.*}}) {
55
// CHECK-NEXT: %[[COND:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["cond", init]
66
// CHECK-NEXT: %[[V1:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["var1", init]
77
// CHECK-NEXT: %[[V2:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["var2", init]
8+
// CHECK-NEXT: %[[ARR:.*]] = cir.alloca !cir.ptr<!s32i>, !cir.ptr<!cir.ptr<!s32i>>, ["arr", init]
89
// CHECK-NEXT: cir.store %[[ARG_COND]], %[[COND]] : !s32i, !cir.ptr<!s32i>
910
// CHECK-NEXT: cir.store %[[ARG_V1]], %[[V1]] : !s32i, !cir.ptr<!s32i>
1011
// CHECK-NEXT: cir.store %[[ARG_V2]], %[[V2]] : !s32i, !cir.ptr<!s32i>
12+
// CHECK-NEXT: cir.store %[[ARG_ARR]], %[[ARR]] : !cir.ptr<!s32i>, !cir.ptr<!cir.ptr<!s32i>>
1113

1214
#pragma acc host_data use_device(var1)
1315
{}
@@ -52,4 +54,18 @@ void acc_host_data(int cond, int var1, int var2) {
5254
// CHECK-NEXT: acc.host_data if(%[[COND_CAST]]) dataOperands(%[[USE_DEV1]], %[[USE_DEV2]] : !cir.ptr<!s32i>, !cir.ptr<!s32i>) {
5355
// CHECK-NEXT: acc.terminator
5456
// CHECK-NEXT: } attributes {ifPresent}
57+
58+
#pragma acc host_data use_device(arr[0:var1])
59+
{}
60+
// CHECK-NEXT: %[[ZERO:.*]] = cir.const #cir.int<0>
61+
// CHECK-NEXT: %[[ZERO_CAST:.*]] = builtin.unrealized_conversion_cast %[[ZERO]] : !s32i to si32
62+
// CHECK-NEXT: %[[VAR1_LOAD:.*]] = cir.load{{.*}} %[[V1]] : !cir.ptr<!s32i>, !s32i
63+
// CHECK-NEXT: %[[VAR1_CAST:.*]] = builtin.unrealized_conversion_cast %[[VAR1_LOAD]] : !s32i to si32
64+
// CHECK-NEXT: %[[CONST_ZERO:.*]] = arith.constant 0
65+
// CHECK-NEXT: %[[CONST_ONE:.*]] = arith.constant 1
66+
// CHECK-NEXT: %[[BOUNDS:.*]] = acc.bounds lowerbound(%[[ZERO_CAST]] : si32) extent(%[[VAR1_CAST]] : si32) stride(%[[CONST_ONE]] : i64) startIdx(%[[CONST_ZERO]] : i64)
67+
// 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]"}
68+
// CHECK-NEXT: acc.host_data dataOperands(%[[USE_DEV1]] : !cir.ptr<!cir.ptr<!s32i>>)
69+
// CHECK-NEXT: acc.terminator
70+
// CHECK-NEXT: } loc
5571
}

clang/test/SemaOpenACC/data-construct-use_device-clause.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %clang_cc1 %s -fopenacc -verify
1+
// RUN: %clang_cc1 %s -fopenacc -verify -Wopenacc-extension
22

33
typedef struct IsComplete {
44
struct S { int A; } CompositeMember;
@@ -23,7 +23,7 @@ void uses(int IntParam, short *PointerParam, float ArrayParam[5], Complete Compo
2323
#pragma acc host_data use_device(LocalComposite.ScalarMember, LocalComposite.ScalarMember)
2424
;
2525

26-
// expected-error@+1{{OpenACC variable in 'use_device' clause is not a valid variable name or array name}}
26+
// expected-warning@+1{{sub-array as a variable in 'use_device' clause is not a valid variable name or array name}}
2727
#pragma acc host_data use_device(LocalArray[2:1])
2828

2929
// 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
3535
;
3636

3737
// expected-error@+2{{OpenACC sub-array length is unspecified and cannot be inferred because the subscripted value is not an array}}
38-
// expected-error@+1{{OpenACC variable in 'use_device' clause is not a valid variable name or array name}}
38+
// expected-warning@+1{{sub-array as a variable in 'use_device' clause is not a valid variable name or array name}}
3939
#pragma acc host_data use_device(PointerParam[2:])
4040
;
4141

4242
// expected-error@+2{{OpenACC sub-array specified range [2:5] would be out of the range of the subscripted array size of 5}}
43-
// expected-error@+1{{OpenACC variable in 'use_device' clause is not a valid variable name or array name}}
43+
// expected-warning@+1{{sub-array as a variable in 'use_device' clause is not a valid variable name or array name}}
4444
#pragma acc host_data use_device(ArrayParam[2:5])
4545
;
4646

clang/test/SemaOpenACC/data-construct.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %clang_cc1 %s -fopenacc -verify -Wno-empty-body -Wno-unused-value
1+
// RUN: %clang_cc1 %s -fopenacc -verify -Wno-empty-body -Wno-unused-value -Wopenacc-extension
22

33
void HasStmt() {
44
{
@@ -185,7 +185,7 @@ void HostDataRules() {
185185
#pragma acc host_data use_device(Array)
186186
;
187187

188-
// expected-error@+1{{OpenACC variable in 'use_device' clause is not a valid variable name or array name}}
188+
// expected-warning@+1{{sub-array as a variable in 'use_device' clause is not a valid variable name or array name}}
189189
#pragma acc host_data use_device(Array[1:1])
190190
;
191191

clang/test/SemaOpenACC/declare-construct.cpp

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
// RUN: %clang_cc1 %s -fopenacc -verify
1+
// RUN: %clang_cc1 %s -fopenacc -verify -Wopenacc-extension
22

33
int *Global;
44
int GlobalArray[5];
5+
int GlobalArray2[5];
56
// expected-error@+1{{no valid clauses specified in OpenACC 'declare' directive}}
67
#pragma acc declare
78
namespace NS {
@@ -265,8 +266,8 @@ void use() {
265266

266267
// expected-error@+1{{OpenACC variable on 'declare' construct is not a valid variable name or array name}}
267268
#pragma acc declare create(GlobalArray[0])
268-
// expected-error@+1{{OpenACC variable on 'declare' construct is not a valid variable name or array name}}
269-
#pragma acc declare create(GlobalArray[0: 1])
269+
// expected-warning@+1{{sub-array as a variable on 'declare' construct is not a valid variable name or array name}}
270+
#pragma acc declare create(GlobalArray[0: 1]) // #GLOBALARRAYREF
270271

271272
struct S { int I; };
272273
// expected-error@+1{{OpenACC variable on 'declare' construct is not a valid variable name or array name}}
@@ -288,8 +289,12 @@ void ExternVar() {
288289
#pragma acc declare copy(I) copyin(I2), copyout(I3), create(I4), present(I5), deviceptr(I6), device_resident(I7), link(I8)
289290
}
290291

292+
// expected-error@+2{{variable referenced in 'link' clause of OpenACC 'declare' directive was already referenced}}
293+
// expected-note@#GLOBALARRAYREF{{previous reference is here}}
294+
#pragma acc declare link(GlobalArray)
295+
291296
// Link can only have global, namespace, or extern vars.
292-
#pragma acc declare link(Global, GlobalArray)
297+
#pragma acc declare link(Global, GlobalArray2)
293298

294299
struct Struct2 {
295300
static const int StaticMem = 5;

0 commit comments

Comments
 (0)