[clang] 49ee8b5 - [OpenMP] atomic compare fail : Codegen support (#75709)
via cfe-commits
cfe-commits at lists.llvm.org
Tue Jan 2 09:16:08 PST 2024
Author: SunilKuravinakop
Date: 2024-01-02T22:46:02+05:30
New Revision: 49ee8b53ef39c158d40d76128828379dd34ea61f
URL: https://github.com/llvm/llvm-project/commit/49ee8b53ef39c158d40d76128828379dd34ea61f
DIFF: https://github.com/llvm/llvm-project/commit/49ee8b53ef39c158d40d76128828379dd34ea61f.diff
LOG: [OpenMP] atomic compare fail : Codegen support (#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.
---------
Co-authored-by: Sunil Kuravinakop
Added:
Modified:
clang/lib/CodeGen/CGStmtOpenMP.cpp
clang/lib/Sema/SemaOpenMP.cpp
clang/test/OpenMP/atomic_compare_codegen.cpp
llvm/include/llvm/Frontend/OpenMP/OMPIRBuilder.h
llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp
Removed:
################################################################################
diff --git a/clang/lib/CodeGen/CGStmtOpenMP.cpp b/clang/lib/CodeGen/CGStmtOpenMP.cpp
index ed426098ac6915..e362c9da51fe31 100644
--- a/clang/lib/CodeGen/CGStmtOpenMP.cpp
+++ b/clang/lib/CodeGen/CGStmtOpenMP.cpp
@@ -6406,13 +6406,11 @@ static void emitOMPAtomicCaptureExpr(CodeGenFunction &CGF,
}
}
-static void emitOMPAtomicCompareExpr(CodeGenFunction &CGF,
- llvm::AtomicOrdering AO, const Expr *X,
- const Expr *V, const Expr *R,
- const Expr *E, const Expr *D,
- const Expr *CE, bool IsXBinopExpr,
- bool IsPostfixUpdate, bool IsFailOnly,
- SourceLocation Loc) {
+static void emitOMPAtomicCompareExpr(
+ CodeGenFunction &CGF, llvm::AtomicOrdering AO, llvm::AtomicOrdering FailAO,
+ const Expr *X, const Expr *V, const Expr *R, const Expr *E, const Expr *D,
+ const Expr *CE, bool IsXBinopExpr, bool IsPostfixUpdate, bool IsFailOnly,
+ SourceLocation Loc) {
llvm::OpenMPIRBuilder &OMPBuilder =
CGF.CGM.getOpenMPRuntime().getOMPBuilder();
@@ -6477,13 +6475,21 @@ static void emitOMPAtomicCompareExpr(CodeGenFunction &CGF,
R->getType().isVolatileQualified()};
}
- CGF.Builder.restoreIP(OMPBuilder.createAtomicCompare(
- CGF.Builder, XOpVal, VOpVal, ROpVal, EVal, DVal, AO, Op, IsXBinopExpr,
- IsPostfixUpdate, IsFailOnly));
+ if (FailAO == llvm::AtomicOrdering::NotAtomic) {
+ // fail clause was not mentionend on the
+ // "#pragma omp atomic compare" construct.
+ CGF.Builder.restoreIP(OMPBuilder.createAtomicCompare(
+ CGF.Builder, XOpVal, VOpVal, ROpVal, EVal, DVal, AO, Op, IsXBinopExpr,
+ IsPostfixUpdate, IsFailOnly));
+ } else
+ CGF.Builder.restoreIP(OMPBuilder.createAtomicCompare(
+ CGF.Builder, XOpVal, VOpVal, ROpVal, EVal, DVal, AO, Op, IsXBinopExpr,
+ IsPostfixUpdate, IsFailOnly, FailAO));
}
static void emitOMPAtomicExpr(CodeGenFunction &CGF, OpenMPClauseKind Kind,
- llvm::AtomicOrdering AO, bool IsPostfixUpdate,
+ llvm::AtomicOrdering AO,
+ llvm::AtomicOrdering FailAO, bool IsPostfixUpdate,
const Expr *X, const Expr *V, const Expr *R,
const Expr *E, const Expr *UE, const Expr *D,
const Expr *CE, bool IsXLHSInRHSPart,
@@ -6504,12 +6510,8 @@ static void emitOMPAtomicExpr(CodeGenFunction &CGF, OpenMPClauseKind Kind,
IsXLHSInRHSPart, Loc);
break;
case OMPC_compare: {
- emitOMPAtomicCompareExpr(CGF, AO, X, V, R, E, D, CE, IsXLHSInRHSPart,
- IsPostfixUpdate, IsFailOnly, Loc);
- break;
- }
- case OMPC_fail: {
- //TODO
+ emitOMPAtomicCompareExpr(CGF, AO, FailAO, X, V, R, E, D, CE,
+ IsXLHSInRHSPart, IsPostfixUpdate, IsFailOnly, Loc);
break;
}
default:
@@ -6519,6 +6521,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 FailAO = llvm::AtomicOrdering::NotAtomic;
bool MemOrderingSpecified = false;
if (S.getSingleClause<OMPSeqCstClause>()) {
AO = llvm::AtomicOrdering::SequentiallyConsistent;
@@ -6572,12 +6576,27 @@ void CodeGenFunction::EmitOMPAtomicDirective(const OMPAtomicDirective &S) {
}
}
+ if (KindsEncountered.contains(OMPC_compare) &&
+ KindsEncountered.contains(OMPC_fail)) {
+ Kind = OMPC_compare;
+ const auto *FailClause = S.getSingleClause<OMPFailClause>();
+ if (FailClause) {
+ OpenMPClauseKind FailParameter = FailClause->getFailParameter();
+ if (FailParameter == llvm::omp::OMPC_relaxed)
+ FailAO = llvm::AtomicOrdering::Monotonic;
+ else if (FailParameter == llvm::omp::OMPC_acquire)
+ FailAO = llvm::AtomicOrdering::Acquire;
+ else if (FailParameter == llvm::omp::OMPC_seq_cst)
+ FailAO = llvm::AtomicOrdering::SequentiallyConsistent;
+ }
+ }
+
LexicalScope Scope(*this, S.getSourceRange());
EmitStopPoint(S.getAssociatedStmt());
- emitOMPAtomicExpr(*this, Kind, AO, S.isPostfixUpdate(), S.getX(), S.getV(),
- S.getR(), S.getExpr(), S.getUpdateExpr(), S.getD(),
- S.getCondExpr(), S.isXLHSInRHSPart(), S.isFailOnly(),
- S.getBeginLoc());
+ emitOMPAtomicExpr(*this, Kind, AO, FailAO, S.isPostfixUpdate(), S.getX(),
+ S.getV(), S.getR(), S.getExpr(), S.getUpdateExpr(),
+ S.getD(), S.getCondExpr(), S.isXLHSInRHSPart(),
+ S.isFailOnly(), S.getBeginLoc());
}
static void emitCommonOMPTargetDirective(CodeGenFunction &CGF,
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index 3826994ef2126c..f34d2959dc6191 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -12683,7 +12683,7 @@ StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses,
break;
}
case OMPC_fail: {
- if (AtomicKind != OMPC_compare) {
+ if (!EncounteredAtomicKinds.contains(OMPC_compare)) {
Diag(C->getBeginLoc(), diag::err_omp_atomic_fail_no_compare)
<< SourceRange(C->getBeginLoc(), C->getEndLoc());
return StmtError();
diff --git a/clang/test/OpenMP/atomic_compare_codegen.cpp b/clang/test/OpenMP/atomic_compare_codegen.cpp
index 43607cc65ad9b5..03e5081a5c1d8a 100644
--- a/clang/test/OpenMP/atomic_compare_codegen.cpp
+++ b/clang/test/OpenMP/atomic_compare_codegen.cpp
@@ -13806,6 +13806,64 @@ double dxevd() {
return dv;
}
+
+double fail_dxevd() {
+ double dx, dv, de, dd;
+
+#pragma omp atomic compare capture relaxed fail(relaxed)
+ {if(dx == de) { dx = dv; } else { dd = dx; }}
+
+#pragma omp atomic compare capture acquire fail(relaxed)
+ {if(dx == de) { dx = dv; } else { dd = dx; }}
+
+#pragma omp atomic compare capture release fail(relaxed)
+ {if(dx == de) { dx = dv; } else { dd = dx; }}
+
+#pragma omp atomic compare capture acq_rel fail(relaxed)
+ {if(dx == de) { dx = dv; } else { dd = dx; }}
+
+#pragma omp atomic compare capture seq_cst fail(relaxed)
+ {if(dx == de) { dx = dv; } else { dd = dx; }}
+
+#pragma omp atomic compare capture relaxed fail(acquire)
+ {if(dx == de) { dx = dv; } else { dd = dx; }}
+
+#pragma omp atomic compare capture acquire fail(acquire)
+ {if(dx == de) { dx = dv; } else { dd = dx; }}
+
+#pragma omp atomic compare capture release fail(acquire)
+ {if(dx == de) { dx = dv; } else { dd = dx; }}
+
+#pragma omp atomic compare capture acq_rel fail(acquire)
+ {if(dx == de) { dx = dv; } else { dd = dx; }}
+
+#pragma omp atomic compare capture seq_cst fail(acquire)
+ {if(dx == de) { dx = dv; } else { dd = dx; }}
+
+#pragma omp atomic compare capture relaxed fail(seq_cst)
+ {if(dx == de) { dx = dv; } else { dd = dx; }}
+
+#pragma omp atomic compare capture acquire fail(seq_cst)
+ {if(dx == de) { dx = dv; } else { dd = dx; }}
+
+#pragma omp atomic compare capture release fail(seq_cst)
+ {if(dx == de) { dx = dv; } else { dd = dx; }}
+
+#pragma omp atomic compare capture acq_rel fail(seq_cst)
+ {if(dx == de) { dx = dv; } else { dd = dx; }}
+
+#pragma omp atomic compare capture seq_cst fail(seq_cst)
+ {if(dx == de) { dx = dv; } else { dd = dx; }}
+
+#pragma omp atomic compare seq_cst fail(acquire)
+ dx = dx < de ? de : dx;
+
+#pragma omp atomic compare relaxed fail(seq_cst)
+ dx = dx > de ? de : dx;
+
+ return dx;
+}
+
#endif
// CHECK-LABEL: @foo(
// CHECK-NEXT: entry:
@@ -61966,3 +62024,89 @@ double dxevd() {
// SIMD-ONLY0-NEXT: [[TMP180:%.*]] = load double, ptr [[DV]], align 8
// SIMD-ONLY0-NEXT: ret double [[TMP180]]
//
+// CHECK-LABEL: {{.+}}fail_dxevd{{.+}}
+// CHECK-NEXT: entry:
+// CHECK: {{.+}} load double,{{.+}}
+// CHECK-NEXT: {{.+}} load double,{{.+}}
+// CHECK-NEXT: {{.+}} bitcast double{{.+}}
+// CHECK-NEXT: {{.+}} bitcast double{{.+}}
+// CHECK-NEXT: {{.+}}cmpxchg ptr {{.+}} monotonic monotonic{{.+}}
+// CHECK: {{.+}} load double,{{.+}}
+// CHECK-NEXT: {{.+}} load double,{{.+}}
+// CHECK-NEXT: {{.+}} bitcast double{{.+}}
+// CHECK-NEXT: {{.+}} bitcast double{{.+}}
+// CHECK: {{.+}}cmpxchg ptr {{.+}} acquire monotonic{{.+}}
+// CHECK: {{.+}} load double,{{.+}}
+// CHECK-NEXT: {{.+}} load double,{{.+}}
+// CHECK-NEXT: {{.+}} bitcast double{{.+}}
+// CHECK-NEXT: {{.+}} bitcast double{{.+}}
+// CHECK: {{.+}}cmpxchg ptr {{.+}} release monotonic{{.+}}
+// CHECK: {{.+}} load double,{{.+}}
+// CHECK-NEXT: {{.+}} load double,{{.+}}
+// CHECK-NEXT: {{.+}} bitcast double{{.+}}
+// CHECK-NEXT: {{.+}} bitcast double{{.+}}
+// CHECK: {{.+}}cmpxchg ptr {{.+}} acq_rel monotonic{{.+}}
+// CHECK: {{.+}} load double,{{.+}}
+// CHECK-NEXT: {{.+}} load double,{{.+}}
+// CHECK-NEXT: {{.+}} bitcast double{{.+}}
+// CHECK-NEXT: {{.+}} bitcast double{{.+}}
+// CHECK-NEXT: {{.+}}cmpxchg ptr {{.+}} seq_cst monotonic{{.+}}
+// CHECK: {{.+}}__kmpc_flush{{.+}}
+// CHECK-NEXT: {{.+}} load double,{{.+}}
+// CHECK-NEXT: {{.+}} load double,{{.+}}
+// CHECK-NEXT: {{.+}} bitcast double{{.+}}
+// CHECK-NEXT: {{.+}} bitcast double{{.+}}
+// CHECK: {{.+}}cmpxchg ptr {{.+}} monotonic acquire{{.+}}
+// CHECK: {{.+}} load double,{{.+}}
+// CHECK-NEXT: {{.+}} load double,{{.+}}
+// CHECK-NEXT: {{.+}} bitcast double{{.+}}
+// CHECK-NEXT: {{.+}} bitcast double{{.+}}
+// CHECK: {{.+}}cmpxchg ptr {{.+}} acquire acquire{{.+}}
+// CHECK: {{.+}} load double,{{.+}}
+// CHECK-NEXT: {{.+}} load double,{{.+}}
+// CHECK-NEXT: {{.+}} bitcast double{{.+}}
+// CHECK-NEXT: {{.+}} bitcast double{{.+}}
+// CHECK: {{.+}}cmpxchg ptr {{.+}} release acquire{{.+}}
+// CHECK: {{.+}} load double,{{.+}}
+// CHECK-NEXT: {{.+}} load double,{{.+}}
+// CHECK-NEXT: {{.+}} bitcast double{{.+}}
+// CHECK-NEXT: {{.+}} bitcast double{{.+}}
+// CHECK: {{.+}}cmpxchg ptr {{.+}} acq_rel acquire{{.+}}
+// CHECK: {{.+}} load double,{{.+}}
+// CHECK-NEXT: {{.+}} load double,{{.+}}
+// CHECK-NEXT: {{.+}} bitcast double{{.+}}
+// CHECK-NEXT: {{.+}} bitcast double{{.+}}
+// CHECK: {{.+}}cmpxchg ptr {{.+}} seq_cst acquire{{.+}}
+// CHECK: {{.+}}__kmpc_flush{{.+}}
+// CHECK-NEXT: {{.+}} load double,{{.+}}
+// CHECK-NEXT: {{.+}} load double,{{.+}}
+// CHECK-NEXT: {{.+}} bitcast double{{.+}}
+// CHECK-NEXT: {{.+}} bitcast double{{.+}}
+// CHECK: {{.+}}cmpxchg ptr {{.+}} monotonic seq_cst{{.+}}
+// CHECK: {{.+}} load double,{{.+}}
+// CHECK-NEXT: {{.+}} load double,{{.+}}
+// CHECK-NEXT: {{.+}} bitcast double{{.+}}
+// CHECK-NEXT: {{.+}} bitcast double{{.+}}
+// CHECK: {{.+}}cmpxchg ptr {{.+}} acquire seq_cst{{.+}}
+// CHECK: {{.+}} load double,{{.+}}
+// CHECK-NEXT: {{.+}} load double,{{.+}}
+// CHECK-NEXT: {{.+}} bitcast double{{.+}}
+// CHECK-NEXT: {{.+}} bitcast double{{.+}}
+// CHECK: {{.+}}cmpxchg ptr {{.+}} release seq_cst{{.+}}
+// CHECK: {{.+}} load double,{{.+}}
+// CHECK-NEXT: {{.+}} load double,{{.+}}
+// CHECK-NEXT: {{.+}} bitcast double{{.+}}
+// CHECK-NEXT: {{.+}} bitcast double{{.+}}
+// CHECK: {{.+}}cmpxchg ptr {{.+}} acq_rel seq_cst{{.+}}
+// CHECK: {{.+}} load double,{{.+}}
+// CHECK-NEXT: {{.+}} load double,{{.+}}
+// CHECK-NEXT: {{.+}} bitcast double{{.+}}
+// CHECK-NEXT: {{.+}} bitcast double{{.+}}
+// CHECK: {{.+}}cmpxchg ptr {{.+}} seq_cst seq_cst{{.+}}
+// CHECK: call void {{.+}}__kmpc_flush{{.+}}
+// CHECK-NEXT: {{.+}} load double,{{.+}}
+// CHECK-NEXT: {{.+}} atomicrmw fmax {{.+}} seq_cst{{.+}}
+// CHECK-NEXT: call void {{.+}}__kmpc_flush{{.+}}
+// CHECK-NEXT: {{.+}} load double,{{.+}}
+// CHECK-NEXT: {{.+}} atomicrmw fmin {{.+}} monotonic{{.+}}
+// CHECK: ret double {{.+}}
diff --git a/llvm/include/llvm/Frontend/OpenMP/OMPIRBuilder.h b/llvm/include/llvm/Frontend/OpenMP/OMPIRBuilder.h
index abbef03d02cb10..669104307fa0e2 100644
--- a/llvm/include/llvm/Frontend/OpenMP/OMPIRBuilder.h
+++ b/llvm/include/llvm/Frontend/OpenMP/OMPIRBuilder.h
@@ -2562,6 +2562,13 @@ class OpenMPIRBuilder {
AtomicOpValue &V, AtomicOpValue &R, Value *E, Value *D,
AtomicOrdering AO, omp::OMPAtomicCompareOp Op,
bool IsXBinopExpr, bool IsPostfixUpdate, bool IsFailOnly);
+ InsertPointTy createAtomicCompare(const LocationDescription &Loc,
+ AtomicOpValue &X, AtomicOpValue &V,
+ AtomicOpValue &R, Value *E, Value *D,
+ AtomicOrdering AO,
+ omp::OMPAtomicCompareOp Op,
+ bool IsXBinopExpr, bool IsPostfixUpdate,
+ bool IsFailOnly, AtomicOrdering Failure);
/// Create the control flow structure of a canonical OpenMP loop.
///
diff --git a/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp b/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp
index ce428f78dc843e..f6cf358119fb71 100644
--- a/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp
+++ b/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp
@@ -6026,6 +6026,17 @@ OpenMPIRBuilder::InsertPointTy OpenMPIRBuilder::createAtomicCompare(
omp::OMPAtomicCompareOp Op, bool IsXBinopExpr, bool IsPostfixUpdate,
bool IsFailOnly) {
+ AtomicOrdering Failure = AtomicCmpXchgInst::getStrongestFailureOrdering(AO);
+ return createAtomicCompare(Loc, X, V, R, E, D, AO, Op, IsXBinopExpr,
+ IsPostfixUpdate, IsFailOnly, Failure);
+}
+
+OpenMPIRBuilder::InsertPointTy OpenMPIRBuilder::createAtomicCompare(
+ const LocationDescription &Loc, AtomicOpValue &X, AtomicOpValue &V,
+ AtomicOpValue &R, Value *E, Value *D, AtomicOrdering AO,
+ omp::OMPAtomicCompareOp Op, bool IsXBinopExpr, bool IsPostfixUpdate,
+ bool IsFailOnly, AtomicOrdering Failure) {
+
if (!updateToLocation(Loc))
return Loc.IP;
@@ -6040,7 +6051,6 @@ OpenMPIRBuilder::InsertPointTy OpenMPIRBuilder::createAtomicCompare(
bool IsInteger = E->getType()->isIntegerTy();
if (Op == OMPAtomicCompareOp::EQ) {
- AtomicOrdering Failure = AtomicCmpXchgInst::getStrongestFailureOrdering(AO);
AtomicCmpXchgInst *Result = nullptr;
if (!IsInteger) {
IntegerType *IntCastTy =
More information about the cfe-commits
mailing list