@@ -262,6 +262,62 @@ static llvm::omp::ProcBindKind getProcBindKind(omp::ClauseProcBindKind kind) {
262262 llvm_unreachable (" Unknown ClauseProcBindKind kind" );
263263}
264264
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+
265321// / Converts an OpenMP 'masked' operation into LLVM IR using OpenMPIRBuilder.
266322static LogicalResult
267323convertOmpMasked (Operation &opInst, llvm::IRBuilderBase &builder,
@@ -1262,9 +1318,6 @@ convertOmpWsloop(Operation &opInst, llvm::IRBuilderBase &builder,
12621318 !wsloopOp.getPrivateVars ().empty () || wsloopOp.getPrivateSyms ())
12631319 return opInst.emitError (" unhandled clauses for translation to LLVM IR" );
12641320
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'.
12681321 auto loopOp = cast<omp::LoopNestOp>(wsloopOp.getWrappedLoop ());
12691322
12701323 llvm::ArrayRef<bool > isByRef = getIsByRef (wsloopOp.getReductionByref ());
@@ -1302,6 +1355,13 @@ convertOmpWsloop(Operation &opInst, llvm::IRBuilderBase &builder,
13021355 isByRef)))
13031356 return failure ();
13041357
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+
13051365 // Store the mapping between reduction variables and their private copies on
13061366 // ModuleTranslation stack. It can be then recovered when translating
13071367 // omp.reduce operations in a separate call.
0 commit comments