Skip to content

Commit 78c7024

Browse files
committed
[OpenACC] Implement 'present' for combined constructs.
This is another clause where the parsing does all the required enforcement besides the construct it appertains to, so this patch removes the restriction and adds sufficient test coverage for combined constructs.
1 parent 5fd4f32 commit 78c7024

7 files changed

+263
-18
lines changed

clang/lib/Sema/SemaOpenACC.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -859,10 +859,11 @@ OpenACCClause *SemaOpenACCClauseVisitor::VisitNoCreateClause(
859859

860860
OpenACCClause *SemaOpenACCClauseVisitor::VisitPresentClause(
861861
SemaOpenACC::OpenACCParsedClause &Clause) {
862-
// Restrictions only properly implemented on 'compute' constructs, and
863-
// 'compute' constructs are the only construct that can do anything with
864-
// this yet, so skip/treat as unimplemented in this case.
865-
if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind()))
862+
// Restrictions only properly implemented on 'compute'/'combined constructs,
863+
// and 'compute'/'combined' constructs are the only construct that can do
864+
// anything with this yet, so skip/treat as unimplemented in this case.
865+
if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind()) &&
866+
!isOpenACCCombinedDirectiveKind(Clause.getDirectiveKind()))
866867
return isNotImplemented();
867868
// ActOnVar ensured that everything is a valid variable reference, so there
868869
// really isn't anything to do here. GCC does some duplicate-finding, though

clang/test/AST/ast-print-openacc-combined-construct.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,4 +122,13 @@ void foo() {
122122
#pragma acc kernels loop async
123123
for(int i = 0;i<5;++i);
124124

125+
// CHECK: #pragma acc parallel loop present(i, array[1], array, array[1:2])
126+
#pragma acc parallel loop present(i, array[1], array, array[1:2])
127+
for(int i = 0;i<5;++i);
128+
// CHECK: #pragma acc serial loop present(i, array[1], array, array[1:2])
129+
#pragma acc serial loop present(i, array[1], array, array[1:2])
130+
for(int i = 0;i<5;++i);
131+
// CHECK: #pragma acc kernels loop present(i, array[1], array, array[1:2])
132+
#pragma acc kernels loop present(i, array[1], array, array[1:2])
133+
for(int i = 0;i<5;++i);
125134
}

clang/test/SemaOpenACC/combined-construct-auto_seq_independent-clauses.c

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -111,8 +111,6 @@ void uses() {
111111
// expected-warning@+1{{OpenACC clause 'no_create' not yet implemented}}
112112
#pragma acc parallel loop auto no_create(Var)
113113
for(unsigned i = 0; i < 5; ++i);
114-
// TODOexpected-error@+1{{OpenACC 'present' clause is not valid on 'parallel loop' directive}}
115-
// expected-warning@+1{{OpenACC clause 'present' not yet implemented}}
116114
#pragma acc parallel loop auto present(Var)
117115
for(unsigned i = 0; i < 5; ++i);
118116
#pragma acc parallel loop auto private(Var)
@@ -274,8 +272,6 @@ void uses() {
274272
// expected-warning@+1{{OpenACC clause 'no_create' not yet implemented}}
275273
#pragma acc parallel loop no_create(Var) auto
276274
for(unsigned i = 0; i < 5; ++i);
277-
// TODOexpected-error@+1{{OpenACC 'present' clause is not valid on 'parallel loop' directive}}
278-
// expected-warning@+1{{OpenACC clause 'present' not yet implemented}}
279275
#pragma acc parallel loop present(Var) auto
280276
for(unsigned i = 0; i < 5; ++i);
281277
#pragma acc parallel loop private(Var) auto
@@ -438,8 +434,6 @@ void uses() {
438434
// expected-warning@+1{{OpenACC clause 'no_create' not yet implemented}}
439435
#pragma acc parallel loop independent no_create(Var)
440436
for(unsigned i = 0; i < 5; ++i);
441-
// TODOexpected-error@+1{{OpenACC 'present' clause is not valid on 'parallel loop' directive}}
442-
// expected-warning@+1{{OpenACC clause 'present' not yet implemented}}
443437
#pragma acc parallel loop independent present(Var)
444438
for(unsigned i = 0; i < 5; ++i);
445439
#pragma acc parallel loop independent private(Var)
@@ -601,8 +595,6 @@ void uses() {
601595
// expected-warning@+1{{OpenACC clause 'no_create' not yet implemented}}
602596
#pragma acc parallel loop no_create(Var) independent
603597
for(unsigned i = 0; i < 5; ++i);
604-
// TODOexpected-error@+1{{OpenACC 'present' clause is not valid on 'parallel loop' directive}}
605-
// expected-warning@+1{{OpenACC clause 'present' not yet implemented}}
606598
#pragma acc parallel loop present(Var) independent
607599
for(unsigned i = 0; i < 5; ++i);
608600
#pragma acc parallel loop private(Var) independent
@@ -771,8 +763,6 @@ void uses() {
771763
// expected-warning@+1{{OpenACC clause 'no_create' not yet implemented}}
772764
#pragma acc parallel loop seq no_create(Var)
773765
for(unsigned i = 0; i < 5; ++i);
774-
// TODOexpected-error@+1{{OpenACC 'present' clause is not valid on 'parallel loop' directive}}
775-
// expected-warning@+1{{OpenACC clause 'present' not yet implemented}}
776766
#pragma acc parallel loop seq present(Var)
777767
for(unsigned i = 0; i < 5; ++i);
778768
#pragma acc parallel loop seq private(Var)
@@ -940,8 +930,6 @@ void uses() {
940930
// expected-warning@+1{{OpenACC clause 'no_create' not yet implemented}}
941931
#pragma acc parallel loop no_create(Var) seq
942932
for(unsigned i = 0; i < 5; ++i);
943-
// TODOexpected-error@+1{{OpenACC 'present' clause is not valid on 'parallel loop' directive}}
944-
// expected-warning@+1{{OpenACC clause 'present' not yet implemented}}
945933
#pragma acc parallel loop present(Var) seq
946934
for(unsigned i = 0; i < 5; ++i);
947935
#pragma acc parallel loop private(Var) seq

clang/test/SemaOpenACC/combined-construct-default-clause.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,7 @@ void SingleOnly() {
1111

1212
int i;
1313

14-
// expected-warning@+4{{OpenACC clause 'copy' not yet implemented}}
15-
// expected-warning@+3{{OpenACC clause 'present' not yet implemented}}
14+
// expected-warning@+3{{OpenACC clause 'copy' not yet implemented}}
1615
// expected-error@+2{{OpenACC 'default' clause cannot appear more than once on a 'kernels loop' directive}}
1716
// expected-note@+1{{previous clause is here}}
1817
#pragma acc kernels loop self default(present) present(i) default(none) copy(i)
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
// RUN: %clang_cc1 %s -fopenacc -ast-dump | FileCheck %s
2+
3+
// Test this with PCH.
4+
// RUN: %clang_cc1 %s -fopenacc -emit-pch -o %t %s
5+
// RUN: %clang_cc1 %s -fopenacc -include-pch %t -ast-dump-all | FileCheck %s
6+
7+
#ifndef PCH_HELPER
8+
#define PCH_HELPER
9+
10+
int Global;
11+
short GlobalArray[5];
12+
13+
void NormalUses(float *PointerParam) {
14+
// CHECK: FunctionDecl{{.*}}NormalUses
15+
// CHECK: ParmVarDecl
16+
// CHECK-NEXT: CompoundStmt
17+
18+
#pragma acc parallel loop present(GlobalArray, PointerParam[Global])
19+
for(int i = 0; i < 5; ++i);
20+
// CHECK-NEXT: OpenACCCombinedConstruct{{.*}} parallel loop
21+
// CHECK-NEXT: present clause
22+
// CHECK-NEXT: DeclRefExpr{{.*}}'short[5]' lvalue Var{{.*}}'GlobalArray' 'short[5]'
23+
// CHECK-NEXT: ArraySubscriptExpr{{.*}}'float' lvalue
24+
// CHECK-NEXT: ImplicitCastExpr{{.*}} 'float *' <LValueToRValue>
25+
// CHECK-NEXT: DeclRefExpr{{.*}}'float *' lvalue ParmVar{{.*}}'PointerParam' 'float *'
26+
// CHECK-NEXT: ImplicitCastExpr{{.*}} 'int' <LValueToRValue>
27+
// CHECK-NEXT: DeclRefExpr{{.*}}'int' lvalue Var{{.*}}'Global' 'int'
28+
// CHECK-NEXT: ForStmt
29+
// CHECK: NullStmt
30+
}
31+
32+
template<auto &NTTP, typename T>
33+
void TemplUses(T t) {
34+
// CHECK-NEXT: FunctionTemplateDecl
35+
// CHECK-NEXT: NonTypeTemplateParmDecl {{.*}}referenced 'auto &' depth 0 index 0 NTTP
36+
// CHECK-NEXT: TemplateTypeParmDecl{{.*}}typename depth 0 index 1 T
37+
// CHECK-NEXT: FunctionDecl{{.*}} TemplUses 'void (T)'
38+
// CHECK-NEXT: ParmVarDecl{{.*}} referenced t 'T'
39+
// CHECK-NEXT: CompoundStmt
40+
41+
#pragma acc serial loop seq present(NTTP, t)
42+
for(int i = 0; i < 5; ++i);
43+
// CHECK-NEXT: OpenACCCombinedConstruct{{.*}} serial loop
44+
// CHECK-NEXT: seq clause
45+
// CHECK-NEXT: present clause
46+
// CHECK-NEXT: DeclRefExpr{{.*}}'auto' lvalue NonTypeTemplateParm{{.*}} 'NTTP' 'auto &'
47+
// CHECK-NEXT: DeclRefExpr{{.*}}'T' lvalue ParmVar{{.*}} 't' 'T'
48+
// CHECK-NEXT: ForStmt
49+
// CHECK: NullStmt
50+
51+
52+
// Check the instantiated versions of the above.
53+
// CHECK-NEXT: FunctionDecl{{.*}} used TemplUses 'void (int)' implicit_instantiation
54+
// CHECK-NEXT: TemplateArgument decl
55+
// CHECK-NEXT: Var{{.*}} 'CEVar' 'const unsigned int'
56+
// CHECK-NEXT: TemplateArgument type 'int'
57+
// CHECK-NEXT: BuiltinType{{.*}} 'int'
58+
// CHECK-NEXT: ParmVarDecl{{.*}} used t 'int'
59+
// CHECK-NEXT: CompoundStmt
60+
61+
// #pragma acc parallel seq present(NTTP, t)
62+
// CHECK-NEXT: OpenACCCombinedConstruct{{.*}} serial loop
63+
// CHECK-NEXT: seq clause
64+
// CHECK-NEXT: present clause
65+
// CHECK-NEXT: SubstNonTypeTemplateParmExpr{{.*}}'const unsigned int' lvalue
66+
// CHECK-NEXT: NonTypeTemplateParmDecl{{.*}} referenced 'auto &' depth 0 index 0 NTTP
67+
// CHECK-NEXT: DeclRefExpr{{.*}}'const unsigned int' lvalue Var{{.*}} 'CEVar' 'const unsigned int'
68+
// CHECK-NEXT: DeclRefExpr{{.*}}'int' lvalue ParmVar{{.*}} 't' 'int'
69+
// CHECK-NEXT: ForStmt
70+
// CHECK: NullStmt
71+
72+
}
73+
74+
void Inst() {
75+
static constexpr unsigned CEVar = 1;
76+
TemplUses<CEVar>(5);
77+
}
78+
#endif
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
// RUN: %clang_cc1 %s -fopenacc -verify
2+
3+
typedef struct IsComplete {
4+
struct S { int A; } CompositeMember;
5+
int ScalarMember;
6+
float ArrayMember[5];
7+
void *PointerMember;
8+
} Complete;
9+
void uses(int IntParam, short *PointerParam, float ArrayParam[5], Complete CompositeParam) {
10+
int LocalInt;
11+
short *LocalPointer;
12+
float LocalArray[5];
13+
Complete LocalComposite;
14+
// Check Appertainment:
15+
#pragma acc parallel loop present(LocalInt)
16+
for(int i = 5; i < 10;++i);
17+
#pragma acc serial loop present(LocalInt)
18+
for(int i = 5; i < 10;++i);
19+
#pragma acc kernels loop present(LocalInt)
20+
for(int i = 5; i < 10;++i);
21+
22+
// Valid cases:
23+
#pragma acc parallel loop present(LocalInt, LocalPointer, LocalArray)
24+
for(int i = 5; i < 10;++i);
25+
#pragma acc parallel loop present(LocalArray[2:1])
26+
for(int i = 5; i < 10;++i);
27+
28+
#pragma acc parallel loop present(LocalComposite.ScalarMember, LocalComposite.ScalarMember)
29+
for(int i = 5; i < 10;++i);
30+
31+
// expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
32+
#pragma acc parallel loop present(1 + IntParam)
33+
for(int i = 5; i < 10;++i);
34+
35+
// expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
36+
#pragma acc parallel loop present(+IntParam)
37+
for(int i = 5; i < 10;++i);
38+
39+
// expected-error@+1{{OpenACC sub-array length is unspecified and cannot be inferred because the subscripted value is not an array}}
40+
#pragma acc parallel loop present(PointerParam[2:])
41+
for(int i = 5; i < 10;++i);
42+
43+
// expected-error@+1{{OpenACC sub-array specified range [2:5] would be out of the range of the subscripted array size of 5}}
44+
#pragma acc parallel loop present(ArrayParam[2:5])
45+
for(int i = 5; i < 10;++i);
46+
47+
// expected-error@+2{{OpenACC sub-array specified range [2:5] would be out of the range of the subscripted array size of 5}}
48+
// expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
49+
#pragma acc parallel loop present((float*)ArrayParam[2:5])
50+
for(int i = 5; i < 10;++i);
51+
// expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
52+
#pragma acc parallel loop present((float)ArrayParam[2])
53+
for(int i = 5; i < 10;++i);
54+
55+
// expected-error@+1{{OpenACC 'present' clause is not valid on 'loop' directive}}
56+
#pragma acc loop present(LocalInt)
57+
for(int i = 5; i < 10;++i);
58+
}
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
// RUN: %clang_cc1 %s -fopenacc -verify
2+
3+
enum SomeE{};
4+
typedef struct IsComplete {
5+
struct S { int A; } CompositeMember;
6+
int ScalarMember;
7+
float ArrayMember[5];
8+
SomeE EnumMember;
9+
char *PointerMember;
10+
} Complete;
11+
12+
void uses(int IntParam, char *PointerParam, float ArrayParam[5], Complete CompositeParam, int &IntParamRef) {
13+
int LocalInt;
14+
char *LocalPointer;
15+
float LocalArray[5];
16+
// Check Appertainment:
17+
#pragma acc parallel loop present(LocalInt)
18+
for(unsigned I = 0; I < 5; ++I);
19+
#pragma acc serial loop present(LocalInt)
20+
for(unsigned I = 0; I < 5; ++I);
21+
#pragma acc kernels loop present(LocalInt)
22+
for(unsigned I = 0; I < 5; ++I);
23+
24+
// Valid cases:
25+
#pragma acc parallel loop present(LocalInt, LocalPointer, LocalArray)
26+
for(unsigned I = 0; I < 5; ++I);
27+
#pragma acc parallel loop present(LocalArray[2:1])
28+
for(unsigned I = 0; I < 5; ++I);
29+
30+
Complete LocalComposite2;
31+
#pragma acc parallel loop present(LocalComposite2.ScalarMember, LocalComposite2.ScalarMember)
32+
for(unsigned I = 0; I < 5; ++I);
33+
34+
// expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
35+
#pragma acc parallel loop present(1 + IntParam)
36+
for(unsigned I = 0; I < 5; ++I);
37+
38+
// expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
39+
#pragma acc parallel loop present(+IntParam)
40+
for(unsigned I = 0; I < 5; ++I);
41+
42+
// expected-error@+1{{OpenACC sub-array length is unspecified and cannot be inferred because the subscripted value is not an array}}
43+
#pragma acc parallel loop present(PointerParam[2:])
44+
for(unsigned I = 0; I < 5; ++I);
45+
46+
// expected-error@+1{{OpenACC sub-array specified range [2:5] would be out of the range of the subscripted array size of 5}}
47+
#pragma acc parallel loop present(ArrayParam[2:5])
48+
for(unsigned I = 0; I < 5; ++I);
49+
50+
// expected-error@+2{{OpenACC sub-array specified range [2:5] would be out of the range of the subscripted array size of 5}}
51+
// expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
52+
#pragma acc parallel loop present((float*)ArrayParam[2:5])
53+
for(unsigned I = 0; I < 5; ++I);
54+
// expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
55+
#pragma acc parallel loop present((float)ArrayParam[2])
56+
for(unsigned I = 0; I < 5; ++I);
57+
}
58+
59+
template<typename T, unsigned Int, typename V>
60+
void TemplUses(T t, T (&arrayT)[Int], V TemplComp) {
61+
// expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
62+
#pragma acc parallel loop present(+t)
63+
for(unsigned I = 0; I < 5; ++I);
64+
65+
// NTTP's are only valid if it is a reference to something.
66+
// expected-error@+2{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
67+
// expected-note@#TEMPL_USES_INST{{in instantiation of}}
68+
#pragma acc parallel loop present(Int)
69+
for(unsigned I = 0; I < 5; ++I);
70+
71+
// expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
72+
#pragma acc parallel loop present(t, Int)
73+
for(unsigned I = 0; I < 5; ++I);
74+
75+
#pragma acc parallel loop present(arrayT)
76+
for(unsigned I = 0; I < 5; ++I);
77+
78+
#pragma acc parallel loop present(TemplComp)
79+
for(unsigned I = 0; I < 5; ++I);
80+
81+
#pragma acc parallel loop present(TemplComp.PointerMember[5])
82+
for(unsigned I = 0; I < 5; ++I);
83+
int *Pointer;
84+
#pragma acc parallel loop present(Pointer[:Int])
85+
for(unsigned I = 0; I < 5; ++I);
86+
#pragma acc parallel loop present(Pointer[:t])
87+
for(unsigned I = 0; I < 5; ++I);
88+
// expected-error@+1{{OpenACC sub-array length is unspecified and cannot be inferred because the subscripted value is not an array}}
89+
#pragma acc parallel loop present(Pointer[1:])
90+
for(unsigned I = 0; I < 5; ++I);
91+
}
92+
93+
template<unsigned Int, auto &NTTP_REF>
94+
void NTTP() {
95+
// NTTP's are only valid if it is a reference to something.
96+
// expected-error@+2{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
97+
// expected-note@#NTTP_INST{{in instantiation of}}
98+
#pragma acc parallel loop present(Int)
99+
for(unsigned I = 0; I < 5; ++I);
100+
101+
#pragma acc parallel loop present(NTTP_REF)
102+
for(unsigned I = 0; I < 5; ++I);
103+
}
104+
105+
void Inst() {
106+
static constexpr int NTTP_REFed = 1;
107+
int i;
108+
int Arr[5];
109+
Complete C;
110+
TemplUses(i, Arr, C); // #TEMPL_USES_INST
111+
NTTP<5, NTTP_REFed>(); // #NTTP_INST
112+
}

0 commit comments

Comments
 (0)