forked from OSchip/llvm-project
[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. llvm-svn: 311013
This commit is contained in:
parent
cd21378ff6
commit
8c3edfef6b
|
@ -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::EmitOMPLinearClauseInit(const OMPLoopDirective &D) {
|
|||
EmitIgnoredExpr(CS);
|
||||
}
|
||||
}
|
||||
return HasLinears;
|
||||
}
|
||||
|
||||
void CodeGenFunction::EmitOMPLinearClauseFinal(
|
||||
|
@ -1550,7 +1553,7 @@ void CodeGenFunction::EmitOMPSimdDirective(const OMPSimdDirective &S) {
|
|||
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::EmitOMPWorksharingLoop(
|
|||
|
||||
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::EmitOMPWorksharingLoop(
|
|||
// 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.
|
||||
|
|
|
@ -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*/,
|
||||
|
|
|
@ -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(
|
||||
|
|
Loading…
Reference in New Issue