@@ -1671,7 +1671,7 @@ static void genTargetClauses(
16711671 hostEvalInfo->collectValues (clauseOps.hostEvalVars );
16721672 }
16731673 cp.processIf (llvm::omp::Directive::OMPD_target, clauseOps);
1674- cp.processIsDevicePtr (clauseOps, isDevicePtrSyms);
1674+ cp.processIsDevicePtr (stmtCtx, clauseOps, isDevicePtrSyms);
16751675 cp.processMap (loc, stmtCtx, clauseOps, llvm::omp::Directive::OMPD_unknown,
16761676 &mapSyms);
16771677 cp.processNowait (clauseOps);
@@ -2487,13 +2487,15 @@ static bool isDuplicateMappedSymbol(
24872487 const semantics::Symbol &sym,
24882488 const llvm::SetVector<const semantics::Symbol *> &privatizedSyms,
24892489 const llvm::SmallVectorImpl<const semantics::Symbol *> &hasDevSyms,
2490- const llvm::SmallVectorImpl<const semantics::Symbol *> &mappedSyms) {
2490+ const llvm::SmallVectorImpl<const semantics::Symbol *> &mappedSyms,
2491+ const llvm::SmallVectorImpl<const semantics::Symbol *> &isDevicePtrSyms) {
24912492 llvm::SmallVector<const semantics::Symbol *> concatSyms;
24922493 concatSyms.reserve (privatizedSyms.size () + hasDevSyms.size () +
2493- mappedSyms.size ());
2494+ mappedSyms.size () + isDevicePtrSyms. size () );
24942495 concatSyms.append (privatizedSyms.begin (), privatizedSyms.end ());
24952496 concatSyms.append (hasDevSyms.begin (), hasDevSyms.end ());
24962497 concatSyms.append (mappedSyms.begin (), mappedSyms.end ());
2498+ concatSyms.append (isDevicePtrSyms.begin (), isDevicePtrSyms.end ());
24972499
24982500 auto checkSymbol = [&](const semantics::Symbol &checkSym) {
24992501 return std::any_of (concatSyms.begin (), concatSyms.end (),
@@ -2533,6 +2535,38 @@ genTargetOp(lower::AbstractConverter &converter, lower::SymMap &symTable,
25332535 loc, clauseOps, defaultMaps, hasDeviceAddrSyms,
25342536 isDevicePtrSyms, mapSyms);
25352537
2538+ if (!isDevicePtrSyms.empty ()) {
2539+ // is_device_ptr maps get duplicated so the clause and synthesized
2540+ // has_device_addr entry each own a unique MapInfoOp user, keeping
2541+ // MapInfoFinalization happy while still wiring the symbol into
2542+ // has_device_addr when the user didn’t spell it explicitly.
2543+ auto insertionPt = firOpBuilder.saveInsertionPoint ();
2544+ auto alreadyPresent = [&](const semantics::Symbol *sym) {
2545+ return llvm::any_of (hasDeviceAddrSyms, [&](const semantics::Symbol *s) {
2546+ return s && sym && s->GetUltimate () == sym->GetUltimate ();
2547+ });
2548+ };
2549+
2550+ for (auto [idx, sym] : llvm::enumerate (isDevicePtrSyms)) {
2551+ mlir::Value mapVal = clauseOps.isDevicePtrVars [idx];
2552+ assert (sym && " expected symbol for is_device_ptr" );
2553+ assert (mapVal && " expected map value for is_device_ptr" );
2554+ auto mapInfo = mapVal.getDefiningOp <mlir::omp::MapInfoOp>();
2555+ assert (mapInfo && " expected map info op" );
2556+
2557+ if (!alreadyPresent (sym)) {
2558+ clauseOps.hasDeviceAddrVars .push_back (mapVal);
2559+ hasDeviceAddrSyms.push_back (sym);
2560+ }
2561+
2562+ firOpBuilder.setInsertionPointAfter (mapInfo);
2563+ mlir::Operation *clonedOp = firOpBuilder.clone (*mapInfo.getOperation ());
2564+ auto clonedMapInfo = mlir::cast<mlir::omp::MapInfoOp>(clonedOp);
2565+ clauseOps.isDevicePtrVars [idx] = clonedMapInfo.getResult ();
2566+ }
2567+ firOpBuilder.restoreInsertionPoint (insertionPt);
2568+ }
2569+
25362570 DataSharingProcessor dsp (converter, semaCtx, item->clauses , eval,
25372571 /* shouldCollectPreDeterminedSymbols=*/
25382572 lower::omp::isLastItemInQueue (item, queue),
@@ -2572,7 +2606,7 @@ genTargetOp(lower::AbstractConverter &converter, lower::SymMap &symTable,
25722606 return ;
25732607
25742608 if (!isDuplicateMappedSymbol (sym, dsp.getAllSymbolsToPrivatize (),
2575- hasDeviceAddrSyms, mapSyms)) {
2609+ hasDeviceAddrSyms, mapSyms, isDevicePtrSyms )) {
25762610 if (const auto *details =
25772611 sym.template detailsIf <semantics::HostAssocDetails>())
25782612 converter.copySymbolBinding (details->symbol (), sym);
0 commit comments