Skip to content

Commit f117f2c

Browse files
committed
[OPENMP50]Check for lastprivate conditional updates in atomic
constructs. Added analysis in atomic constrcuts to support checks for updates of conditional lastprivate variables.
1 parent 9c54b42 commit f117f2c

File tree

2 files changed

+20
-0
lines changed

2 files changed

+20
-0
lines changed

clang/lib/CodeGen/CGStmtOpenMP.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3984,6 +3984,7 @@ static void emitOMPAtomicReadExpr(CodeGenFunction &CGF, bool IsSeqCst,
39843984
if (IsSeqCst)
39853985
CGF.CGM.getOpenMPRuntime().emitFlush(CGF, llvm::None, Loc);
39863986
CGF.emitOMPSimpleStore(VLValue, Res, X->getType().getNonReferenceType(), Loc);
3987+
CGF.CGM.getOpenMPRuntime().checkAndEmitLastprivateConditional(CGF, V);
39873988
}
39883989

39893990
static void emitOMPAtomicWriteExpr(CodeGenFunction &CGF, bool IsSeqCst,
@@ -3992,6 +3993,7 @@ static void emitOMPAtomicWriteExpr(CodeGenFunction &CGF, bool IsSeqCst,
39923993
// x = expr;
39933994
assert(X->isLValue() && "X of 'omp atomic write' is not lvalue");
39943995
emitSimpleAtomicStore(CGF, IsSeqCst, CGF.EmitLValue(X), CGF.EmitAnyExpr(E));
3996+
CGF.CGM.getOpenMPRuntime().checkAndEmitLastprivateConditional(CGF, X);
39953997
// OpenMP, 2.12.6, atomic Construct
39963998
// Any atomic construct with a seq_cst clause forces the atomically
39973999
// performed operation to include an implicit flush operation without a
@@ -4148,6 +4150,7 @@ static void emitOMPAtomicUpdateExpr(CodeGenFunction &CGF, bool IsSeqCst,
41484150
};
41494151
(void)CGF.EmitOMPAtomicSimpleUpdateExpr(
41504152
XLValue, ExprRValue, BOUE->getOpcode(), IsXLHSInRHSPart, AO, Loc, Gen);
4153+
CGF.CGM.getOpenMPRuntime().checkAndEmitLastprivateConditional(CGF, X);
41514154
// OpenMP, 2.12.6, atomic Construct
41524155
// Any atomic construct with a seq_cst clause forces the atomically
41534156
// performed operation to include an implicit flush operation without a
@@ -4214,6 +4217,7 @@ static void emitOMPAtomicCaptureExpr(CodeGenFunction &CGF, bool IsSeqCst,
42144217
};
42154218
auto Res = CGF.EmitOMPAtomicSimpleUpdateExpr(
42164219
XLValue, ExprRValue, BOUE->getOpcode(), IsXLHSInRHSPart, AO, Loc, Gen);
4220+
CGF.CGM.getOpenMPRuntime().checkAndEmitLastprivateConditional(CGF, X);
42174221
if (Res.first) {
42184222
// 'atomicrmw' instruction was generated.
42194223
if (IsPostfixUpdate) {
@@ -4240,13 +4244,15 @@ static void emitOMPAtomicCaptureExpr(CodeGenFunction &CGF, bool IsSeqCst,
42404244
auto Res = CGF.EmitOMPAtomicSimpleUpdateExpr(
42414245
XLValue, ExprRValue, /*BO=*/BO_Assign, /*IsXLHSInRHSPart=*/false, AO,
42424246
Loc, Gen);
4247+
CGF.CGM.getOpenMPRuntime().checkAndEmitLastprivateConditional(CGF, X);
42434248
if (Res.first) {
42444249
// 'atomicrmw' instruction was generated.
42454250
NewVVal = IsPostfixUpdate ? Res.second : ExprRValue;
42464251
}
42474252
}
42484253
// Emit post-update store to 'v' of old/new 'x' value.
42494254
CGF.emitOMPSimpleStore(VLValue, NewVVal, NewVValType, Loc);
4255+
CGF.CGM.getOpenMPRuntime().checkAndEmitLastprivateConditional(CGF, V);
42504256
// OpenMP, 2.12.6, atomic Construct
42514257
// Any atomic construct with a seq_cst clause forces the atomically
42524258
// performed operation to include an implicit flush operation without a

clang/test/OpenMP/parallel_for_lastprivate_conditional.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ int main() {
1919
a = 0;
2020
#pragma omp parallel reduction(+:a) num_threads(10)
2121
a += i;
22+
#pragma omp atomic
23+
a += i;
2224
}
2325
}
2426
return 0;
@@ -40,6 +42,18 @@ int main() {
4042
// CHECK: br label %[[DONE]]
4143
// CHECK: [[DONE]]:
4244
// CHECK: call void @__kmpc_end_critical(%struct.ident_t* @{{.+}}, i32 %{{.+}}, [8 x i32]* @{{.+}})
45+
// CHECK: atomicrmw add i32*
46+
// CHECK: call void @__kmpc_critical(%struct.ident_t* @{{.+}}, i32 %{{.+}}, [8 x i32]* @{{.+}})
47+
// CHECK: [[LAST_IV_VAL:%.+]] = load i32, i32* [[LAST_IV:@.+]],
48+
// CHECK: [[RES:%.+]] = icmp sle i32 [[LAST_IV_VAL]], [[IV:%.+]]
49+
// CHECK: br i1 [[RES]], label %[[THEN:.+]], label %[[DONE:.+]]
50+
// CHECK: [[THEN]]:
51+
// CHECK: store i32 [[IV]], i32* [[LAST_IV]],
52+
// CHECK: [[A_VAL:%.+]] = load i32, i32* [[A_PRIV:%.+]],
53+
// CHECK: store i32 [[A_VAL]], i32* [[A_GLOB:@.+]],
54+
// CHECK: br label %[[DONE]]
55+
// CHECK: [[DONE]]:
56+
// CHECK: call void @__kmpc_end_critical(%struct.ident_t* @{{.+}}, i32 %{{.+}}, [8 x i32]* @{{.+}})
4357
// CHECK: call void @__kmpc_for_static_fini(%struct.ident_t* @{{.+}}, i32 %{{.+}})
4458
// CHECK: [[IS_LAST:%.+]] = load i32, i32* %{{.+}},
4559
// CHECK: [[RES:%.+]] = icmp ne i32 [[IS_LAST]], 0

0 commit comments

Comments
 (0)