@@ -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