@@ -1978,8 +1978,35 @@ LogicalResult ModuleImport::convertInstruction(llvm::Instruction *inst) {
19781978 }
19791979
19801980 // Convert all instructions that have an mlirBuilder.
1981- if (succeeded (convertInstructionImpl (builder, inst, *this , iface)))
1981+ if (succeeded (convertInstructionImpl (builder, inst, *this , iface))) {
1982+ // Handle DIAssignID metadata on store and alloca instructions for
1983+ // assignment tracking
1984+ if (auto *assignIDMD =
1985+ inst->getMetadata (llvm::LLVMContext::MD_DIAssignID)) {
1986+ if (auto *assignIDNode = dyn_cast<llvm::DIAssignID>(assignIDMD)) {
1987+ // Get the converted MLIR operation
1988+ Operation *mlirOp = lookupOperation (inst);
1989+ if (mlirOp) {
1990+ // Get or create the DIAssignIDAttr using the same mapping as debug
1991+ // intrinsics
1992+ auto it = assignIDMapping.find (assignIDNode);
1993+ DIAssignIDAttr assignIdAttr;
1994+ if (it != assignIDMapping.end ()) {
1995+ assignIdAttr = it->second ;
1996+ } else {
1997+ // Create new DIAssignIDAttr and add to mapping
1998+ DistinctAttr distinctId =
1999+ DistinctAttr::create (UnitAttr::get (context));
2000+ assignIdAttr = DIAssignIDAttr::get (context, distinctId);
2001+ assignIDMapping[assignIDNode] = assignIdAttr;
2002+ }
2003+ // Attach the assignment ID as an attribute to the operation
2004+ mlirOp->setAttr (" DIAssignID" , assignIdAttr);
2005+ }
2006+ }
2007+ }
19822008 return success ();
2009+ }
19832010
19842011 return emitError (loc) << " unhandled instruction: " << diag (*inst);
19852012}
@@ -2518,24 +2545,94 @@ ModuleImport::processDebugIntrinsic(llvm::DbgVariableIntrinsic *dbgIntr,
25182545 return emitError (loc) << " failed to convert a debug intrinsic operand: "
25192546 << diag (*dbgIntr);
25202547
2548+ // Enhanced dominance validation with comprehensive undef value handling
2549+ bool isUndefValue = false ;
2550+ bool isComplexUndef = false ;
2551+ if (auto *nodeAsVal =
2552+ dyn_cast<llvm::MetadataAsValue>(dbgIntr->getArgOperand (0 ))) {
2553+ if (auto *node =
2554+ dyn_cast<llvm::ValueAsMetadata>(nodeAsVal->getMetadata ())) {
2555+ if (isa<llvm::UndefValue>(node->getValue ())) {
2556+ isUndefValue = true ;
2557+ } else if (isa<llvm::PoisonValue>(node->getValue ())) {
2558+ // Poison values require similar handling to undef values
2559+ isUndefValue = true ;
2560+ isComplexUndef = true ;
2561+ }
2562+ } else if (isa<llvm::MDNode>(nodeAsVal->getMetadata ())) {
2563+ // Complex metadata nodes may contain undef values
2564+ isComplexUndef = true ;
2565+ }
2566+ }
2567+
25212568 // Ensure that the debug intrinsic is inserted right after its operand is
25222569 // defined. Otherwise, the operand might not necessarily dominate the
25232570 // intrinsic. If the defining operation is a terminator, insert the intrinsic
25242571 // into a dominated block.
25252572 OpBuilder::InsertionGuard guard (builder);
2526- if (Operation *op = argOperand->getDefiningOp ();
2527- op && op->hasTrait <OpTrait::IsTerminator>()) {
2573+ if (isUndefValue || isComplexUndef) {
2574+ // Enhanced placement logic for undef and complex values
2575+ Block *currentBlock = builder.getInsertionBlock ();
2576+ if (!currentBlock) {
2577+ return emitError (loc) << " no insertion block available for debug "
2578+ " intrinsic with undef value" ;
2579+ }
2580+
2581+ if (currentBlock->empty ()) {
2582+ return emitError (loc) << " cannot place debug intrinsic in empty block" ;
2583+ }
2584+
2585+ Operation *terminator = ¤tBlock->back ();
2586+ if (terminator->hasTrait <OpTrait::IsTerminator>()) {
2587+ builder.setInsertionPoint (terminator);
2588+ } else {
2589+ // Validate that we can safely insert at the end of the block
2590+ if (currentBlock->hasNoSuccessors ()) {
2591+ return emitError (loc)
2592+ << " cannot place debug intrinsic in block without successors" ;
2593+ }
2594+ }
2595+
2596+ // Additional validation for complex undef patterns
2597+ if (isComplexUndef && emitExpensiveWarnings) {
2598+ emitWarning (loc) << " debug intrinsic contains complex undef pattern that "
2599+ " may affect debugging accuracy" ;
2600+ }
2601+ } else if (Operation *op = argOperand->getDefiningOp ();
2602+ op && op->hasTrait <OpTrait::IsTerminator>()) {
25282603 // Find a dominated block that can hold the debug intrinsic.
25292604 auto dominatedBlocks = domInfo.getNode (op->getBlock ())->children ();
25302605 // If no block is dominated by the terminator, this intrinisc cannot be
25312606 // converted.
25322607 if (dominatedBlocks.empty ())
25332608 return emitUnsupportedWarning ();
2609+
2610+ // Enhanced validation for terminator-dominated placement
2611+ Block *dominatedBlock = (*dominatedBlocks.begin ())->getBlock ();
2612+ if (!dominatedBlock || dominatedBlock->empty ()) {
2613+ return emitError (loc)
2614+ << " dominated block is invalid for debug intrinsic placement" ;
2615+ }
2616+
2617+ Operation *dominatedTerminator = dominatedBlock->getTerminator ();
2618+ if (!dominatedTerminator) {
2619+ return emitError (loc) << " dominated block lacks terminator for safe "
2620+ " debug intrinsic placement" ;
2621+ }
2622+
25342623 // Set insertion point before the terminator, to avoid inserting something
25352624 // before landingpads.
2536- Block *dominatedBlock = (*dominatedBlocks.begin ())->getBlock ();
2537- builder.setInsertionPoint (dominatedBlock->getTerminator ());
2625+ builder.setInsertionPoint (dominatedTerminator);
25382626 } else {
2627+ // Standard placement with additional validation
2628+ if (argOperand->getDefiningOp ()) {
2629+ // Verify that the defining operation is in a valid state for dominance
2630+ Operation *defOp = argOperand->getDefiningOp ();
2631+ if (!defOp->getBlock ()) {
2632+ return emitError (loc)
2633+ << " debug intrinsic operand has invalid defining operation" ;
2634+ }
2635+ }
25392636 builder.setInsertionPointAfterValue (*argOperand);
25402637 }
25412638 auto locationExprAttr =
@@ -2546,6 +2643,64 @@ ModuleImport::processDebugIntrinsic(llvm::DbgVariableIntrinsic *dbgIntr,
25462643 return builder.create <LLVM::DbgDeclareOp>(
25472644 loc, *argOperand, localVariableAttr, locationExprAttr);
25482645 })
2646+ .Case ([&](llvm::DbgAssignIntrinsic *dbgAssign) {
2647+ // Convert all operands for DbgAssignIntrinsic
2648+
2649+ // Get the assignment ID (operand 3) and preserve the mapping
2650+ auto *assignIdNodeAsVal =
2651+ cast<llvm::MetadataAsValue>(dbgAssign->getArgOperand (3 ));
2652+ auto *assignIdNode =
2653+ cast<llvm::DIAssignID>(assignIdNodeAsVal->getMetadata ());
2654+
2655+ // Enhanced assignment ID consistency verification
2656+ DIAssignIDAttr assignIdAttr;
2657+ auto it = assignIDMapping.find (assignIdNode);
2658+ if (it != assignIDMapping.end ()) {
2659+ assignIdAttr = it->second ;
2660+ // Verify consistency of reused assignment IDs
2661+ if (emitExpensiveWarnings) {
2662+ // Check if this assignment ID usage is consistent with previous
2663+ // usage Note: Assignment ID consistency checking requires
2664+ // traversing debug intrinsics which may be expensive, but
2665+ // provides valuable validation for debug tracking
2666+ emitWarning (loc) << " reusing assignment ID - verify consistent "
2667+ " variable tracking" ;
2668+ }
2669+ } else {
2670+ // Create a new DIAssignIDAttr with distinct ID for this
2671+ // DIAssignID
2672+ DistinctAttr distinctId =
2673+ DistinctAttr::create (UnitAttr::get (context));
2674+ assignIdAttr = DIAssignIDAttr::get (context, distinctId);
2675+ assignIDMapping[assignIdNode] = assignIdAttr;
2676+
2677+ // Validate that the assignment ID is properly structured
2678+ if (!assignIdNode->isDistinct ()) {
2679+ emitWarning (loc)
2680+ << " assignment ID should be distinct for proper tracking" ;
2681+ }
2682+ }
2683+
2684+ // Get the address operand (operand 4)
2685+ FailureOr<Value> addressOperand =
2686+ convertMetadataValue (dbgAssign->getArgOperand (4 ));
2687+ if (failed (addressOperand))
2688+ return (Operation *)nullptr ;
2689+
2690+ // Get the address expression (operand 5)
2691+ auto *addressExprNodeAsVal =
2692+ cast<llvm::MetadataAsValue>(dbgAssign->getArgOperand (5 ));
2693+ auto *addressExprNode =
2694+ cast<llvm::DIExpression>(addressExprNodeAsVal->getMetadata ());
2695+ auto addressExprAttr =
2696+ debugImporter->translateExpression (addressExprNode);
2697+
2698+ return builder
2699+ .create <LLVM::DbgAssignOp>(loc, *argOperand, localVariableAttr,
2700+ locationExprAttr, assignIdAttr,
2701+ *addressOperand, addressExprAttr)
2702+ .getOperation ();
2703+ })
25492704 .Case ([&](llvm::DbgValueInst *) {
25502705 return builder.create <LLVM::DbgValueOp>(
25512706 loc, *argOperand, localVariableAttr, locationExprAttr);
0 commit comments