@@ -104,9 +104,9 @@ class AMDGPUHotBlockRegisterRenamingImpl {
104104 bool isSuitableRegister (MCRegister PhysReg) const ;
105105
106106 // / Check if a virtual register can be safely moved
107- bool canMoveValue (Register VirtReg, MCRegister CurrentPhysReg,
108- MCRegister TargetPhysReg, SlotIndex BBStart,
109- SlotIndex BBEnd);
107+ bool isVirtRegMovable (Register VirtReg, MCRegister CurrentPhysReg,
108+ MCRegister TargetPhysReg, SlotIndex BBStart,
109+ SlotIndex BBEnd);
110110
111111 // / Try to move a value from DenseReg to FreeReg
112112 bool tryMoveValue (MCRegister DenseReg, MCRegister FreeReg,
@@ -363,19 +363,30 @@ void AMDGPUHotBlockRegisterRenamingImpl::findFreeRegisters(
363363 }
364364}
365365
366- bool AMDGPUHotBlockRegisterRenamingImpl::canMoveValue (Register VirtReg,
367- MCRegister CurrentPhysReg,
368- MCRegister TargetPhysReg,
369- SlotIndex BBStart,
370- SlotIndex BBEnd) {
366+ bool AMDGPUHotBlockRegisterRenamingImpl::isVirtRegMovable (Register VirtReg,
367+ MCRegister CurrentPhysReg,
368+ MCRegister TargetPhysReg,
369+ SlotIndex BBStart,
370+ SlotIndex BBEnd) {
371+
372+ LiveInterval &VirtRegLI = LIS->getInterval (VirtReg);
373+
374+ // Verify precondition: single value with single segment in BB
375+ unsigned SegmentCount = 0 ;
376+ for (const LiveRange::Segment &S : VirtRegLI) {
377+ if (S.start >= BBStart && S.end <= BBEnd)
378+ SegmentCount++;
379+ }
380+ assert (SegmentCount == 1 &&
381+ " isVirtRegMovable expects VirtReg with single segment in BB" );
382+ assert (VirtRegLI.getNumValNums () == 1 &&
383+ " isVirtRegMovable expects VirtReg with single value" );
371384
372385 // Check for tied operands
373386 // A tied operand means the instruction requires source and destination to be
374387 // the same physical register. Moving such a value would break this
375388 // constraint.
376389
377- LiveInterval &VirtRegLI = LIS->getInterval (VirtReg);
378-
379390 for (const LiveRange::Segment &S : VirtRegLI) {
380391 // Only check segments within this BB
381392 if (S.start < BBStart || S.end > BBEnd)
@@ -387,8 +398,31 @@ bool AMDGPUHotBlockRegisterRenamingImpl::canMoveValue(Register VirtReg,
387398 if (!DefMI)
388399 continue ;
389400
390- for (const MachineOperand &MO : DefMI->operands ()) {
401+ for (unsigned OpIdx = 0 , E = DefMI->getNumOperands (); OpIdx < E; ++OpIdx) {
402+ const MachineOperand &MO = DefMI->getOperand (OpIdx);
391403 if (MO.isReg () && MO.getReg () == VirtReg && MO.isDef () && MO.isTied ()) {
404+ // Found a tied def - need to check the source operand it's tied to
405+ unsigned TiedIdx = DefMI->findTiedOperandIdx (OpIdx);
406+ const MachineOperand &TiedMO = DefMI->getOperand (TiedIdx);
407+
408+ // If the tied source is a register, verify it won't conflict
409+ if (TiedMO.isReg ()) {
410+ Register TiedReg = TiedMO.getReg ();
411+ if (TiedReg.isVirtual ()) {
412+ MCRegister TiedPhysReg = VRM->getPhys (TiedReg);
413+ // Cannot move if it would violate the tied constraint
414+ // (source and dest must be in same physical register)
415+ if (TiedPhysReg != CurrentPhysReg) {
416+ LLVM_DEBUG (dbgs () << " Cannot move " << printReg (VirtReg, TRI)
417+ << " : tied to " << printReg (TiedReg, TRI)
418+ << " which is in different PhysReg "
419+ << printReg (TiedPhysReg, TRI) << " at " << S.start
420+ << " in " << *DefMI);
421+ return false ;
422+ }
423+ }
424+ }
425+
392426 LLVM_DEBUG (dbgs () << " Cannot move " << printReg (VirtReg, TRI)
393427 << " : has tied def at " << S.start << " in "
394428 << *DefMI);
@@ -418,6 +452,9 @@ bool AMDGPUHotBlockRegisterRenamingImpl::tryMoveValue(MCRegister DenseReg,
418452 Register VirtReg = SI.value ()->reg ();
419453
420454 // Check if this VirtReg is mapped to DenseReg
455+ // NOTE: This is NOT redundant! We iterate per register unit, and units
456+ // can be shared between aliased registers (e.g., VGPR0 and VGPR0_VGPR1).
457+ // This check filters out VirtRegs mapped to aliased registers.
421458 if (VRM->getPhys (VirtReg) != DenseReg)
422459 continue ;
423460
@@ -450,7 +487,7 @@ bool AMDGPUHotBlockRegisterRenamingImpl::tryMoveValue(MCRegister DenseReg,
450487 }
451488
452489 // Check: Can this value be safely moved?
453- if (!canMoveValue (VirtReg, DenseReg, FreeReg, BBStart, BBEnd)) {
490+ if (!isVirtRegMovable (VirtReg, DenseReg, FreeReg, BBStart, BBEnd)) {
454491 // Cache the result to avoid checking again
455492 UnmovableVRegs.insert (VirtReg);
456493 continue ;
0 commit comments