Author: Alexey Bataev Date: 2020-01-28T11:40:31-05:00 New Revision: f117f2cc7837fbca75bf97fcca2a55423f3023ca
URL: https://github.com/llvm/llvm-project/commit/f117f2cc7837fbca75bf97fcca2a55423f3023ca DIFF: https://github.com/llvm/llvm-project/commit/f117f2cc7837fbca75bf97fcca2a55423f3023ca.diff LOG: [OPENMP50]Check for lastprivate conditional updates in atomic constructs. Added analysis in atomic constrcuts to support checks for updates of conditional lastprivate variables. Added: Modified: clang/lib/CodeGen/CGStmtOpenMP.cpp clang/test/OpenMP/parallel_for_lastprivate_conditional.cpp Removed: ################################################################################ diff --git a/clang/lib/CodeGen/CGStmtOpenMP.cpp b/clang/lib/CodeGen/CGStmtOpenMP.cpp index 0e41d520da20..fcc619da837d 100644 --- a/clang/lib/CodeGen/CGStmtOpenMP.cpp +++ b/clang/lib/CodeGen/CGStmtOpenMP.cpp @@ -3984,6 +3984,7 @@ static void emitOMPAtomicReadExpr(CodeGenFunction &CGF, bool IsSeqCst, if (IsSeqCst) CGF.CGM.getOpenMPRuntime().emitFlush(CGF, llvm::None, Loc); CGF.emitOMPSimpleStore(VLValue, Res, X->getType().getNonReferenceType(), Loc); + CGF.CGM.getOpenMPRuntime().checkAndEmitLastprivateConditional(CGF, V); } static void emitOMPAtomicWriteExpr(CodeGenFunction &CGF, bool IsSeqCst, @@ -3992,6 +3993,7 @@ static void emitOMPAtomicWriteExpr(CodeGenFunction &CGF, bool IsSeqCst, // x = expr; assert(X->isLValue() && "X of 'omp atomic write' is not lvalue"); emitSimpleAtomicStore(CGF, IsSeqCst, CGF.EmitLValue(X), CGF.EmitAnyExpr(E)); + CGF.CGM.getOpenMPRuntime().checkAndEmitLastprivateConditional(CGF, X); // OpenMP, 2.12.6, atomic Construct // Any atomic construct with a seq_cst clause forces the atomically // performed operation to include an implicit flush operation without a @@ -4148,6 +4150,7 @@ static void emitOMPAtomicUpdateExpr(CodeGenFunction &CGF, bool IsSeqCst, }; (void)CGF.EmitOMPAtomicSimpleUpdateExpr( XLValue, ExprRValue, BOUE->getOpcode(), IsXLHSInRHSPart, AO, Loc, Gen); + CGF.CGM.getOpenMPRuntime().checkAndEmitLastprivateConditional(CGF, X); // OpenMP, 2.12.6, atomic Construct // Any atomic construct with a seq_cst clause forces the atomically // performed operation to include an implicit flush operation without a @@ -4214,6 +4217,7 @@ static void emitOMPAtomicCaptureExpr(CodeGenFunction &CGF, bool IsSeqCst, }; auto Res = CGF.EmitOMPAtomicSimpleUpdateExpr( XLValue, ExprRValue, BOUE->getOpcode(), IsXLHSInRHSPart, AO, Loc, Gen); + CGF.CGM.getOpenMPRuntime().checkAndEmitLastprivateConditional(CGF, X); if (Res.first) { // 'atomicrmw' instruction was generated. if (IsPostfixUpdate) { @@ -4240,6 +4244,7 @@ static void emitOMPAtomicCaptureExpr(CodeGenFunction &CGF, bool IsSeqCst, auto Res = CGF.EmitOMPAtomicSimpleUpdateExpr( XLValue, ExprRValue, /*BO=*/BO_Assign, /*IsXLHSInRHSPart=*/false, AO, Loc, Gen); + CGF.CGM.getOpenMPRuntime().checkAndEmitLastprivateConditional(CGF, X); if (Res.first) { // 'atomicrmw' instruction was generated. NewVVal = IsPostfixUpdate ? Res.second : ExprRValue; @@ -4247,6 +4252,7 @@ static void emitOMPAtomicCaptureExpr(CodeGenFunction &CGF, bool IsSeqCst, } // Emit post-update store to 'v' of old/new 'x' value. CGF.emitOMPSimpleStore(VLValue, NewVVal, NewVValType, Loc); + CGF.CGM.getOpenMPRuntime().checkAndEmitLastprivateConditional(CGF, V); // OpenMP, 2.12.6, atomic Construct // Any atomic construct with a seq_cst clause forces the atomically // performed operation to include an implicit flush operation without a diff --git a/clang/test/OpenMP/parallel_for_lastprivate_conditional.cpp b/clang/test/OpenMP/parallel_for_lastprivate_conditional.cpp index e05a5b977a4c..50282354a87a 100644 --- a/clang/test/OpenMP/parallel_for_lastprivate_conditional.cpp +++ b/clang/test/OpenMP/parallel_for_lastprivate_conditional.cpp @@ -19,6 +19,8 @@ int main() { a = 0; #pragma omp parallel reduction(+:a) num_threads(10) a += i; +#pragma omp atomic + a += i; } } return 0; @@ -40,6 +42,18 @@ int main() { // CHECK: br label %[[DONE]] // CHECK: [[DONE]]: // CHECK: call void @__kmpc_end_critical(%struct.ident_t* @{{.+}}, i32 %{{.+}}, [8 x i32]* @{{.+}}) +// CHECK: atomicrmw add i32* +// CHECK: call void @__kmpc_critical(%struct.ident_t* @{{.+}}, i32 %{{.+}}, [8 x i32]* @{{.+}}) +// CHECK: [[LAST_IV_VAL:%.+]] = load i32, i32* [[LAST_IV:@.+]], +// CHECK: [[RES:%.+]] = icmp sle i32 [[LAST_IV_VAL]], [[IV:%.+]] +// CHECK: br i1 [[RES]], label %[[THEN:.+]], label %[[DONE:.+]] +// CHECK: [[THEN]]: +// CHECK: store i32 [[IV]], i32* [[LAST_IV]], +// CHECK: [[A_VAL:%.+]] = load i32, i32* [[A_PRIV:%.+]], +// CHECK: store i32 [[A_VAL]], i32* [[A_GLOB:@.+]], +// CHECK: br label %[[DONE]] +// CHECK: [[DONE]]: +// CHECK: call void @__kmpc_end_critical(%struct.ident_t* @{{.+}}, i32 %{{.+}}, [8 x i32]* @{{.+}}) // CHECK: call void @__kmpc_for_static_fini(%struct.ident_t* @{{.+}}, i32 %{{.+}}) // CHECK: [[IS_LAST:%.+]] = load i32, i32* %{{.+}}, // CHECK: [[RES:%.+]] = icmp ne i32 [[IS_LAST]], 0 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits