-
Notifications
You must be signed in to change notification settings - Fork 10.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[OpenMP] atomic compare fail : Codegen support #75709
[OpenMP] atomic compare fail : Codegen support #75709
Conversation
Changes to be committed: modified: clang/lib/CodeGen/CGStmtOpenMP.cpp
@llvm/pr-subscribers-flang-openmp @llvm/pr-subscribers-clang Author: None (SunilKuravinakop) ChangesThis 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. Full diff: https://github.com/llvm/llvm-project/pull/75709.diff 1 Files Affected:
diff --git a/clang/lib/CodeGen/CGStmtOpenMP.cpp b/clang/lib/CodeGen/CGStmtOpenMP.cpp
index ed426098ac6915..e2caa0d7742126 100644
--- a/clang/lib/CodeGen/CGStmtOpenMP.cpp
+++ b/clang/lib/CodeGen/CGStmtOpenMP.cpp
@@ -6508,10 +6508,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'.");
}
@@ -6519,6 +6515,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;
@@ -6572,6 +6570,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(),
|
@llvm/pr-subscribers-clang-codegen Author: None (SunilKuravinakop) ChangesThis 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. Full diff: https://github.com/llvm/llvm-project/pull/75709.diff 1 Files Affected:
diff --git a/clang/lib/CodeGen/CGStmtOpenMP.cpp b/clang/lib/CodeGen/CGStmtOpenMP.cpp
index ed426098ac6915..e2caa0d7742126 100644
--- a/clang/lib/CodeGen/CGStmtOpenMP.cpp
+++ b/clang/lib/CodeGen/CGStmtOpenMP.cpp
@@ -6508,10 +6508,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'.");
}
@@ -6519,6 +6515,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;
@@ -6572,6 +6570,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(),
|
{if(x == e) {x = v;} else {d = x;}} results in generation of cmpxchg in the LLVM IR, the memory order clause in "fail" clause is now being added. In case of other operators ">" & "<" e.g. dx = dx > de ? de : dx; result in atomicrmw in the LLVM IR. "atomicrmw" can have only one memory order clause. Currently, the memory order clause is ignored. 2) Test cases for codegen 3) In SemaOpenMP.cpp, added EncounteredAtomicKinds.contains(OMPC_compare) instead of AtomicKind == OMPC_compare. This was to accomodate where AtomicKind is OMPC_capture. Changes to be committed: modified: clang/lib/CodeGen/CGStmtOpenMP.cpp modified: clang/lib/Sema/SemaOpenMP.cpp modified: clang/test/OpenMP/atomic_compare_codegen.cpp modified: llvm/include/llvm/Frontend/OpenMP/OMPIRBuilder.h modified: llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp
clang/lib/CodeGen/CGStmtOpenMP.cpp
Outdated
if (KindsEncountered.contains(OMPC_compare) && | ||
KindsEncountered.contains(OMPC_fail)) { | ||
Kind = OMPC_compare; | ||
const OMPFailClause *fC = S.getSingleClause<OMPFailClause>(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
const OMPFailClause *fC = S.getSingleClause<OMPFailClause>(); | |
const auto *FC = S.getSingleClause<OMPFailClause>(); |
clang/lib/CodeGen/CGStmtOpenMP.cpp
Outdated
Kind = OMPC_compare; | ||
const OMPFailClause *fC = S.getSingleClause<OMPFailClause>(); | ||
if (fC) { | ||
OpenMPClauseKind fP = fC->getFailParameter(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OpenMPClauseKind fP = fC->getFailParameter(); | |
OpenMPClauseKind FP = fC->getFailParameter(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Aside from Alexey's comments, LGTM.
Changed the variable names of "fail" clause and the parameter to this fail clause more self-explanatory.
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.