@@ -1673,7 +1673,7 @@ static void genTargetClauses(
16731673 hostEvalInfo->collectValues (clauseOps.hostEvalVars );
16741674 }
16751675 cp.processIf (llvm::omp::Directive::OMPD_target, clauseOps);
1676- cp.processIsDevicePtr (clauseOps, isDevicePtrSyms);
1676+ cp.processIsDevicePtr (stmtCtx, clauseOps, isDevicePtrSyms);
16771677 cp.processMap (loc, stmtCtx, clauseOps, llvm::omp::Directive::OMPD_unknown,
16781678 &mapSyms);
16791679 cp.processNowait (clauseOps);
@@ -2485,13 +2485,15 @@ static bool isDuplicateMappedSymbol(
24852485 const semantics::Symbol &sym,
24862486 const llvm::SetVector<const semantics::Symbol *> &privatizedSyms,
24872487 const llvm::SmallVectorImpl<const semantics::Symbol *> &hasDevSyms,
2488- const llvm::SmallVectorImpl<const semantics::Symbol *> &mappedSyms) {
2488+ const llvm::SmallVectorImpl<const semantics::Symbol *> &mappedSyms,
2489+ const llvm::SmallVectorImpl<const semantics::Symbol *> &isDevicePtrSyms) {
24892490 llvm::SmallVector<const semantics::Symbol *> concatSyms;
24902491 concatSyms.reserve (privatizedSyms.size () + hasDevSyms.size () +
2491- mappedSyms.size ());
2492+ mappedSyms.size () + isDevicePtrSyms. size () );
24922493 concatSyms.append (privatizedSyms.begin (), privatizedSyms.end ());
24932494 concatSyms.append (hasDevSyms.begin (), hasDevSyms.end ());
24942495 concatSyms.append (mappedSyms.begin (), mappedSyms.end ());
2496+ concatSyms.append (isDevicePtrSyms.begin (), isDevicePtrSyms.end ());
24952497
24962498 auto checkSymbol = [&](const semantics::Symbol &checkSym) {
24972499 return std::any_of (concatSyms.begin (), concatSyms.end (),
@@ -2531,6 +2533,41 @@ genTargetOp(lower::AbstractConverter &converter, lower::SymMap &symTable,
25312533 loc, clauseOps, defaultMaps, hasDeviceAddrSyms,
25322534 isDevicePtrSyms, mapSyms);
25332535
2536+ if (!isDevicePtrSyms.empty ()) {
2537+ // is_device_ptr maps get duplicated so the clause and synthesized
2538+ // has_device_addr entry each own a unique MapInfoOp user, keeping
2539+ // MapInfoFinalization happy while still wiring the symbol into
2540+ // has_device_addr when the user didn’t spell it explicitly.
2541+ fir::FirOpBuilder &builder = converter.getFirOpBuilder ();
2542+ auto insertionPt = builder.saveInsertionPoint ();
2543+ auto alreadyPresent = [&](const semantics::Symbol *sym) {
2544+ return llvm::any_of (hasDeviceAddrSyms, [&](const semantics::Symbol *s) {
2545+ return s && sym && s->GetUltimate () == sym->GetUltimate ();
2546+ });
2547+ };
2548+
2549+ for (auto [idx, sym] : llvm::enumerate (isDevicePtrSyms)) {
2550+ mlir::Value mapVal = clauseOps.isDevicePtrVars [idx];
2551+ if (!sym || !mapVal)
2552+ continue ;
2553+ auto mapInfo = mapVal.getDefiningOp <mlir::omp::MapInfoOp>();
2554+ if (!mapInfo)
2555+ continue ;
2556+
2557+ if (!alreadyPresent (sym)) {
2558+ clauseOps.hasDeviceAddrVars .push_back (mapVal);
2559+ hasDeviceAddrSyms.push_back (sym);
2560+ }
2561+
2562+ builder.setInsertionPointAfter (mapInfo);
2563+ auto clonedOp = builder.clone (*mapInfo.getOperation ());
2564+ auto clonedMapInfo = mlir::dyn_cast<mlir::omp::MapInfoOp>(clonedOp);
2565+ assert (clonedMapInfo && " expected cloned map info op" );
2566+ clauseOps.isDevicePtrVars [idx] = clonedMapInfo.getResult ();
2567+ }
2568+ builder.restoreInsertionPoint (insertionPt);
2569+ }
2570+
25342571 DataSharingProcessor dsp (converter, semaCtx, item->clauses , eval,
25352572 /* shouldCollectPreDeterminedSymbols=*/
25362573 lower::omp::isLastItemInQueue (item, queue),
@@ -2570,7 +2607,7 @@ genTargetOp(lower::AbstractConverter &converter, lower::SymMap &symTable,
25702607 return ;
25712608
25722609 if (!isDuplicateMappedSymbol (sym, dsp.getAllSymbolsToPrivatize (),
2573- hasDeviceAddrSyms, mapSyms)) {
2610+ hasDeviceAddrSyms, mapSyms, isDevicePtrSyms )) {
25742611 if (const auto *details =
25752612 sym.template detailsIf <semantics::HostAssocDetails>())
25762613 converter.copySymbolBinding (details->symbol (), sym);
0 commit comments