@@ -262,6 +262,62 @@ static llvm::omp::ProcBindKind getProcBindKind(omp::ClauseProcBindKind kind) {
262
262
llvm_unreachable (" Unknown ClauseProcBindKind kind" );
263
263
}
264
264
265
+ // / Helper function to map block arguments defined by ignored loop wrappers to
266
+ // / LLVM values and prevent any uses of those from triggering null pointer
267
+ // / dereferences.
268
+ // /
269
+ // / This must be called after block arguments of parent wrappers have already
270
+ // / been mapped to LLVM IR values.
271
+ static LogicalResult
272
+ convertIgnoredWrapper (omp::LoopWrapperInterface &opInst,
273
+ LLVM::ModuleTranslation &moduleTranslation) {
274
+ // Map block arguments directly to the LLVM value associated to the
275
+ // corresponding operand. This is semantically equivalent to this wrapper not
276
+ // being present.
277
+ auto forwardArgs =
278
+ [&moduleTranslation](llvm::ArrayRef<BlockArgument> blockArgs,
279
+ OperandRange operands) {
280
+ for (auto [arg, var] : llvm::zip_equal (blockArgs, operands))
281
+ moduleTranslation.mapValue (arg, moduleTranslation.lookupValue (var));
282
+ };
283
+
284
+ return llvm::TypeSwitch<Operation *, LogicalResult>(opInst)
285
+ .Case ([&](omp::SimdOp op) {
286
+ auto blockArgIface = cast<omp::BlockArgOpenMPOpInterface>(*op);
287
+ forwardArgs (blockArgIface.getPrivateBlockArgs (), op.getPrivateVars ());
288
+ forwardArgs (blockArgIface.getReductionBlockArgs (),
289
+ op.getReductionVars ());
290
+ return success ();
291
+ })
292
+ .Default ([&](Operation *op) {
293
+ return op->emitError () << " cannot ignore nested wrapper" ;
294
+ });
295
+ }
296
+
297
+ // / Helper function to call \c convertIgnoredWrapper() for all wrappers of the
298
+ // / given \c loopOp nested inside of \c parentOp. This has the effect of mapping
299
+ // / entry block arguments defined by these operations to outside values.
300
+ // /
301
+ // / It must be called after block arguments of \c parentOp have already been
302
+ // / mapped themselves.
303
+ static LogicalResult
304
+ convertIgnoredWrappers (omp::LoopNestOp loopOp,
305
+ omp::LoopWrapperInterface parentOp,
306
+ LLVM::ModuleTranslation &moduleTranslation) {
307
+ SmallVector<omp::LoopWrapperInterface> wrappers;
308
+ loopOp.gatherWrappers (wrappers);
309
+
310
+ // Process wrappers nested inside of `parentOp` from outermost to innermost.
311
+ for (auto it =
312
+ std::next (std::find (wrappers.rbegin (), wrappers.rend (), parentOp));
313
+ it != wrappers.rend (); ++it) {
314
+ if (failed (convertIgnoredWrapper (*it, moduleTranslation)))
315
+ return failure ();
316
+ }
317
+
318
+ return success ();
319
+ }
320
+
265
321
// / Converts an OpenMP 'masked' operation into LLVM IR using OpenMPIRBuilder.
266
322
static LogicalResult
267
323
convertOmpMasked (Operation &opInst, llvm::IRBuilderBase &builder,
@@ -1262,9 +1318,6 @@ convertOmpWsloop(Operation &opInst, llvm::IRBuilderBase &builder,
1262
1318
!wsloopOp.getPrivateVars ().empty () || wsloopOp.getPrivateSyms ())
1263
1319
return opInst.emitError (" unhandled clauses for translation to LLVM IR" );
1264
1320
1265
- // FIXME: Here any other nested wrappers (e.g. omp.simd) are skipped, so
1266
- // codegen for composite constructs like 'DO/FOR SIMD' will be the same as for
1267
- // 'DO/FOR'.
1268
1321
auto loopOp = cast<omp::LoopNestOp>(wsloopOp.getWrappedLoop ());
1269
1322
1270
1323
llvm::ArrayRef<bool > isByRef = getIsByRef (wsloopOp.getReductionByref ());
@@ -1302,6 +1355,13 @@ convertOmpWsloop(Operation &opInst, llvm::IRBuilderBase &builder,
1302
1355
isByRef)))
1303
1356
return failure ();
1304
1357
1358
+ // TODO: Replace this with proper composite translation support.
1359
+ // Currently, all nested wrappers are ignored, so 'do/for simd' will be
1360
+ // treated the same as a standalone 'do/for'. This is allowed by the spec,
1361
+ // since it's equivalent to always using a SIMD length of 1.
1362
+ if (failed (convertIgnoredWrappers (loopOp, wsloopOp, moduleTranslation)))
1363
+ return failure ();
1364
+
1305
1365
// Store the mapping between reduction variables and their private copies on
1306
1366
// ModuleTranslation stack. It can be then recovered when translating
1307
1367
// omp.reduce operations in a separate call.
0 commit comments