@@ -1715,6 +1715,13 @@ bool ARMConstantIslands::undoLRSpillRestore() {
17151715 MI->eraseFromParent ();
17161716 MadeChange = true ;
17171717 }
1718+ if (MI->getOpcode () == ARM::tPUSH &&
1719+ MI->getOperand (2 ).getReg () == ARM::LR &&
1720+ MI->getNumExplicitOperands () == 3 ) {
1721+ // Just remove the push.
1722+ MI->eraseFromParent ();
1723+ MadeChange = true ;
1724+ }
17181725 }
17191726 return MadeChange;
17201727}
@@ -1984,6 +1991,16 @@ static bool jumpTableFollowsTB(MachineInstr *JTMI, MachineInstr *CPEMI) {
19841991 &*MBB->begin () == CPEMI;
19851992}
19861993
1994+ static bool registerDefinedBetween (unsigned Reg,
1995+ MachineBasicBlock::iterator From,
1996+ MachineBasicBlock::iterator To,
1997+ const TargetRegisterInfo *TRI) {
1998+ for (auto I = From; I != To; ++I)
1999+ if (I->modifiesRegister (Reg, TRI))
2000+ return true ;
2001+ return false ;
2002+ }
2003+
19872004// / optimizeThumb2JumpTables - Use tbb / tbh instructions to generate smaller
19882005// / jumptables when it's possible.
19892006bool ARMConstantIslands::optimizeThumb2JumpTables () {
@@ -2033,7 +2050,7 @@ bool ARMConstantIslands::optimizeThumb2JumpTables() {
20332050 unsigned DeadSize = 0 ;
20342051 bool CanDeleteLEA = false ;
20352052 bool BaseRegKill = false ;
2036-
2053+
20372054 unsigned IdxReg = ~0U ;
20382055 bool IdxRegKill = true ;
20392056 if (isThumb2) {
@@ -2061,6 +2078,12 @@ bool ARMConstantIslands::optimizeThumb2JumpTables() {
20612078 IdxReg = Shift->getOperand (2 ).getReg ();
20622079 unsigned ShiftedIdxReg = Shift->getOperand (0 ).getReg ();
20632080
2081+ // It's important that IdxReg is live until the actual TBB/TBH. Most of
2082+ // the range is checked later, but the LEA might still clobber it and not
2083+ // actually get removed.
2084+ if (BaseReg == IdxReg && !jumpTableFollowsTB (MI, User.CPEMI ))
2085+ continue ;
2086+
20642087 MachineInstr *Load = User.MI ->getNextNode ();
20652088 if (Load->getOpcode () != ARM::tLDRr)
20662089 continue ;
@@ -2070,6 +2093,16 @@ bool ARMConstantIslands::optimizeThumb2JumpTables() {
20702093 continue ;
20712094
20722095 // If we're in PIC mode, there should be another ADD following.
2096+ auto *TRI = STI->getRegisterInfo ();
2097+
2098+ // %base cannot be redefined after the load as it will appear before
2099+ // TBB/TBH like:
2100+ // %base =
2101+ // %base =
2102+ // tBB %base, %idx
2103+ if (registerDefinedBetween (BaseReg, Load->getNextNode (), MBB->end (), TRI))
2104+ continue ;
2105+
20732106 if (isPositionIndependentOrROPI) {
20742107 MachineInstr *Add = Load->getNextNode ();
20752108 if (Add->getOpcode () != ARM::tADDrr ||
@@ -2079,22 +2112,27 @@ bool ARMConstantIslands::optimizeThumb2JumpTables() {
20792112 continue ;
20802113 if (Add->getOperand (0 ).getReg () != MI->getOperand (0 ).getReg ())
20812114 continue ;
2082-
2115+ if (registerDefinedBetween (IdxReg, Add->getNextNode (), MI, TRI))
2116+ // IdxReg gets redefined in the middle of the sequence.
2117+ continue ;
20832118 Add->eraseFromParent ();
20842119 DeadSize += 2 ;
20852120 } else {
20862121 if (Load->getOperand (0 ).getReg () != MI->getOperand (0 ).getReg ())
20872122 continue ;
2123+ if (registerDefinedBetween (IdxReg, Load->getNextNode (), MI, TRI))
2124+ // IdxReg gets redefined in the middle of the sequence.
2125+ continue ;
20882126 }
2089-
2090-
2127+
2128+
20912129 // Now safe to delete the load and lsl. The LEA will be removed later.
20922130 CanDeleteLEA = true ;
20932131 Shift->eraseFromParent ();
20942132 Load->eraseFromParent ();
20952133 DeadSize += 4 ;
20962134 }
2097-
2135+
20982136 DEBUG (dbgs () << " Shrink JT: " << *MI);
20992137 MachineInstr *CPEMI = User.CPEMI ;
21002138 unsigned Opc = ByteOk ? ARM::t2TBB_JT : ARM::t2TBH_JT;
0 commit comments