Skip to content

Commit 49ee8b5

Browse files
[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
1 parent 7c55dd8 commit 49ee8b5

File tree

5 files changed

+203
-23
lines changed

5 files changed

+203
-23
lines changed

clang/lib/CodeGen/CGStmtOpenMP.cpp

Lines changed: 40 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -6406,13 +6406,11 @@ static void emitOMPAtomicCaptureExpr(CodeGenFunction &CGF,
64066406
}
64076407
}
64086408

6409-
static void emitOMPAtomicCompareExpr(CodeGenFunction &CGF,
6410-
llvm::AtomicOrdering AO, const Expr *X,
6411-
const Expr *V, const Expr *R,
6412-
const Expr *E, const Expr *D,
6413-
const Expr *CE, bool IsXBinopExpr,
6414-
bool IsPostfixUpdate, bool IsFailOnly,
6415-
SourceLocation Loc) {
6409+
static void emitOMPAtomicCompareExpr(
6410+
CodeGenFunction &CGF, llvm::AtomicOrdering AO, llvm::AtomicOrdering FailAO,
6411+
const Expr *X, const Expr *V, const Expr *R, const Expr *E, const Expr *D,
6412+
const Expr *CE, bool IsXBinopExpr, bool IsPostfixUpdate, bool IsFailOnly,
6413+
SourceLocation Loc) {
64166414
llvm::OpenMPIRBuilder &OMPBuilder =
64176415
CGF.CGM.getOpenMPRuntime().getOMPBuilder();
64186416

@@ -6477,13 +6475,21 @@ static void emitOMPAtomicCompareExpr(CodeGenFunction &CGF,
64776475
R->getType().isVolatileQualified()};
64786476
}
64796477

6480-
CGF.Builder.restoreIP(OMPBuilder.createAtomicCompare(
6481-
CGF.Builder, XOpVal, VOpVal, ROpVal, EVal, DVal, AO, Op, IsXBinopExpr,
6482-
IsPostfixUpdate, IsFailOnly));
6478+
if (FailAO == llvm::AtomicOrdering::NotAtomic) {
6479+
// fail clause was not mentionend on the
6480+
// "#pragma omp atomic compare" construct.
6481+
CGF.Builder.restoreIP(OMPBuilder.createAtomicCompare(
6482+
CGF.Builder, XOpVal, VOpVal, ROpVal, EVal, DVal, AO, Op, IsXBinopExpr,
6483+
IsPostfixUpdate, IsFailOnly));
6484+
} else
6485+
CGF.Builder.restoreIP(OMPBuilder.createAtomicCompare(
6486+
CGF.Builder, XOpVal, VOpVal, ROpVal, EVal, DVal, AO, Op, IsXBinopExpr,
6487+
IsPostfixUpdate, IsFailOnly, FailAO));
64836488
}
64846489

64856490
static void emitOMPAtomicExpr(CodeGenFunction &CGF, OpenMPClauseKind Kind,
6486-
llvm::AtomicOrdering AO, bool IsPostfixUpdate,
6491+
llvm::AtomicOrdering AO,
6492+
llvm::AtomicOrdering FailAO, bool IsPostfixUpdate,
64876493
const Expr *X, const Expr *V, const Expr *R,
64886494
const Expr *E, const Expr *UE, const Expr *D,
64896495
const Expr *CE, bool IsXLHSInRHSPart,
@@ -6504,12 +6510,8 @@ static void emitOMPAtomicExpr(CodeGenFunction &CGF, OpenMPClauseKind Kind,
65046510
IsXLHSInRHSPart, Loc);
65056511
break;
65066512
case OMPC_compare: {
6507-
emitOMPAtomicCompareExpr(CGF, AO, X, V, R, E, D, CE, IsXLHSInRHSPart,
6508-
IsPostfixUpdate, IsFailOnly, Loc);
6509-
break;
6510-
}
6511-
case OMPC_fail: {
6512-
//TODO
6513+
emitOMPAtomicCompareExpr(CGF, AO, FailAO, X, V, R, E, D, CE,
6514+
IsXLHSInRHSPart, IsPostfixUpdate, IsFailOnly, Loc);
65136515
break;
65146516
}
65156517
default:
@@ -6519,6 +6521,8 @@ static void emitOMPAtomicExpr(CodeGenFunction &CGF, OpenMPClauseKind Kind,
65196521

65206522
void CodeGenFunction::EmitOMPAtomicDirective(const OMPAtomicDirective &S) {
65216523
llvm::AtomicOrdering AO = llvm::AtomicOrdering::Monotonic;
6524+
// Fail Memory Clause Ordering.
6525+
llvm::AtomicOrdering FailAO = llvm::AtomicOrdering::NotAtomic;
65226526
bool MemOrderingSpecified = false;
65236527
if (S.getSingleClause<OMPSeqCstClause>()) {
65246528
AO = llvm::AtomicOrdering::SequentiallyConsistent;
@@ -6572,12 +6576,27 @@ void CodeGenFunction::EmitOMPAtomicDirective(const OMPAtomicDirective &S) {
65726576
}
65736577
}
65746578

6579+
if (KindsEncountered.contains(OMPC_compare) &&
6580+
KindsEncountered.contains(OMPC_fail)) {
6581+
Kind = OMPC_compare;
6582+
const auto *FailClause = S.getSingleClause<OMPFailClause>();
6583+
if (FailClause) {
6584+
OpenMPClauseKind FailParameter = FailClause->getFailParameter();
6585+
if (FailParameter == llvm::omp::OMPC_relaxed)
6586+
FailAO = llvm::AtomicOrdering::Monotonic;
6587+
else if (FailParameter == llvm::omp::OMPC_acquire)
6588+
FailAO = llvm::AtomicOrdering::Acquire;
6589+
else if (FailParameter == llvm::omp::OMPC_seq_cst)
6590+
FailAO = llvm::AtomicOrdering::SequentiallyConsistent;
6591+
}
6592+
}
6593+
65756594
LexicalScope Scope(*this, S.getSourceRange());
65766595
EmitStopPoint(S.getAssociatedStmt());
6577-
emitOMPAtomicExpr(*this, Kind, AO, S.isPostfixUpdate(), S.getX(), S.getV(),
6578-
S.getR(), S.getExpr(), S.getUpdateExpr(), S.getD(),
6579-
S.getCondExpr(), S.isXLHSInRHSPart(), S.isFailOnly(),
6580-
S.getBeginLoc());
6596+
emitOMPAtomicExpr(*this, Kind, AO, FailAO, S.isPostfixUpdate(), S.getX(),
6597+
S.getV(), S.getR(), S.getExpr(), S.getUpdateExpr(),
6598+
S.getD(), S.getCondExpr(), S.isXLHSInRHSPart(),
6599+
S.isFailOnly(), S.getBeginLoc());
65816600
}
65826601

65836602
static void emitCommonOMPTargetDirective(CodeGenFunction &CGF,

clang/lib/Sema/SemaOpenMP.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12683,7 +12683,7 @@ StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses,
1268312683
break;
1268412684
}
1268512685
case OMPC_fail: {
12686-
if (AtomicKind != OMPC_compare) {
12686+
if (!EncounteredAtomicKinds.contains(OMPC_compare)) {
1268712687
Diag(C->getBeginLoc(), diag::err_omp_atomic_fail_no_compare)
1268812688
<< SourceRange(C->getBeginLoc(), C->getEndLoc());
1268912689
return StmtError();

clang/test/OpenMP/atomic_compare_codegen.cpp

Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13806,6 +13806,64 @@ double dxevd() {
1380613806
return dv;
1380713807
}
1380813808

13809+
13810+
double fail_dxevd() {
13811+
double dx, dv, de, dd;
13812+
13813+
#pragma omp atomic compare capture relaxed fail(relaxed)
13814+
{if(dx == de) { dx = dv; } else { dd = dx; }}
13815+
13816+
#pragma omp atomic compare capture acquire fail(relaxed)
13817+
{if(dx == de) { dx = dv; } else { dd = dx; }}
13818+
13819+
#pragma omp atomic compare capture release fail(relaxed)
13820+
{if(dx == de) { dx = dv; } else { dd = dx; }}
13821+
13822+
#pragma omp atomic compare capture acq_rel fail(relaxed)
13823+
{if(dx == de) { dx = dv; } else { dd = dx; }}
13824+
13825+
#pragma omp atomic compare capture seq_cst fail(relaxed)
13826+
{if(dx == de) { dx = dv; } else { dd = dx; }}
13827+
13828+
#pragma omp atomic compare capture relaxed fail(acquire)
13829+
{if(dx == de) { dx = dv; } else { dd = dx; }}
13830+
13831+
#pragma omp atomic compare capture acquire fail(acquire)
13832+
{if(dx == de) { dx = dv; } else { dd = dx; }}
13833+
13834+
#pragma omp atomic compare capture release fail(acquire)
13835+
{if(dx == de) { dx = dv; } else { dd = dx; }}
13836+
13837+
#pragma omp atomic compare capture acq_rel fail(acquire)
13838+
{if(dx == de) { dx = dv; } else { dd = dx; }}
13839+
13840+
#pragma omp atomic compare capture seq_cst fail(acquire)
13841+
{if(dx == de) { dx = dv; } else { dd = dx; }}
13842+
13843+
#pragma omp atomic compare capture relaxed fail(seq_cst)
13844+
{if(dx == de) { dx = dv; } else { dd = dx; }}
13845+
13846+
#pragma omp atomic compare capture acquire fail(seq_cst)
13847+
{if(dx == de) { dx = dv; } else { dd = dx; }}
13848+
13849+
#pragma omp atomic compare capture release fail(seq_cst)
13850+
{if(dx == de) { dx = dv; } else { dd = dx; }}
13851+
13852+
#pragma omp atomic compare capture acq_rel fail(seq_cst)
13853+
{if(dx == de) { dx = dv; } else { dd = dx; }}
13854+
13855+
#pragma omp atomic compare capture seq_cst fail(seq_cst)
13856+
{if(dx == de) { dx = dv; } else { dd = dx; }}
13857+
13858+
#pragma omp atomic compare seq_cst fail(acquire)
13859+
dx = dx < de ? de : dx;
13860+
13861+
#pragma omp atomic compare relaxed fail(seq_cst)
13862+
dx = dx > de ? de : dx;
13863+
13864+
return dx;
13865+
}
13866+
1380913867
#endif
1381013868
// CHECK-LABEL: @foo(
1381113869
// CHECK-NEXT: entry:
@@ -61966,3 +62024,89 @@ double dxevd() {
6196662024
// SIMD-ONLY0-NEXT: [[TMP180:%.*]] = load double, ptr [[DV]], align 8
6196762025
// SIMD-ONLY0-NEXT: ret double [[TMP180]]
6196862026
//
62027+
// CHECK-LABEL: {{.+}}fail_dxevd{{.+}}
62028+
// CHECK-NEXT: entry:
62029+
// CHECK: {{.+}} load double,{{.+}}
62030+
// CHECK-NEXT: {{.+}} load double,{{.+}}
62031+
// CHECK-NEXT: {{.+}} bitcast double{{.+}}
62032+
// CHECK-NEXT: {{.+}} bitcast double{{.+}}
62033+
// CHECK-NEXT: {{.+}}cmpxchg ptr {{.+}} monotonic monotonic{{.+}}
62034+
// CHECK: {{.+}} load double,{{.+}}
62035+
// CHECK-NEXT: {{.+}} load double,{{.+}}
62036+
// CHECK-NEXT: {{.+}} bitcast double{{.+}}
62037+
// CHECK-NEXT: {{.+}} bitcast double{{.+}}
62038+
// CHECK: {{.+}}cmpxchg ptr {{.+}} acquire monotonic{{.+}}
62039+
// CHECK: {{.+}} load double,{{.+}}
62040+
// CHECK-NEXT: {{.+}} load double,{{.+}}
62041+
// CHECK-NEXT: {{.+}} bitcast double{{.+}}
62042+
// CHECK-NEXT: {{.+}} bitcast double{{.+}}
62043+
// CHECK: {{.+}}cmpxchg ptr {{.+}} release monotonic{{.+}}
62044+
// CHECK: {{.+}} load double,{{.+}}
62045+
// CHECK-NEXT: {{.+}} load double,{{.+}}
62046+
// CHECK-NEXT: {{.+}} bitcast double{{.+}}
62047+
// CHECK-NEXT: {{.+}} bitcast double{{.+}}
62048+
// CHECK: {{.+}}cmpxchg ptr {{.+}} acq_rel monotonic{{.+}}
62049+
// CHECK: {{.+}} load double,{{.+}}
62050+
// CHECK-NEXT: {{.+}} load double,{{.+}}
62051+
// CHECK-NEXT: {{.+}} bitcast double{{.+}}
62052+
// CHECK-NEXT: {{.+}} bitcast double{{.+}}
62053+
// CHECK-NEXT: {{.+}}cmpxchg ptr {{.+}} seq_cst monotonic{{.+}}
62054+
// CHECK: {{.+}}__kmpc_flush{{.+}}
62055+
// CHECK-NEXT: {{.+}} load double,{{.+}}
62056+
// CHECK-NEXT: {{.+}} load double,{{.+}}
62057+
// CHECK-NEXT: {{.+}} bitcast double{{.+}}
62058+
// CHECK-NEXT: {{.+}} bitcast double{{.+}}
62059+
// CHECK: {{.+}}cmpxchg ptr {{.+}} monotonic acquire{{.+}}
62060+
// CHECK: {{.+}} load double,{{.+}}
62061+
// CHECK-NEXT: {{.+}} load double,{{.+}}
62062+
// CHECK-NEXT: {{.+}} bitcast double{{.+}}
62063+
// CHECK-NEXT: {{.+}} bitcast double{{.+}}
62064+
// CHECK: {{.+}}cmpxchg ptr {{.+}} acquire acquire{{.+}}
62065+
// CHECK: {{.+}} load double,{{.+}}
62066+
// CHECK-NEXT: {{.+}} load double,{{.+}}
62067+
// CHECK-NEXT: {{.+}} bitcast double{{.+}}
62068+
// CHECK-NEXT: {{.+}} bitcast double{{.+}}
62069+
// CHECK: {{.+}}cmpxchg ptr {{.+}} release acquire{{.+}}
62070+
// CHECK: {{.+}} load double,{{.+}}
62071+
// CHECK-NEXT: {{.+}} load double,{{.+}}
62072+
// CHECK-NEXT: {{.+}} bitcast double{{.+}}
62073+
// CHECK-NEXT: {{.+}} bitcast double{{.+}}
62074+
// CHECK: {{.+}}cmpxchg ptr {{.+}} acq_rel acquire{{.+}}
62075+
// CHECK: {{.+}} load double,{{.+}}
62076+
// CHECK-NEXT: {{.+}} load double,{{.+}}
62077+
// CHECK-NEXT: {{.+}} bitcast double{{.+}}
62078+
// CHECK-NEXT: {{.+}} bitcast double{{.+}}
62079+
// CHECK: {{.+}}cmpxchg ptr {{.+}} seq_cst acquire{{.+}}
62080+
// CHECK: {{.+}}__kmpc_flush{{.+}}
62081+
// CHECK-NEXT: {{.+}} load double,{{.+}}
62082+
// CHECK-NEXT: {{.+}} load double,{{.+}}
62083+
// CHECK-NEXT: {{.+}} bitcast double{{.+}}
62084+
// CHECK-NEXT: {{.+}} bitcast double{{.+}}
62085+
// CHECK: {{.+}}cmpxchg ptr {{.+}} monotonic seq_cst{{.+}}
62086+
// CHECK: {{.+}} load double,{{.+}}
62087+
// CHECK-NEXT: {{.+}} load double,{{.+}}
62088+
// CHECK-NEXT: {{.+}} bitcast double{{.+}}
62089+
// CHECK-NEXT: {{.+}} bitcast double{{.+}}
62090+
// CHECK: {{.+}}cmpxchg ptr {{.+}} acquire seq_cst{{.+}}
62091+
// CHECK: {{.+}} load double,{{.+}}
62092+
// CHECK-NEXT: {{.+}} load double,{{.+}}
62093+
// CHECK-NEXT: {{.+}} bitcast double{{.+}}
62094+
// CHECK-NEXT: {{.+}} bitcast double{{.+}}
62095+
// CHECK: {{.+}}cmpxchg ptr {{.+}} release seq_cst{{.+}}
62096+
// CHECK: {{.+}} load double,{{.+}}
62097+
// CHECK-NEXT: {{.+}} load double,{{.+}}
62098+
// CHECK-NEXT: {{.+}} bitcast double{{.+}}
62099+
// CHECK-NEXT: {{.+}} bitcast double{{.+}}
62100+
// CHECK: {{.+}}cmpxchg ptr {{.+}} acq_rel seq_cst{{.+}}
62101+
// CHECK: {{.+}} load double,{{.+}}
62102+
// CHECK-NEXT: {{.+}} load double,{{.+}}
62103+
// CHECK-NEXT: {{.+}} bitcast double{{.+}}
62104+
// CHECK-NEXT: {{.+}} bitcast double{{.+}}
62105+
// CHECK: {{.+}}cmpxchg ptr {{.+}} seq_cst seq_cst{{.+}}
62106+
// CHECK: call void {{.+}}__kmpc_flush{{.+}}
62107+
// CHECK-NEXT: {{.+}} load double,{{.+}}
62108+
// CHECK-NEXT: {{.+}} atomicrmw fmax {{.+}} seq_cst{{.+}}
62109+
// CHECK-NEXT: call void {{.+}}__kmpc_flush{{.+}}
62110+
// CHECK-NEXT: {{.+}} load double,{{.+}}
62111+
// CHECK-NEXT: {{.+}} atomicrmw fmin {{.+}} monotonic{{.+}}
62112+
// CHECK: ret double {{.+}}

llvm/include/llvm/Frontend/OpenMP/OMPIRBuilder.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2562,6 +2562,13 @@ class OpenMPIRBuilder {
25622562
AtomicOpValue &V, AtomicOpValue &R, Value *E, Value *D,
25632563
AtomicOrdering AO, omp::OMPAtomicCompareOp Op,
25642564
bool IsXBinopExpr, bool IsPostfixUpdate, bool IsFailOnly);
2565+
InsertPointTy createAtomicCompare(const LocationDescription &Loc,
2566+
AtomicOpValue &X, AtomicOpValue &V,
2567+
AtomicOpValue &R, Value *E, Value *D,
2568+
AtomicOrdering AO,
2569+
omp::OMPAtomicCompareOp Op,
2570+
bool IsXBinopExpr, bool IsPostfixUpdate,
2571+
bool IsFailOnly, AtomicOrdering Failure);
25652572

25662573
/// Create the control flow structure of a canonical OpenMP loop.
25672574
///

llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6026,6 +6026,17 @@ OpenMPIRBuilder::InsertPointTy OpenMPIRBuilder::createAtomicCompare(
60266026
omp::OMPAtomicCompareOp Op, bool IsXBinopExpr, bool IsPostfixUpdate,
60276027
bool IsFailOnly) {
60286028

6029+
AtomicOrdering Failure = AtomicCmpXchgInst::getStrongestFailureOrdering(AO);
6030+
return createAtomicCompare(Loc, X, V, R, E, D, AO, Op, IsXBinopExpr,
6031+
IsPostfixUpdate, IsFailOnly, Failure);
6032+
}
6033+
6034+
OpenMPIRBuilder::InsertPointTy OpenMPIRBuilder::createAtomicCompare(
6035+
const LocationDescription &Loc, AtomicOpValue &X, AtomicOpValue &V,
6036+
AtomicOpValue &R, Value *E, Value *D, AtomicOrdering AO,
6037+
omp::OMPAtomicCompareOp Op, bool IsXBinopExpr, bool IsPostfixUpdate,
6038+
bool IsFailOnly, AtomicOrdering Failure) {
6039+
60296040
if (!updateToLocation(Loc))
60306041
return Loc.IP;
60316042

@@ -6040,7 +6051,6 @@ OpenMPIRBuilder::InsertPointTy OpenMPIRBuilder::createAtomicCompare(
60406051
bool IsInteger = E->getType()->isIntegerTy();
60416052

60426053
if (Op == OMPAtomicCompareOp::EQ) {
6043-
AtomicOrdering Failure = AtomicCmpXchgInst::getStrongestFailureOrdering(AO);
60446054
AtomicCmpXchgInst *Result = nullptr;
60456055
if (!IsInteger) {
60466056
IntegerType *IntCastTy =

0 commit comments

Comments
 (0)