@@ -1677,7 +1677,7 @@ static void genTargetClauses(
16771677 hostEvalInfo->collectValues (clauseOps.hostEvalVars );
16781678 }
16791679 cp.processIf (llvm::omp::Directive::OMPD_target, clauseOps);
1680- cp.processIsDevicePtr (clauseOps, isDevicePtrSyms);
1680+ cp.processIsDevicePtr (stmtCtx, clauseOps, isDevicePtrSyms);
16811681 cp.processMap (loc, stmtCtx, clauseOps, llvm::omp::Directive::OMPD_unknown,
16821682 &mapSyms);
16831683 cp.processNowait (clauseOps);
@@ -2499,13 +2499,15 @@ static bool isDuplicateMappedSymbol(
24992499 const semantics::Symbol &sym,
25002500 const llvm::SetVector<const semantics::Symbol *> &privatizedSyms,
25012501 const llvm::SmallVectorImpl<const semantics::Symbol *> &hasDevSyms,
2502- const llvm::SmallVectorImpl<const semantics::Symbol *> &mappedSyms) {
2502+ const llvm::SmallVectorImpl<const semantics::Symbol *> &mappedSyms,
2503+ const llvm::SmallVectorImpl<const semantics::Symbol *> &isDevicePtrSyms) {
25032504 llvm::SmallVector<const semantics::Symbol *> concatSyms;
25042505 concatSyms.reserve (privatizedSyms.size () + hasDevSyms.size () +
2505- mappedSyms.size ());
2506+ mappedSyms.size () + isDevicePtrSyms. size () );
25062507 concatSyms.append (privatizedSyms.begin (), privatizedSyms.end ());
25072508 concatSyms.append (hasDevSyms.begin (), hasDevSyms.end ());
25082509 concatSyms.append (mappedSyms.begin (), mappedSyms.end ());
2510+ concatSyms.append (isDevicePtrSyms.begin (), isDevicePtrSyms.end ());
25092511
25102512 auto checkSymbol = [&](const semantics::Symbol &checkSym) {
25112513 return std::any_of (concatSyms.begin (), concatSyms.end (),
@@ -2545,6 +2547,38 @@ genTargetOp(lower::AbstractConverter &converter, lower::SymMap &symTable,
25452547 loc, clauseOps, defaultMaps, hasDeviceAddrSyms,
25462548 isDevicePtrSyms, mapSyms);
25472549
2550+ if (!isDevicePtrSyms.empty ()) {
2551+ // is_device_ptr maps get duplicated so the clause and synthesized
2552+ // has_device_addr entry each own a unique MapInfoOp user, keeping
2553+ // MapInfoFinalization happy while still wiring the symbol into
2554+ // has_device_addr when the user didn’t spell it explicitly.
2555+ auto insertionPt = firOpBuilder.saveInsertionPoint ();
2556+ auto alreadyPresent = [&](const semantics::Symbol *sym) {
2557+ return llvm::any_of (hasDeviceAddrSyms, [&](const semantics::Symbol *s) {
2558+ return s && sym && s->GetUltimate () == sym->GetUltimate ();
2559+ });
2560+ };
2561+
2562+ for (auto [idx, sym] : llvm::enumerate (isDevicePtrSyms)) {
2563+ mlir::Value mapVal = clauseOps.isDevicePtrVars [idx];
2564+ assert (sym && " expected symbol for is_device_ptr" );
2565+ assert (mapVal && " expected map value for is_device_ptr" );
2566+ auto mapInfo = mapVal.getDefiningOp <mlir::omp::MapInfoOp>();
2567+ assert (mapInfo && " expected map info op" );
2568+
2569+ if (!alreadyPresent (sym)) {
2570+ clauseOps.hasDeviceAddrVars .push_back (mapVal);
2571+ hasDeviceAddrSyms.push_back (sym);
2572+ }
2573+
2574+ firOpBuilder.setInsertionPointAfter (mapInfo);
2575+ mlir::Operation *clonedOp = firOpBuilder.clone (*mapInfo.getOperation ());
2576+ auto clonedMapInfo = mlir::cast<mlir::omp::MapInfoOp>(clonedOp);
2577+ clauseOps.isDevicePtrVars [idx] = clonedMapInfo.getResult ();
2578+ }
2579+ firOpBuilder.restoreInsertionPoint (insertionPt);
2580+ }
2581+
25482582 DataSharingProcessor dsp (converter, semaCtx, item->clauses , eval,
25492583 /* shouldCollectPreDeterminedSymbols=*/
25502584 lower::omp::isLastItemInQueue (item, queue),
@@ -2584,7 +2618,7 @@ genTargetOp(lower::AbstractConverter &converter, lower::SymMap &symTable,
25842618 return ;
25852619
25862620 if (!isDuplicateMappedSymbol (sym, dsp.getAllSymbolsToPrivatize (),
2587- hasDeviceAddrSyms, mapSyms)) {
2621+ hasDeviceAddrSyms, mapSyms, isDevicePtrSyms )) {
25882622 if (const auto *details =
25892623 sym.template detailsIf <semantics::HostAssocDetails>())
25902624 converter.copySymbolBinding (details->symbol (), sym);
0 commit comments