@@ -1330,59 +1330,71 @@ bool RegisterCoalescer::reMaterializeDef(const CoalescerPair &CP,
13301330 // the same basic block to enable better coalescing.
13311331 if (DstReg.isPhysical ()) {
13321332 MachineBasicBlock *MBB = CopyMI->getParent ();
1333- if (DefMI->getParent () == MBB) {
1334- // Check if there's already an identical instruction before CopyMI
1335- // If so, allow rematerialization to avoid redundant instructions
1336- bool FoundCopy = false ;
1337- for (MachineInstr &MI : *MBB) {
1338- if (&MI == CopyMI) {
1339- FoundCopy = true ;
1340- continue ;
1341- }
1333+ if (DefMI->getParent () == MBB && !MBB->empty ()) {
1334+ // Quick check: is the last instruction a return using DstReg?
1335+ const MachineInstr &LastInstr = MBB->back ();
1336+ if (LastInstr.isReturn () && LastInstr.readsRegister (DstReg, TRI)) {
1337+ // This is a return register, perform checks
1338+
1339+ // Exception: allow rematerialization for zero-idiom instructions
1340+ // (e.g., xorps %xmm0, %xmm0) because rematerialization produces
1341+ // independent zero-latency instructions, which is better than copying
1342+ const TargetSubtargetInfo &STI = MF->getSubtarget ();
1343+ APInt Mask;
1344+ if (STI.isZeroIdiom (DefMI, Mask)) {
1345+ LLVM_DEBUG (dbgs () << " \t Allow remat: zero-idiom instruction\n " );
1346+ } else {
1347+ // Check for duplicate DefMI before CopyMI
1348+ bool HasDuplicateDef = false ;
1349+ for (MachineBasicBlock::iterator I = MBB->begin (); &*I != CopyMI; ++I) {
1350+ if (&*I != DefMI &&
1351+ I->isIdenticalTo (*DefMI, MachineInstr::IgnoreDefs)) {
1352+ HasDuplicateDef = true ;
1353+ break ;
1354+ }
1355+ }
13421356
1343- // Before CopyMI: check for duplicate instructions
1344- if (!FoundCopy && &MI != DefMI &&
1345- MI.isIdenticalTo (*DefMI, MachineInstr::IgnoreDefs)) {
1346- break ; // Found duplicate, allow rematerialization
1347- } else if (FoundCopy) {
1348- // After CopyMI: check if used as return register
1349- // If the register is redefined, it's not a return register
1350- if (MI.modifiesRegister (DstReg, TRI))
1351- break ;
1352- // If there's a return instruction that uses this register, skip remat
1353- if (MI.isReturn () && MI.readsRegister (DstReg, TRI)) {
1354- // Exception: if DefMI is moving a constant and SrcReg has no other
1355- // uses (besides copies), rematerialization is beneficial to
1356- // eliminate the def
1357+ // Check if register is redefined after CopyMI
1358+ bool RegRedefinedAfterCopy = false ;
1359+ for (MachineBasicBlock::iterator I = std::next (CopyMI->getIterator ());
1360+ I != MBB->end (); ++I) {
1361+ if (I->modifiesRegister (DstReg, TRI)) {
1362+ RegRedefinedAfterCopy = true ;
1363+ break ;
1364+ }
1365+ if (I->isReturn ())
1366+ break ;
1367+ }
1368+
1369+ // Skip remat only if: no duplicate def AND reg not redefined
1370+ if (!HasDuplicateDef && !RegRedefinedAfterCopy) {
1371+ // Exception: allow remat for constant moves with limited uses
13571372 if (DefMI->isMoveImmediate ()) {
1358- // Quick check: if there's only one use and it's this copy,
1359- // definitely remat
13601373 if (MRI->hasOneNonDBGUse (SrcReg)) {
1361- LLVM_DEBUG (dbgs ()
1362- << " \t Allow remat: single use constant move\n " );
1363- break ;
1364- }
1365-
1366- // Check all uses to see if they're all copies
1367- bool OnlyUsedByCopies = true ;
1368- unsigned UseCount = 0 ;
1369- for (const MachineOperand &MO : MRI->use_operands (SrcReg)) {
1370- const MachineInstr *UseMI = MO.getParent ();
1371- if (!UseMI->isCopy () && !UseMI->isSubregToReg ()) {
1372- OnlyUsedByCopies = false ;
1373- break ;
1374+ LLVM_DEBUG (dbgs () << " \t Allow remat: single use constant move\n " );
1375+ } else {
1376+ // Check if all uses are copies
1377+ bool OnlyUsedByCopies = true ;
1378+ for (const MachineOperand &MO : MRI->use_operands (SrcReg)) {
1379+ const MachineInstr *UseMI = MO.getParent ();
1380+ if (!UseMI->isCopy () && !UseMI->isSubregToReg ()) {
1381+ OnlyUsedByCopies = false ;
1382+ break ;
1383+ }
13741384 }
1375- UseCount++;
1376- }
13771385
1378- if (OnlyUsedByCopies && UseCount > 0 ) {
1379- break ;
1386+ if (!OnlyUsedByCopies || MRI->use_empty (SrcReg)) {
1387+ LLVM_DEBUG (dbgs () << " \t Skip remat for return register: "
1388+ << printReg (DstReg, TRI) << ' \n ' );
1389+ return false ;
1390+ }
1391+ LLVM_DEBUG (dbgs () << " \t Allow remat: only used by copies\n " );
13801392 }
1393+ } else {
1394+ LLVM_DEBUG (dbgs () << " \t Skip remat for return register: "
1395+ << printReg (DstReg, TRI) << ' \n ' );
1396+ return false ;
13811397 }
1382-
1383- LLVM_DEBUG (dbgs () << " \t Skip remat for return register: "
1384- << printReg (DstReg, TRI) << ' \n ' );
1385- return false ;
13861398 }
13871399 }
13881400 }
0 commit comments