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