Skip to content

Commit 1465299

Browse files
authored
[MLIR][OpenMP] Update op verifiers dependent on omp.wsloop (2/5) (#89211)
This patch updates verifiers for `omp.ordered`, `omp.ordered.region`, `omp.cancel` and `omp.cancellation_point`, which check for a parent `omp.wsloop`. After transitioning to a loop wrapper-based approach, the expected direct parent will become `omp.loop_nest` instead, so verifiers need to take this into account. This PR on its own will not pass premerge tests. All patches in the stack are needed before it can be compiled and passes tests.
1 parent 4c16b12 commit 1465299

File tree

2 files changed

+104
-35
lines changed

2 files changed

+104
-35
lines changed

mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp

Lines changed: 49 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1964,21 +1964,51 @@ LogicalResult CriticalOp::verifySymbolUses(SymbolTableCollection &symbolTable) {
19641964
// Ordered construct
19651965
//===----------------------------------------------------------------------===//
19661966

1967+
static LogicalResult verifyOrderedParent(Operation &op) {
1968+
bool hasRegion = op.getNumRegions() > 0;
1969+
auto loopOp = op.getParentOfType<LoopNestOp>();
1970+
if (!loopOp) {
1971+
if (hasRegion)
1972+
return success();
1973+
1974+
// TODO: Consider if this needs to be the case only for the standalone
1975+
// variant of the ordered construct.
1976+
return op.emitOpError() << "must be nested inside of a loop";
1977+
}
1978+
1979+
Operation *wrapper = loopOp->getParentOp();
1980+
if (auto wsloopOp = dyn_cast<WsloopOp>(wrapper)) {
1981+
IntegerAttr orderedAttr = wsloopOp.getOrderedValAttr();
1982+
if (!orderedAttr)
1983+
return op.emitOpError() << "the enclosing worksharing-loop region must "
1984+
"have an ordered clause";
1985+
1986+
if (hasRegion && orderedAttr.getInt() != 0)
1987+
return op.emitOpError() << "the enclosing loop's ordered clause must not "
1988+
"have a parameter present";
1989+
1990+
if (!hasRegion && orderedAttr.getInt() == 0)
1991+
return op.emitOpError() << "the enclosing loop's ordered clause must "
1992+
"have a parameter present";
1993+
} else if (!isa<SimdOp>(wrapper)) {
1994+
return op.emitOpError() << "must be nested inside of a worksharing, simd "
1995+
"or worksharing simd loop";
1996+
}
1997+
return success();
1998+
}
1999+
19672000
void OrderedOp::build(OpBuilder &builder, OperationState &state,
19682001
const OrderedOpClauseOps &clauses) {
19692002
OrderedOp::build(builder, state, clauses.doacrossDependTypeAttr,
19702003
clauses.doacrossNumLoopsAttr, clauses.doacrossVectorVars);
19712004
}
19722005

19732006
LogicalResult OrderedOp::verify() {
1974-
auto container = (*this)->getParentOfType<WsloopOp>();
1975-
if (!container || !container.getOrderedValAttr() ||
1976-
container.getOrderedValAttr().getInt() == 0)
1977-
return emitOpError() << "ordered depend directive must be closely "
1978-
<< "nested inside a worksharing-loop with ordered "
1979-
<< "clause with parameter present";
1980-
1981-
if (container.getOrderedValAttr().getInt() != (int64_t)*getNumLoopsVal())
2007+
if (failed(verifyOrderedParent(**this)))
2008+
return failure();
2009+
2010+
auto wrapper = (*this)->getParentOfType<WsloopOp>();
2011+
if (!wrapper || *wrapper.getOrderedVal() != *getNumLoopsVal())
19822012
return emitOpError() << "number of variables in depend clause does not "
19832013
<< "match number of iteration variables in the "
19842014
<< "doacross loop";
@@ -1996,15 +2026,7 @@ LogicalResult OrderedRegionOp::verify() {
19962026
if (getSimd())
19972027
return failure();
19982028

1999-
if (auto container = (*this)->getParentOfType<WsloopOp>()) {
2000-
if (!container.getOrderedValAttr() ||
2001-
container.getOrderedValAttr().getInt() != 0)
2002-
return emitOpError() << "ordered region must be closely nested inside "
2003-
<< "a worksharing-loop region with an ordered "
2004-
<< "clause without parameter present";
2005-
}
2006-
2007-
return success();
2029+
return verifyOrderedParent(**this);
20082030
}
20092031

20102032
//===----------------------------------------------------------------------===//
@@ -2149,15 +2171,19 @@ LogicalResult CancelOp::verify() {
21492171
<< "inside a parallel region";
21502172
}
21512173
if (cct == ClauseCancellationConstructType::Loop) {
2152-
if (!isa<WsloopOp>(parentOp)) {
2153-
return emitOpError() << "cancel loop must appear "
2154-
<< "inside a worksharing-loop region";
2174+
auto loopOp = dyn_cast<LoopNestOp>(parentOp);
2175+
auto wsloopOp = llvm::dyn_cast_if_present<WsloopOp>(
2176+
loopOp ? loopOp->getParentOp() : nullptr);
2177+
2178+
if (!wsloopOp) {
2179+
return emitOpError()
2180+
<< "cancel loop must appear inside a worksharing-loop region";
21552181
}
2156-
if (cast<WsloopOp>(parentOp).getNowaitAttr()) {
2182+
if (wsloopOp.getNowaitAttr()) {
21572183
return emitError() << "A worksharing construct that is canceled "
21582184
<< "must not have a nowait clause";
21592185
}
2160-
if (cast<WsloopOp>(parentOp).getOrderedValAttr()) {
2186+
if (wsloopOp.getOrderedValAttr()) {
21612187
return emitError() << "A worksharing construct that is canceled "
21622188
<< "must not have an ordered clause";
21632189
}
@@ -2195,7 +2221,7 @@ LogicalResult CancellationPointOp::verify() {
21952221
<< "inside a parallel region";
21962222
}
21972223
if ((cct == ClauseCancellationConstructType::Loop) &&
2198-
!isa<WsloopOp>(parentOp)) {
2224+
(!isa<LoopNestOp>(parentOp) || !isa<WsloopOp>(parentOp->getParentOp()))) {
21992225
return emitOpError() << "cancellation point loop must appear "
22002226
<< "inside a worksharing-loop region";
22012227
}

mlir/test/Dialect/OpenMP/invalid.mlir

Lines changed: 55 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -748,10 +748,10 @@ omp.critical.declare @mutex hint(invalid_hint)
748748

749749
// -----
750750

751-
func.func @omp_ordered1(%arg1 : i32, %arg2 : i32, %arg3 : i32) -> () {
752-
omp.wsloop ordered(1) {
753-
omp.loop_nest (%0) : i32 = (%arg1) to (%arg2) step (%arg3) {
754-
// expected-error @below {{ordered region must be closely nested inside a worksharing-loop region with an ordered clause without parameter present}}
751+
func.func @omp_ordered_region1(%x : i32) -> () {
752+
omp.distribute {
753+
omp.loop_nest (%i) : i32 = (%x) to (%x) step (%x) {
754+
// expected-error @below {{op must be nested inside of a worksharing, simd or worksharing simd loop}}
755755
omp.ordered.region {
756756
omp.terminator
757757
}
@@ -764,10 +764,26 @@ func.func @omp_ordered1(%arg1 : i32, %arg2 : i32, %arg3 : i32) -> () {
764764

765765
// -----
766766

767-
func.func @omp_ordered2(%arg1 : i32, %arg2 : i32, %arg3 : i32) -> () {
767+
func.func @omp_ordered_region2(%x : i32) -> () {
768768
omp.wsloop {
769-
omp.loop_nest (%0) : i32 = (%arg1) to (%arg2) step (%arg3) {
770-
// expected-error @below {{ordered region must be closely nested inside a worksharing-loop region with an ordered clause without parameter present}}
769+
omp.loop_nest (%i) : i32 = (%x) to (%x) step (%x) {
770+
// expected-error @below {{the enclosing worksharing-loop region must have an ordered clause}}
771+
omp.ordered.region {
772+
omp.terminator
773+
}
774+
omp.yield
775+
}
776+
omp.terminator
777+
}
778+
return
779+
}
780+
781+
// -----
782+
783+
func.func @omp_ordered_region3(%x : i32) -> () {
784+
omp.wsloop ordered(1) {
785+
omp.loop_nest (%i) : i32 = (%x) to (%x) step (%x) {
786+
// expected-error @below {{the enclosing loop's ordered clause must not have a parameter present}}
771787
omp.ordered.region {
772788
omp.terminator
773789
}
@@ -780,34 +796,61 @@ func.func @omp_ordered2(%arg1 : i32, %arg2 : i32, %arg3 : i32) -> () {
780796

781797
// -----
782798

783-
func.func @omp_ordered3(%vec0 : i64) -> () {
784-
// expected-error @below {{ordered depend directive must be closely nested inside a worksharing-loop with ordered clause with parameter present}}
799+
func.func @omp_ordered1(%vec0 : i64) -> () {
800+
// expected-error @below {{op must be nested inside of a loop}}
785801
omp.ordered depend_type(dependsink) depend_vec(%vec0 : i64) {num_loops_val = 1 : i64}
786802
return
787803
}
788804

789805
// -----
790806

807+
func.func @omp_ordered2(%arg1 : i32, %arg2 : i32, %arg3 : i32, %vec0 : i64) -> () {
808+
omp.distribute {
809+
omp.loop_nest (%0) : i32 = (%arg1) to (%arg2) step (%arg3) {
810+
// expected-error @below {{op must be nested inside of a worksharing, simd or worksharing simd loop}}
811+
omp.ordered depend_type(dependsink) depend_vec(%vec0 : i64) {num_loops_val = 1 : i64}
812+
omp.yield
813+
}
814+
omp.terminator
815+
}
816+
return
817+
}
818+
819+
// -----
820+
821+
func.func @omp_ordered3(%arg1 : i32, %arg2 : i32, %arg3 : i32, %vec0 : i64) -> () {
822+
omp.wsloop {
823+
omp.loop_nest (%0) : i32 = (%arg1) to (%arg2) step (%arg3) {
824+
// expected-error @below {{the enclosing worksharing-loop region must have an ordered clause}}
825+
omp.ordered depend_type(dependsink) depend_vec(%vec0 : i64) {num_loops_val = 1 : i64}
826+
omp.yield
827+
}
828+
omp.terminator
829+
}
830+
return
831+
}
832+
833+
// -----
834+
791835
func.func @omp_ordered4(%arg1 : i32, %arg2 : i32, %arg3 : i32, %vec0 : i64) -> () {
792836
omp.wsloop ordered(0) {
793837
omp.loop_nest (%0) : i32 = (%arg1) to (%arg2) step (%arg3) {
794-
// expected-error @below {{ordered depend directive must be closely nested inside a worksharing-loop with ordered clause with parameter present}}
838+
// expected-error @below {{the enclosing loop's ordered clause must have a parameter present}}
795839
omp.ordered depend_type(dependsink) depend_vec(%vec0 : i64) {num_loops_val = 1 : i64}
796-
797840
omp.yield
798841
}
799842
omp.terminator
800843
}
801844
return
802845
}
846+
803847
// -----
804848

805849
func.func @omp_ordered5(%arg1 : i32, %arg2 : i32, %arg3 : i32, %vec0 : i64, %vec1 : i64) -> () {
806850
omp.wsloop ordered(1) {
807851
omp.loop_nest (%0) : i32 = (%arg1) to (%arg2) step (%arg3) {
808852
// expected-error @below {{number of variables in depend clause does not match number of iteration variables in the doacross loop}}
809853
omp.ordered depend_type(dependsource) depend_vec(%vec0, %vec1 : i64, i64) {num_loops_val = 2 : i64}
810-
811854
omp.yield
812855
}
813856
omp.terminator

0 commit comments

Comments
 (0)