Author: abataev Date: Wed Aug 16 08:58:46 2017 New Revision: 311013 URL: http://llvm.org/viewvc/llvm-project?rev=311013&view=rev Log: [OPENMP] Fix for PR28581: OpenMP linear clause - wrong results.
If worksharing construct has at least one linear item, an implicit synchronization point must be emitted to avoid possible conflict with the loading/storing values to the original variables. Added implicit barrier if the linear item is found before actual start of the worksharing construct. Modified: cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp cfe/trunk/lib/CodeGen/CodeGenFunction.h cfe/trunk/test/OpenMP/for_linear_codegen.cpp Modified: cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp?rev=311013&r1=311012&r2=311013&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp (original) +++ cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp Wed Aug 16 08:58:46 2017 @@ -1231,12 +1231,14 @@ void CodeGenFunction::EmitOMPInnerLoop( EmitBlock(LoopExit.getBlock()); } -void CodeGenFunction::EmitOMPLinearClauseInit(const OMPLoopDirective &D) { +bool CodeGenFunction::EmitOMPLinearClauseInit(const OMPLoopDirective &D) { if (!HaveInsertPoint()) - return; + return false; // Emit inits for the linear variables. + bool HasLinears = false; for (const auto *C : D.getClausesOfKind<OMPLinearClause>()) { for (auto *Init : C->inits()) { + HasLinears = true; auto *VD = cast<VarDecl>(cast<DeclRefExpr>(Init)->getDecl()); if (auto *Ref = dyn_cast<DeclRefExpr>(VD->getInit()->IgnoreImpCasts())) { AutoVarEmission Emission = EmitAutoVarAlloca(*VD); @@ -1261,6 +1263,7 @@ void CodeGenFunction::EmitOMPLinearClaus EmitIgnoredExpr(CS); } } + return HasLinears; } void CodeGenFunction::EmitOMPLinearClauseFinal( @@ -1550,7 +1553,7 @@ void CodeGenFunction::EmitOMPSimdDirecti CGF.EmitOMPSimdInit(S); emitAlignedClause(CGF, S); - CGF.EmitOMPLinearClauseInit(S); + (void)CGF.EmitOMPLinearClauseInit(S); { OMPPrivateScope LoopScope(CGF); CGF.EmitOMPPrivateLoopCounters(S, LoopScope); @@ -2170,7 +2173,7 @@ bool CodeGenFunction::EmitOMPWorksharing llvm::DenseSet<const Expr *> EmittedFinals; emitAlignedClause(*this, S); - EmitOMPLinearClauseInit(S); + bool HasLinears = EmitOMPLinearClauseInit(S); // Emit helper vars inits. std::pair<LValue, LValue> Bounds = CodeGenLoopBounds(*this, S); @@ -2184,7 +2187,7 @@ bool CodeGenFunction::EmitOMPWorksharing // Emit 'then' code. { OMPPrivateScope LoopScope(*this); - if (EmitOMPFirstprivateClause(S, LoopScope)) { + if (EmitOMPFirstprivateClause(S, LoopScope) || HasLinears) { // Emit implicit barrier to synchronize threads and avoid data races on // initialization of firstprivate variables and post-update of // lastprivate variables. Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=311013&r1=311012&r2=311013&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original) +++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Wed Aug 16 08:58:46 2017 @@ -2761,7 +2761,9 @@ public: /// and initializes them with the values according to OpenMP standard. /// /// \param D Directive (possibly) with the 'linear' clause. - void EmitOMPLinearClauseInit(const OMPLoopDirective &D); + /// \return true if at least one linear variable is found that should be + /// initialized with the value of the original variable, false otherwise. + bool EmitOMPLinearClauseInit(const OMPLoopDirective &D); typedef const llvm::function_ref<void(CodeGenFunction & /*CGF*/, llvm::Value * /*OutlinedFn*/, Modified: cfe/trunk/test/OpenMP/for_linear_codegen.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/for_linear_codegen.cpp?rev=311013&r1=311012&r2=311013&view=diff ============================================================================== --- cfe/trunk/test/OpenMP/for_linear_codegen.cpp (original) +++ cfe/trunk/test/OpenMP/for_linear_codegen.cpp Wed Aug 16 08:58:46 2017 @@ -422,6 +422,7 @@ int main() { // CHECK: [[A_PRIV:%.+]] = alloca i{{[0-9]+}}, // CHECK: [[B_PRIV:%.+]] = alloca i{{[0-9]+}}, // CHECK: [[C_PRIV:%.+]] = alloca i{{[0-9]+}}, +// CHECK: call void @__kmpc_barrier( // CHECK: store i{{[0-9]+}}* [[A_PRIV]], i{{[0-9]+}}** [[REFA:%.+]], // CHECK: store i{{[0-9]+}}* [[C_PRIV]], i{{[0-9]+}}** [[REFC:%.+]], // CHECK: call void @__kmpc_for_static_init_4( _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits