@@ -306,9 +306,10 @@ CIRGenFunction::emitOpenACCCacheConstruct(const OpenACCCacheConstruct &s) {
306306
307307mlir::LogicalResult
308308CIRGenFunction::emitOpenACCAtomicConstruct (const OpenACCAtomicConstruct &s) {
309- // For now, we are only support 'read', so diagnose. We can switch on the kind
310- // later once we start implementing the other 3 forms.
311- if (s.getAtomicKind () != OpenACCAtomicKind::Read) {
309+ // For now, we are only support 'read'/'write', so diagnose. We can switch on
310+ // the kind later once we start implementing the other 2 forms. While we
311+ if (s.getAtomicKind () != OpenACCAtomicKind::Read &&
312+ s.getAtomicKind () != OpenACCAtomicKind::Write) {
312313 cgm.errorNYI (s.getSourceRange (), " OpenACC Atomic Construct" );
313314 return mlir::failure ();
314315 }
@@ -318,17 +319,41 @@ CIRGenFunction::emitOpenACCAtomicConstruct(const OpenACCAtomicConstruct &s) {
318319 // it has custom emit logic.
319320 mlir::Location start = getLoc (s.getSourceRange ().getBegin ());
320321 OpenACCAtomicConstruct::StmtInfo inf = s.getAssociatedStmtInfo ();
321- // Atomic 'read' only permits 'v = x', where v and x are both scalar L values.
322- // The getAssociatedStmtInfo strips off implicit casts, which includes
323- // implicit conversions and L-to-R-Value conversions, so we can just emit it
324- // as an L value. The Flang implementation has no problem with different
325- // types, so it appears that the dialect can handle the conversions.
326- mlir::Value v = emitLValue (inf.V ).getPointer ();
327- mlir::Value x = emitLValue (inf.X ).getPointer ();
328- mlir::Type resTy = convertType (inf.V ->getType ());
329- auto op = mlir::acc::AtomicReadOp::create (builder, start, x, v, resTy,
330- /* ifCond=*/ {});
331- emitOpenACCClauses (op, s.getDirectiveKind (), s.getDirectiveLoc (),
332- s.clauses ());
333- return mlir::success ();
322+
323+ switch (s.getAtomicKind ()) {
324+ case OpenACCAtomicKind::None:
325+ case OpenACCAtomicKind::Update:
326+ case OpenACCAtomicKind::Capture:
327+ llvm_unreachable (" Unimplemented atomic construct type, should have "
328+ " diagnosed/returned above" );
329+ return mlir::failure ();
330+ case OpenACCAtomicKind::Read: {
331+
332+ // Atomic 'read' only permits 'v = x', where v and x are both scalar L
333+ // values. The getAssociatedStmtInfo strips off implicit casts, which
334+ // includes implicit conversions and L-to-R-Value conversions, so we can
335+ // just emit it as an L value. The Flang implementation has no problem with
336+ // different types, so it appears that the dialect can handle the
337+ // conversions.
338+ mlir::Value v = emitLValue (inf.V ).getPointer ();
339+ mlir::Value x = emitLValue (inf.X ).getPointer ();
340+ mlir::Type resTy = convertType (inf.V ->getType ());
341+ auto op = mlir::acc::AtomicReadOp::create (builder, start, x, v, resTy,
342+ /* ifCond=*/ {});
343+ emitOpenACCClauses (op, s.getDirectiveKind (), s.getDirectiveLoc (),
344+ s.clauses ());
345+ return mlir::success ();
346+ }
347+ case OpenACCAtomicKind::Write: {
348+ mlir::Value x = emitLValue (inf.X ).getPointer ();
349+ mlir::Value expr = emitAnyExpr (inf.Expr ).getValue ();
350+ auto op = mlir::acc::AtomicWriteOp::create (builder, start, x, expr,
351+ /* ifCond=*/ {});
352+ emitOpenACCClauses (op, s.getDirectiveKind (), s.getDirectiveLoc (),
353+ s.clauses ());
354+ return mlir::success ();
355+ }
356+ }
357+
358+ llvm_unreachable (" unknown OpenACC atomic kind" );
334359}
0 commit comments