@@ -381,6 +381,8 @@ static llvm::Expected<llvm::BasicBlock *> convertOmpOpRegions(
381
381
Region ®ion, StringRef blockName, llvm::IRBuilderBase &builder,
382
382
LLVM::ModuleTranslation &moduleTranslation,
383
383
SmallVectorImpl<llvm::PHINode *> *continuationBlockPHIs = nullptr ) {
384
+ bool isLoopWrapper = isa<omp::LoopWrapperInterface>(region.getParentOp ());
385
+
384
386
llvm::BasicBlock *continuationBlock =
385
387
splitBB (builder, true , " omp.region.cont" );
386
388
llvm::BasicBlock *sourceBlock = builder.GetInsertBlock ();
@@ -397,30 +399,34 @@ static llvm::Expected<llvm::BasicBlock *> convertOmpOpRegions(
397
399
398
400
// Terminators (namely YieldOp) may be forwarding values to the region that
399
401
// need to be available in the continuation block. Collect the types of these
400
- // operands in preparation of creating PHI nodes.
402
+ // operands in preparation of creating PHI nodes. This is skipped for loop
403
+ // wrapper operations, for which we know in advance they have no terminators.
401
404
SmallVector<llvm::Type *> continuationBlockPHITypes;
402
- bool operandsProcessed = false ;
403
405
unsigned numYields = 0 ;
404
- for (Block &bb : region.getBlocks ()) {
405
- if (omp::YieldOp yield = dyn_cast<omp::YieldOp>(bb.getTerminator ())) {
406
- if (!operandsProcessed) {
407
- for (unsigned i = 0 , e = yield->getNumOperands (); i < e; ++i) {
408
- continuationBlockPHITypes.push_back (
409
- moduleTranslation.convertType (yield->getOperand (i).getType ()));
410
- }
411
- operandsProcessed = true ;
412
- } else {
413
- assert (continuationBlockPHITypes.size () == yield->getNumOperands () &&
414
- " mismatching number of values yielded from the region" );
415
- for (unsigned i = 0 , e = yield->getNumOperands (); i < e; ++i) {
416
- llvm::Type *operandType =
417
- moduleTranslation.convertType (yield->getOperand (i).getType ());
418
- (void )operandType;
419
- assert (continuationBlockPHITypes[i] == operandType &&
420
- " values of mismatching types yielded from the region" );
406
+
407
+ if (!isLoopWrapper) {
408
+ bool operandsProcessed = false ;
409
+ for (Block &bb : region.getBlocks ()) {
410
+ if (omp::YieldOp yield = dyn_cast<omp::YieldOp>(bb.getTerminator ())) {
411
+ if (!operandsProcessed) {
412
+ for (unsigned i = 0 , e = yield->getNumOperands (); i < e; ++i) {
413
+ continuationBlockPHITypes.push_back (
414
+ moduleTranslation.convertType (yield->getOperand (i).getType ()));
415
+ }
416
+ operandsProcessed = true ;
417
+ } else {
418
+ assert (continuationBlockPHITypes.size () == yield->getNumOperands () &&
419
+ " mismatching number of values yielded from the region" );
420
+ for (unsigned i = 0 , e = yield->getNumOperands (); i < e; ++i) {
421
+ llvm::Type *operandType =
422
+ moduleTranslation.convertType (yield->getOperand (i).getType ());
423
+ (void )operandType;
424
+ assert (continuationBlockPHITypes[i] == operandType &&
425
+ " values of mismatching types yielded from the region" );
426
+ }
421
427
}
428
+ numYields++;
422
429
}
423
- numYields++;
424
430
}
425
431
}
426
432
@@ -458,6 +464,13 @@ static llvm::Expected<llvm::BasicBlock *> convertOmpOpRegions(
458
464
moduleTranslation.convertBlock (*bb, bb->isEntryBlock (), builder)))
459
465
return llvm::make_error<PreviouslyReportedError>();
460
466
467
+ // Create a direct branch here for loop wrappers to prevent their lack of a
468
+ // terminator from causing a crash below.
469
+ if (isLoopWrapper) {
470
+ builder.CreateBr (continuationBlock);
471
+ continue ;
472
+ }
473
+
461
474
// Special handling for `omp.yield` and `omp.terminator` (we may have more
462
475
// than one): they return the control to the parent OpenMP dialect operation
463
476
// so replace them with the branch to the continuation block. We handle this
0 commit comments