Skip to content

Commit e2c1b1f

Browse files
committed
[OpenACC] enable 'async' and 'wait' for 'update' construct
These work the same here as they do for every other construct, so this is as simple as enabling them and writing tests, which this patch does.
1 parent 49357b2 commit e2c1b1f

File tree

4 files changed

+182
-25
lines changed

4 files changed

+182
-25
lines changed

clang/lib/Sema/SemaOpenACC.cpp

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -937,13 +937,6 @@ OpenACCClause *SemaOpenACCClauseVisitor::VisitVectorLengthClause(
937937

938938
OpenACCClause *SemaOpenACCClauseVisitor::VisitAsyncClause(
939939
SemaOpenACC::OpenACCParsedClause &Clause) {
940-
// Restrictions only properly implemented on 'compute'/'combined'/'data'
941-
// constructs, and 'compute'/'combined'/'data' constructs are the only
942-
// construct that can do anything with this yet, so skip/treat as
943-
// unimplemented in this case.
944-
if (!isDirectiveKindImplemented(Clause.getDirectiveKind()))
945-
return isNotImplemented();
946-
947940
// There is no prose in the standard that says duplicates aren't allowed,
948941
// but this diagnostic is present in other compilers, as well as makes
949942
// sense.
@@ -1178,13 +1171,6 @@ OpenACCClause *SemaOpenACCClauseVisitor::VisitDevicePtrClause(
11781171

11791172
OpenACCClause *SemaOpenACCClauseVisitor::VisitWaitClause(
11801173
SemaOpenACC::OpenACCParsedClause &Clause) {
1181-
// Restrictions only properly implemented on 'compute'/'combined'/'data'
1182-
// constructs, and 'compute'/'combined'/'data' constructs are the only
1183-
// construct that can do anything with this yet, so skip/treat as
1184-
// unimplemented in this case.
1185-
if (!isDirectiveKindImplemented(Clause.getDirectiveKind()))
1186-
return isNotImplemented();
1187-
11881174
return OpenACCWaitClause::Create(
11891175
Ctx, Clause.getBeginLoc(), Clause.getLParenLoc(), Clause.getDevNumExpr(),
11901176
Clause.getQueuesLoc(), Clause.getQueueIdExprs(), Clause.getEndLoc());
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,32 @@
11
// RUN: %clang_cc1 -fopenacc -ast-print %s -o - | FileCheck %s
22
void uses(bool cond) {
3+
int I;
4+
int *iPtr;
5+
int array[5];
36
// CHECK: #pragma acc update
47
#pragma acc update
58

69
// CHECK: #pragma acc update if_present
710
#pragma acc update if_present
811
// CHECK: #pragma acc update if(cond)
912
#pragma acc update if(cond)
13+
14+
// CHECK: #pragma acc update async
15+
#pragma acc update async
16+
// CHECK: #pragma acc update async(*iPtr)
17+
#pragma acc update async(*iPtr)
18+
// CHECK: #pragma acc update async(I)
19+
#pragma acc update async(I)
20+
21+
// CHECK: #pragma acc update wait(*iPtr, I) async
22+
#pragma acc update wait(*iPtr, I) async
23+
24+
// CHECK: #pragma acc update wait(queues: *iPtr, I) async(*iPtr)
25+
#pragma acc update wait(queues:*iPtr, I) async(*iPtr)
26+
27+
// CHECK: #pragma acc update wait(devnum: I : *iPtr, I) async(I)
28+
#pragma acc update wait(devnum:I:*iPtr, I) async(I)
29+
30+
// CHECK: #pragma acc update wait(devnum: I : queues: *iPtr, I) if(I == array[I]) async(I)
31+
#pragma acc update wait(devnum:I:queues:*iPtr, I) if(I == array[I]) async(I)
1032
}

clang/test/SemaOpenACC/update-construct-ast.cpp

Lines changed: 125 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,48 @@ void NormalFunc() {
2626
// CHECK-NEXT: CallExpr{{.*}} 'long'
2727
// CHECK-NEXT: ImplicitCastExpr
2828
// CHECK-NEXT: DeclRefExpr{{.*}}'some_long' 'long ()'
29+
30+
#pragma acc update wait async
31+
// CHECK-NEXT: OpenACCUpdateConstruct{{.*}}update
32+
// CHECK-NEXT: wait clause
33+
// CHECK-NEXT: <<<NULL>>>
34+
// CHECK-NEXT: async clause
35+
#pragma acc update wait(some_int(), some_long()) async(some_int())
36+
// CHECK-NEXT: OpenACCUpdateConstruct{{.*}}update
37+
// CHECK-NEXT: wait clause
38+
// CHECK-NEXT: <<<NULL>>>
39+
// CHECK-NEXT: CallExpr{{.*}}'int'
40+
// CHECK-NEXT: ImplicitCastExpr
41+
// CHECK-NEXT: DeclRefExpr{{.*}}'some_int' 'int ()'
42+
// CHECK-NEXT: CallExpr{{.*}}'long'
43+
// CHECK-NEXT: ImplicitCastExpr
44+
// CHECK-NEXT: DeclRefExpr{{.*}}'some_long' 'long ()'
45+
// CHECK-NEXT: async clause
46+
// CHECK-NEXT: CallExpr{{.*}}'int'
47+
// CHECK-NEXT: ImplicitCastExpr
48+
// CHECK-NEXT: DeclRefExpr{{.*}}'some_int' 'int ()'
49+
#pragma acc update wait(queues:some_int(), some_long())
50+
// CHECK-NEXT: OpenACCUpdateConstruct{{.*}}update
51+
// CHECK-NEXT: wait clause
52+
// CHECK-NEXT: <<<NULL>>>
53+
// CHECK-NEXT: CallExpr{{.*}}'int'
54+
// CHECK-NEXT: ImplicitCastExpr
55+
// CHECK-NEXT: DeclRefExpr{{.*}}'some_int' 'int ()'
56+
// CHECK-NEXT: CallExpr{{.*}}'long'
57+
// CHECK-NEXT: ImplicitCastExpr
58+
// CHECK-NEXT: DeclRefExpr{{.*}}'some_long' 'long ()'
59+
#pragma acc update wait(devnum: some_int() :some_int(), some_long())
60+
// CHECK-NEXT: OpenACCUpdateConstruct{{.*}}update
61+
// CHECK-NEXT: wait clause
62+
// CHECK-NEXT: CallExpr{{.*}}'int'
63+
// CHECK-NEXT: ImplicitCastExpr
64+
// CHECK-NEXT: DeclRefExpr{{.*}}'some_int' 'int ()'
65+
// CHECK-NEXT: CallExpr{{.*}}'int'
66+
// CHECK-NEXT: ImplicitCastExpr
67+
// CHECK-NEXT: DeclRefExpr{{.*}}'some_int' 'int ()'
68+
// CHECK-NEXT: CallExpr{{.*}}'long'
69+
// CHECK-NEXT: ImplicitCastExpr
70+
// CHECK-NEXT: DeclRefExpr{{.*}}'some_long' 'long ()'
2971
}
3072

3173
template<typename T>
@@ -45,6 +87,39 @@ void TemplFunc(T t) {
4587
// CHECK-NEXT: NestedNameSpecifier TypeSpec 'T'
4688
// CHECK-NEXT: DeclRefExpr{{.*}}'t' 'T'
4789

90+
#pragma acc update wait async
91+
// CHECK-NEXT: OpenACCUpdateConstruct{{.*}}update
92+
// CHECK-NEXT: wait clause
93+
// CHECK-NEXT: <<<NULL>>>
94+
// CHECK-NEXT: async clause
95+
#pragma acc update wait(T::value, t) async(T::value)
96+
// CHECK-NEXT: OpenACCUpdateConstruct{{.*}}update
97+
// CHECK-NEXT: wait clause
98+
// CHECK-NEXT: <<<NULL>>>
99+
// CHECK-NEXT: DependentScopeDeclRefExpr{{.*}}'<dependent type>'
100+
// CHECK-NEXT: NestedNameSpecifier TypeSpec 'T'
101+
// CHECK-NEXT: DeclRefExpr{{.*}} 't' 'T'
102+
// CHECK-NEXT: async clause
103+
// CHECK-NEXT: DependentScopeDeclRefExpr{{.*}}'<dependent type>'
104+
// CHECK-NEXT: NestedNameSpecifier TypeSpec 'T'
105+
#pragma acc update wait(queues:T::value, t) async(t)
106+
// CHECK-NEXT: OpenACCUpdateConstruct{{.*}}update
107+
// CHECK-NEXT: wait clause
108+
// CHECK-NEXT: <<<NULL>>>
109+
// CHECK-NEXT: DependentScopeDeclRefExpr{{.*}}'<dependent type>'
110+
// CHECK-NEXT: NestedNameSpecifier TypeSpec 'T'
111+
// CHECK-NEXT: DeclRefExpr{{.*}} 't' 'T'
112+
// CHECK-NEXT: async clause
113+
// CHECK-NEXT: DeclRefExpr{{.*}} 't' 'T'
114+
#pragma acc update wait(devnum: T::value:t, T::value)
115+
// CHECK-NEXT: OpenACCUpdateConstruct{{.*}}update
116+
// CHECK-NEXT: wait clause
117+
// CHECK-NEXT: DependentScopeDeclRefExpr{{.*}}'<dependent type>'
118+
// CHECK-NEXT: NestedNameSpecifier TypeSpec 'T'
119+
// CHECK-NEXT: DeclRefExpr{{.*}} 't' 'T'
120+
// CHECK-NEXT: DependentScopeDeclRefExpr{{.*}}'<dependent type>'
121+
// CHECK-NEXT: NestedNameSpecifier TypeSpec 'T'
122+
48123
// Instantiation:
49124
// CHECK-NEXT: FunctionDecl{{.*}} TemplFunc 'void (SomeStruct)' implicit_instantiation
50125
// CHECK-NEXT: TemplateArgument type 'SomeStruct'
@@ -63,7 +138,56 @@ void TemplFunc(T t) {
63138
// CHECK-NEXT: ImplicitCastExpr {{.*}}'unsigned int'
64139
// CHECK-NEXT: CXXMemberCallExpr{{.*}}'unsigned int'
65140
// CHECK-NEXT: MemberExpr{{.*}}.operator unsigned int
66-
// CHECk-NEXT: DeclRefExpr{{.*}}'t' 'SomeStruct'
141+
// CHECK-NEXT: DeclRefExpr{{.*}}'t' 'SomeStruct'
142+
143+
// CHECK-NEXT: OpenACCUpdateConstruct{{.*}}update
144+
// CHECK-NEXT: wait clause
145+
// CHECK-NEXT: <<<NULL>>>
146+
// CHECK-NEXT: async clause
147+
148+
// CHECK-NEXT: OpenACCUpdateConstruct{{.*}}update
149+
// CHECK-NEXT: wait clause
150+
// CHECK-NEXT: <<<NULL>>>
151+
// CHECK-NEXT: ImplicitCastExpr{{.*}}'unsigned int'
152+
// CHECK-NEXT: DeclRefExpr{{.*}}'value' 'const unsigned int'
153+
// CHECK-NEXT: NestedNameSpecifier TypeSpec 'SomeStruct'
154+
// CHECK-NEXT: ImplicitCastExpr{{.*}}'unsigned int'
155+
// CHECK-NEXT: CXXMemberCallExpr{{.*}}'unsigned int'
156+
// CHECK-NEXT: MemberExpr{{.*}}.operator unsigned int
157+
// CHECK-NEXT: DeclRefExpr{{.*}}'t' 'SomeStruct'
158+
// CHECK-NEXT: async clause
159+
// CHECK-NEXT: ImplicitCastExpr{{.*}}'unsigned int'
160+
// CHECK-NEXT: DeclRefExpr{{.*}}'value' 'const unsigned int'
161+
// CHECK-NEXT: NestedNameSpecifier TypeSpec 'SomeStruct'
162+
163+
// CHECK-NEXT: OpenACCUpdateConstruct{{.*}}update
164+
// CHECK-NEXT: wait clause
165+
// CHECK-NEXT: <<<NULL>>>
166+
// CHECK-NEXT: ImplicitCastExpr{{.*}}'unsigned int'
167+
// CHECK-NEXT: DeclRefExpr{{.*}}'value' 'const unsigned int'
168+
// CHECK-NEXT: NestedNameSpecifier TypeSpec 'SomeStruct'
169+
// CHECK-NEXT: ImplicitCastExpr{{.*}}'unsigned int'
170+
// CHECK-NEXT: CXXMemberCallExpr{{.*}}'unsigned int'
171+
// CHECK-NEXT: MemberExpr{{.*}}.operator unsigned int
172+
// CHECK-NEXT: DeclRefExpr{{.*}}'t' 'SomeStruct'
173+
// CHECK-NEXT: async clause
174+
// CHECK-NEXT: ImplicitCastExpr{{.*}}'unsigned int'
175+
// CHECK-NEXT: CXXMemberCallExpr{{.*}}'unsigned int'
176+
// CHECK-NEXT: MemberExpr{{.*}}.operator unsigned int
177+
// CHECK-NEXT: DeclRefExpr{{.*}}'t' 'SomeStruct'
178+
179+
// CHECK-NEXT: OpenACCUpdateConstruct{{.*}}update
180+
// CHECK-NEXT: wait clause
181+
// CHECK-NEXT: ImplicitCastExpr{{.*}}'unsigned int'
182+
// CHECK-NEXT: DeclRefExpr{{.*}}'value' 'const unsigned int'
183+
// CHECK-NEXT: NestedNameSpecifier TypeSpec 'SomeStruct'
184+
// CHECK-NEXT: ImplicitCastExpr{{.*}}'unsigned int'
185+
// CHECK-NEXT: CXXMemberCallExpr{{.*}}'unsigned int'
186+
// CHECK-NEXT: MemberExpr{{.*}}.operator unsigned int
187+
// CHECK-NEXT: DeclRefExpr{{.*}}'t' 'SomeStruct'
188+
// CHECK-NEXT: ImplicitCastExpr{{.*}}'unsigned int'
189+
// CHECK-NEXT: DeclRefExpr{{.*}}'value' 'const unsigned int'
190+
// CHECK-NEXT: NestedNameSpecifier TypeSpec 'SomeStruct'
67191
}
68192

69193
struct SomeStruct{

clang/test/SemaOpenACC/update-construct.cpp

Lines changed: 35 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
// RUN: %clang_cc1 %s -fopenacc -verify
22

33
struct NotConvertible{} NC;
4+
int getI();
45
void uses() {
56
int Var;
6-
// expected-warning@+2{{OpenACC clause 'async' not yet implemented}}
77
// expected-warning@+1{{OpenACC clause 'self' not yet implemented}}
88
#pragma acc update async self(Var)
9-
// expected-warning@+2{{OpenACC clause 'wait' not yet implemented}}
109
// expected-warning@+1{{OpenACC clause 'self' not yet implemented}}
1110
#pragma acc update wait self(Var)
1211
// expected-warning@+2{{OpenACC clause 'self' not yet implemented}}
@@ -45,20 +44,16 @@ void uses() {
4544
// expected-warning@+1{{OpenACC clause 'device' not yet implemented}}
4645
#pragma acc update device_type(I) device(Var)
4746
// These 2 are OK.
48-
// expected-warning@+3{{OpenACC clause 'self' not yet implemented}}
49-
// expected-warning@+2{{OpenACC clause 'device_type' not yet implemented}}
50-
// expected-warning@+1{{OpenACC clause 'async' not yet implemented}}
47+
// expected-warning@+2{{OpenACC clause 'self' not yet implemented}}
48+
// expected-warning@+1{{OpenACC clause 'device_type' not yet implemented}}
5149
#pragma acc update self(Var) device_type(I) async
52-
// expected-warning@+3{{OpenACC clause 'self' not yet implemented}}
53-
// expected-warning@+2{{OpenACC clause 'device_type' not yet implemented}}
54-
// expected-warning@+1{{OpenACC clause 'wait' not yet implemented}}
50+
// expected-warning@+2{{OpenACC clause 'self' not yet implemented}}
51+
// expected-warning@+1{{OpenACC clause 'device_type' not yet implemented}}
5552
#pragma acc update self(Var) device_type(I) wait
5653

5754
// TODO: OpenACC: These should diagnose because there isn't at least 1 of
5855
// 'self', 'host', or 'device'.
59-
// expected-warning@+1{{OpenACC clause 'async' not yet implemented}}
6056
#pragma acc update async
61-
// expected-warning@+1{{OpenACC clause 'wait' not yet implemented}}
6257
#pragma acc update wait
6358
// expected-warning@+1{{OpenACC clause 'device_type' not yet implemented}}
6459
#pragma acc update device_type(I)
@@ -108,4 +103,34 @@ void uses() {
108103
for (;;)
109104
// expected-warning@+1{{OpenACC clause 'device' not yet implemented}}
110105
#pragma acc update device(Var)
106+
107+
// Checking for 'async', which requires an 'int' expression.
108+
#pragma acc update async
109+
110+
#pragma acc update async(getI())
111+
// expected-error@+2{{expected ')'}}
112+
// expected-note@+1{{to match this '('}}
113+
#pragma acc update async(getI(), getI())
114+
// expected-error@+2{{OpenACC 'async' clause cannot appear more than once on a 'update' directive}}
115+
// expected-note@+1{{previous clause is here}}
116+
#pragma acc update async(getI()) async(getI())
117+
// expected-error@+1{{OpenACC clause 'async' requires expression of integer type ('struct NotConvertible' invalid)}}
118+
#pragma acc update async(NC)
119+
120+
// Checking for 'wait', which has a complicated set arguments.
121+
#pragma acc update wait
122+
#pragma acc update wait()
123+
#pragma acc update wait(getI(), getI())
124+
#pragma acc update wait(devnum: getI(): getI())
125+
#pragma acc update wait(devnum: getI(): queues: getI(), getI())
126+
// expected-error@+1{{OpenACC clause 'wait' requires expression of integer type ('struct NotConvertible' invalid)}}
127+
#pragma acc update wait(devnum:NC : 5)
128+
// expected-error@+1{{OpenACC clause 'wait' requires expression of integer type ('struct NotConvertible' invalid)}}
129+
#pragma acc update wait(devnum:5 : NC)
130+
131+
int arr[5];
132+
// expected-error@+3{{OpenACC clause 'wait' requires expression of integer type ('int[5]' invalid)}}
133+
// expected-error@+2{{OpenACC clause 'wait' requires expression of integer type ('int[5]' invalid)}}
134+
// expected-error@+1{{OpenACC clause 'wait' requires expression of integer type ('struct NotConvertible' invalid)}}
135+
#pragma acc update wait(devnum:arr : queues: arr, NC, 5)
111136
}

0 commit comments

Comments
 (0)