Skip to content

Commit afe5057

Browse files
committed
[OPENMP] Do not capture local static variables.
Previously we may erroneously try to capture locally declared static variables, which will lead to crash for target-based constructs. Patch fixes this problem. llvm-svn: 315076
1 parent 1fe643a commit afe5057

File tree

2 files changed

+42
-1
lines changed

2 files changed

+42
-1
lines changed

clang/lib/Sema/SemaOpenMP.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1838,6 +1838,10 @@ class DSAAttrChecker : public StmtVisitor<DSAAttrChecker, void> {
18381838
if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second)
18391839
return;
18401840

1841+
// Skip internally declared static variables.
1842+
if (VD->hasGlobalStorage() && !CS->capturesVariable(VD))
1843+
return;
1844+
18411845
auto ELoc = E->getExprLoc();
18421846
auto DKind = Stack->getCurrentDirective();
18431847
// The default(none) clause requires that each variable that is referenced

clang/test/OpenMP/target_codegen.cpp

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,9 @@
3434
// code, only 6 will have mapped arguments, and only 4 have all-constant map
3535
// sizes.
3636

37-
// CHECK-DAG: [[SIZET2:@.+]] = private unnamed_addr constant [1 x i{{32|64}}] [i[[SZ:32|64]] 2]
37+
// CHECK-DAG: [[SIZET:@.+]] = private unnamed_addr constant [2 x i[[SZ]]] [i[[SZ]] 0, i[[SZ]] 4]
38+
// CHECK-DAG: [[MAPT:@.+]] = private unnamed_addr constant [2 x i32] [i32 32, i32 288]
39+
// CHECK-DAG: [[SIZET2:@.+]] = private unnamed_addr constant [1 x i{{32|64}}] [i[[SZ]] 2]
3840
// CHECK-DAG: [[MAPT2:@.+]] = private unnamed_addr constant [1 x i32] [i32 288]
3941
// CHECK-DAG: [[SIZET3:@.+]] = private unnamed_addr constant [2 x i[[SZ]]] [i[[SZ]] 4, i[[SZ]] 2]
4042
// CHECK-DAG: [[MAPT3:@.+]] = private unnamed_addr constant [2 x i32] [i32 288, i32 288]
@@ -59,6 +61,7 @@
5961
// TCHECK: @{{.+}} = constant [[ENTTY]]
6062
// TCHECK: @{{.+}} = constant [[ENTTY]]
6163
// TCHECK: @{{.+}} = constant [[ENTTY]]
64+
// TCHECK: @{{.+}} = {{.*}}constant [[ENTTY]]
6265
// TCHECK-NOT: @{{.+}} = constant [[ENTTY]]
6366

6467
// Check if offloading descriptor is created.
@@ -91,6 +94,7 @@ int foo(int n) {
9194
double c[5][10];
9295
double cn[5][n];
9396
TT<long long, char> d;
97+
static long *plocal;
9498

9599
// CHECK: [[ADD:%.+]] = add nsw i32
96100
// CHECK: store i32 [[ADD]], i32* [[CAPTURE:%.+]],
@@ -106,6 +110,39 @@ int foo(int n) {
106110
{
107111
}
108112

113+
// CHECK: [[ADD:%.+]] = add nsw i32
114+
// CHECK: store i32 [[ADD]], i32* [[CAPTURE:%.+]],
115+
// CHECK-DAG: [[LD:%.+]] = load i32, i32* [[CAPTURE]],
116+
// CHECK-DAG: [[RET:%.+]] = call i32 @__tgt_target(i32 [[LD]], i8* @{{[^,]+}}, i32 2, i8** [[BPR:%[^,]+]], i8** [[PR:%[^,]+]], i[[SZ]]* getelementptr inbounds ([2 x i[[SZ]]], [2 x i[[SZ]]]* [[SIZET]], i32 0, i32 0), i32* getelementptr inbounds ([2 x i32], [2 x i32]* [[MAPT]], i32 0, i32 0)
117+
// CHECK-DAG: [[BPR]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[BP:%[^,]+]], i32 0, i32 0
118+
// CHECK-DAG: [[PR]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[P:%[^,]+]], i32 0, i32 0
119+
120+
// CHECK-DAG: [[BPADDR0:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[BP]], i32 0, i32 0
121+
// CHECK-DAG: [[PADDR0:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[P]], i32 0, i32 0
122+
// CHECK-DAG: [[CBPADDR0:%.+]] = bitcast i8** [[BPADDR0]] to i[[SZ]]**
123+
// CHECK-DAG: [[CPADDR0:%.+]] = bitcast i8** [[PADDR0]] to i[[SZ]]**
124+
// CHECK-DAG: store i[[SZ]]* [[BP0:%[^,]+]], i[[SZ]]** [[CBPADDR0]]
125+
// CHECK-DAG: store i[[SZ]]* [[BP0]], i[[SZ]]** [[CPADDR0]]
126+
127+
// CHECK-DAG: [[BPADDR1:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[BP]], i32 0, i32 1
128+
// CHECK-DAG: [[PADDR1:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[P]], i32 0, i32 1
129+
// CHECK-DAG: [[CBPADDR1:%.+]] = bitcast i8** [[BPADDR1]] to i[[SZ]]*
130+
// CHECK-DAG: [[CPADDR1:%.+]] = bitcast i8** [[PADDR1]] to i[[SZ]]*
131+
// CHECK-DAG: store i[[SZ]] [[BP1:%[^,]+]], i[[SZ]]* [[CBPADDR1]]
132+
// CHECK-DAG: store i[[SZ]] [[BP1]], i[[SZ]]* [[CPADDR1]]
133+
// CHECK: [[ERROR:%.+]] = icmp ne i32 [[RET]], 0
134+
// CHECK-NEXT: br i1 [[ERROR]], label %[[FAIL:[^,]+]], label %[[END:[^,]+]]
135+
// CHECK: [[FAIL]]
136+
// CHECK: call void [[HVT0_:@.+]](i[[SZ]]* [[BP0]], i[[SZ]] [[BP1]])
137+
// CHECK-NEXT: br label %[[END]]
138+
// CHECK: [[END]]
139+
#pragma omp target device(global + a)
140+
{
141+
static int local1;
142+
*plocal = global;
143+
local1 = global;
144+
}
145+
109146
// CHECK: call void [[HVT1:@.+]](i[[SZ]] {{[^,]+}})
110147
#pragma omp target if(0) firstprivate(global)
111148
{

0 commit comments

Comments
 (0)