@@ -3162,24 +3162,32 @@ void CancelOp::build(OpBuilder &builder, OperationState &state,
31623162 CancelOp::build (builder, state, clauses.cancelDirective , clauses.ifExpr );
31633163}
31643164
3165+ static Operation *getParentInSameDialect (Operation *thisOp) {
3166+ Operation *parent = thisOp->getParentOp ();
3167+ while (parent) {
3168+ if (parent->getDialect () == thisOp->getDialect ())
3169+ return parent;
3170+ parent = parent->getParentOp ();
3171+ }
3172+ return nullptr ;
3173+ }
3174+
31653175LogicalResult CancelOp::verify () {
31663176 ClauseCancellationConstructType cct = getCancelDirective ();
3167- Operation *parentOp = (*this )->getParentOp ();
3168-
3169- if (!parentOp) {
3170- return emitOpError () << " must be used within a region supporting "
3171- " cancel directive" ;
3172- }
3177+ // The next OpenMP operation in the chain of parents
3178+ Operation *structuralParent = getParentInSameDialect ((*this ).getOperation ());
3179+ if (!structuralParent)
3180+ return emitOpError () << " Orphaned cancel construct" ;
31733181
31743182 if ((cct == ClauseCancellationConstructType::Parallel) &&
3175- !isa<ParallelOp>(parentOp )) {
3183+ !mlir:: isa<ParallelOp>(structuralParent )) {
31763184 return emitOpError () << " cancel parallel must appear "
31773185 << " inside a parallel region" ;
31783186 }
31793187 if (cct == ClauseCancellationConstructType::Loop) {
3180- auto loopOp = dyn_cast<LoopNestOp>(parentOp);
3181- auto wsloopOp = llvm::dyn_cast_if_present<WsloopOp>(
3182- loopOp ? loopOp ->getParentOp () : nullptr );
3188+ // structural parent will be omp.loop_nest, directly nested inside
3189+ // omp.wsloop
3190+ auto wsloopOp = mlir::dyn_cast<WsloopOp>(structuralParent ->getParentOp ());
31833191
31843192 if (!wsloopOp) {
31853193 return emitOpError ()
@@ -3195,12 +3203,15 @@ LogicalResult CancelOp::verify() {
31953203 }
31963204
31973205 } else if (cct == ClauseCancellationConstructType::Sections) {
3198- if (!(isa<SectionsOp>(parentOp) || isa<SectionOp>(parentOp))) {
3206+ // structural parent will be an omp.section, directly nested inside
3207+ // omp.sections
3208+ auto sectionsOp =
3209+ mlir::dyn_cast<SectionsOp>(structuralParent->getParentOp ());
3210+ if (!sectionsOp) {
31993211 return emitOpError () << " cancel sections must appear "
32003212 << " inside a sections region" ;
32013213 }
3202- if (isa_and_nonnull<SectionsOp>(parentOp->getParentOp ()) &&
3203- cast<SectionsOp>(parentOp->getParentOp ()).getNowaitAttr ()) {
3214+ if (sectionsOp.getNowait ()) {
32043215 return emitError () << " A sections construct that is canceled "
32053216 << " must not have a nowait clause" ;
32063217 }
@@ -3220,25 +3231,25 @@ void CancellationPointOp::build(OpBuilder &builder, OperationState &state,
32203231
32213232LogicalResult CancellationPointOp::verify () {
32223233 ClauseCancellationConstructType cct = getCancelDirective ();
3223- Operation *parentOp = (*this )->getParentOp ();
3224-
3225- if (!parentOp) {
3226- return emitOpError () << " must be used within a region supporting "
3227- " cancellation point directive" ;
3228- }
3234+ // The next OpenMP operation in the chain of parents
3235+ Operation *structuralParent = getParentInSameDialect ((*this ).getOperation ());
3236+ if (!structuralParent)
3237+ return emitOpError () << " Orphaned cancellation point" ;
32293238
32303239 if ((cct == ClauseCancellationConstructType::Parallel) &&
3231- !( isa<ParallelOp>(parentOp) )) {
3240+ !mlir:: isa<ParallelOp>(structuralParent )) {
32323241 return emitOpError () << " cancellation point parallel must appear "
32333242 << " inside a parallel region" ;
32343243 }
3244+ // Strucutal parent here will be an omp.loop_nest. Get the parent of that to
3245+ // find the wsloop
32353246 if ((cct == ClauseCancellationConstructType::Loop) &&
3236- (! isa<LoopNestOp>(parentOp) || !isa< WsloopOp>(parentOp ->getParentOp () ))) {
3247+ !mlir:: isa<WsloopOp>(structuralParent ->getParentOp ())) {
32373248 return emitOpError () << " cancellation point loop must appear "
32383249 << " inside a worksharing-loop region" ;
32393250 }
32403251 if ((cct == ClauseCancellationConstructType::Sections) &&
3241- !( isa<SectionsOp>(parentOp) || isa< SectionOp>(parentOp) )) {
3252+ !mlir:: isa<omp:: SectionOp>(structuralParent )) {
32423253 return emitOpError () << " cancellation point sections must appear "
32433254 << " inside a sections region" ;
32443255 }
0 commit comments