Commit f117f2cc authored by Alexey Bataev's avatar Alexey Bataev
Browse files

[OPENMP50]Check for lastprivate conditional updates in atomic

constructs.

Added analysis in atomic constrcuts to support checks for updates of
conditional lastprivate variables.
parent 9c54b423
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -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
+14 −0
Original line number Diff line number Diff line
@@ -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