[clang-tools-extra] [clang] [llvm] [OpenMP] atomic compare fail : Codegen support (PR #75709)

via cfe-commits cfe-commits at lists.llvm.org
Sat Dec 16 10:55:43 PST 2023


https://github.com/SunilKuravinakop created https://github.com/llvm/llvm-project/pull/75709

This is a continuation of https://reviews.llvm.org/D123235 ([OpenMP] atomic compare fail : Parser & AST support). In this branch Support for codegen support for atomic compare fail is being added.

>From fe931d64741f427629407bca3e68a61bec6f2b67 Mon Sep 17 00:00:00 2001
From: Sunil Kuravinakop <kuravina at pe28vega.us.cray.com>
Date: Sat, 16 Dec 2023 11:43:35 -0600
Subject: [PATCH] Adding parameter to fail clause (i.e. memory order clause)
 for codegen.

  Changes to be committed:
 	modified:   clang/lib/CodeGen/CGStmtOpenMP.cpp
---
 clang/lib/CodeGen/CGStmtOpenMP.cpp | 51 +++++++++++++++++++++++++++---
 1 file changed, 47 insertions(+), 4 deletions(-)

diff --git a/clang/lib/CodeGen/CGStmtOpenMP.cpp b/clang/lib/CodeGen/CGStmtOpenMP.cpp
index 478d6dbf9ca81d..a502db7ac3a5e0 100644
--- a/clang/lib/CodeGen/CGStmtOpenMP.cpp
+++ b/clang/lib/CodeGen/CGStmtOpenMP.cpp
@@ -6516,10 +6516,6 @@ static void emitOMPAtomicExpr(CodeGenFunction &CGF, OpenMPClauseKind Kind,
                              IsPostfixUpdate, IsFailOnly, Loc);
     break;
   }
-  case OMPC_fail: {
-    //TODO
-    break;
-  }
   default:
     llvm_unreachable("Clause is not allowed in 'omp atomic'.");
   }
@@ -6527,6 +6523,8 @@ static void emitOMPAtomicExpr(CodeGenFunction &CGF, OpenMPClauseKind Kind,
 
 void CodeGenFunction::EmitOMPAtomicDirective(const OMPAtomicDirective &S) {
   llvm::AtomicOrdering AO = llvm::AtomicOrdering::Monotonic;
+  // Fail Memory Clause Ordering.
+  llvm::AtomicOrdering FO = llvm::AtomicOrdering::Monotonic;
   bool MemOrderingSpecified = false;
   if (S.getSingleClause<OMPSeqCstClause>()) {
     AO = llvm::AtomicOrdering::SequentiallyConsistent;
@@ -6580,6 +6578,51 @@ void CodeGenFunction::EmitOMPAtomicDirective(const OMPAtomicDirective &S) {
     }
   }
 
+  if (KindsEncountered.contains(OMPC_compare) &&
+      KindsEncountered.contains(OMPC_fail)) {
+    Kind = OMPC_compare;
+    const OMPFailClause *fC = S.getSingleClause<OMPFailClause>();
+    if (fC) {
+      OpenMPClauseKind fP = fC->getFailParameter();
+      if (fP == llvm::omp::OMPC_relaxed)
+        FO = llvm::AtomicOrdering::Monotonic;
+      else if (fP == llvm::omp::OMPC_acquire)
+        FO = llvm::AtomicOrdering::Acquire;
+      else if (fP == llvm::omp::OMPC_seq_cst)
+        FO = llvm::AtomicOrdering::SequentiallyConsistent;
+    }
+
+    // Logic for 2 memory order clauses in the atomic directive.
+    // e.g. #pragma omp atomic compare capture release fail(seq_cst)
+    //      if(x > e) { x = j; } else { k = x; }
+    // To provide the Memory Order clause in atomic directive
+    // there are 2 instructions in LLVM IR atomicrmw & cmpxchgl.
+    // 1) atomicrmw can use only 1 memory order clause and can contain the
+    //    operator in if condition.
+    // 2) cmpxchgl can use 2 memory order clauses : Success memory order clause
+    //    & fail parameter memory clause. However, cmpxchgl uses only equality
+    //    operator.
+    // We need to change atomicrmw to contain the fail parameter clause or add
+    // a new instruction in LLVM IR. Changes in LLVM IR need to be done
+    // seperately and at present we will use the logic of using the more strict
+    // memory order clause of success or fail memory order clauses for the
+    // atomicrmw. The following logic takes care of this change in the memory
+    // order clause.
+    if (AO == llvm::AtomicOrdering::Monotonic)
+      AO = FO;
+    else if (FO == llvm::AtomicOrdering::Monotonic)
+      AO = AO;
+    else if (AO == llvm::AtomicOrdering::SequentiallyConsistent ||
+             FO == llvm::AtomicOrdering::SequentiallyConsistent)
+      AO = llvm::AtomicOrdering::SequentiallyConsistent;
+    else if (AO == llvm::AtomicOrdering::Acquire)
+      AO = llvm::AtomicOrdering::Acquire;
+    else if (AO == llvm::AtomicOrdering::Release)
+      AO = llvm::AtomicOrdering::AcquireRelease;
+    else if (AO == llvm::AtomicOrdering::AcquireRelease)
+      AO = llvm::AtomicOrdering::AcquireRelease;
+  }
+
   LexicalScope Scope(*this, S.getSourceRange());
   EmitStopPoint(S.getAssociatedStmt());
   emitOMPAtomicExpr(*this, Kind, AO, S.isPostfixUpdate(), S.getX(), S.getV(),



More information about the cfe-commits mailing list