@@ -1715,6 +1715,13 @@ bool ARMConstantIslands::undoLRSpillRestore() {
1715
1715
MI->eraseFromParent ();
1716
1716
MadeChange = true ;
1717
1717
}
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
+ }
1718
1725
}
1719
1726
return MadeChange;
1720
1727
}
@@ -1984,6 +1991,16 @@ static bool jumpTableFollowsTB(MachineInstr *JTMI, MachineInstr *CPEMI) {
1984
1991
&*MBB->begin () == CPEMI;
1985
1992
}
1986
1993
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
+
1987
2004
// / optimizeThumb2JumpTables - Use tbb / tbh instructions to generate smaller
1988
2005
// / jumptables when it's possible.
1989
2006
bool ARMConstantIslands::optimizeThumb2JumpTables () {
@@ -2033,7 +2050,7 @@ bool ARMConstantIslands::optimizeThumb2JumpTables() {
2033
2050
unsigned DeadSize = 0 ;
2034
2051
bool CanDeleteLEA = false ;
2035
2052
bool BaseRegKill = false ;
2036
-
2053
+
2037
2054
unsigned IdxReg = ~0U ;
2038
2055
bool IdxRegKill = true ;
2039
2056
if (isThumb2) {
@@ -2061,6 +2078,12 @@ bool ARMConstantIslands::optimizeThumb2JumpTables() {
2061
2078
IdxReg = Shift->getOperand (2 ).getReg ();
2062
2079
unsigned ShiftedIdxReg = Shift->getOperand (0 ).getReg ();
2063
2080
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
+
2064
2087
MachineInstr *Load = User.MI ->getNextNode ();
2065
2088
if (Load->getOpcode () != ARM::tLDRr)
2066
2089
continue ;
@@ -2070,6 +2093,16 @@ bool ARMConstantIslands::optimizeThumb2JumpTables() {
2070
2093
continue ;
2071
2094
2072
2095
// 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
+
2073
2106
if (isPositionIndependentOrROPI) {
2074
2107
MachineInstr *Add = Load->getNextNode ();
2075
2108
if (Add->getOpcode () != ARM::tADDrr ||
@@ -2079,22 +2112,27 @@ bool ARMConstantIslands::optimizeThumb2JumpTables() {
2079
2112
continue ;
2080
2113
if (Add->getOperand (0 ).getReg () != MI->getOperand (0 ).getReg ())
2081
2114
continue ;
2082
-
2115
+ if (registerDefinedBetween (IdxReg, Add->getNextNode (), MI, TRI))
2116
+ // IdxReg gets redefined in the middle of the sequence.
2117
+ continue ;
2083
2118
Add->eraseFromParent ();
2084
2119
DeadSize += 2 ;
2085
2120
} else {
2086
2121
if (Load->getOperand (0 ).getReg () != MI->getOperand (0 ).getReg ())
2087
2122
continue ;
2123
+ if (registerDefinedBetween (IdxReg, Load->getNextNode (), MI, TRI))
2124
+ // IdxReg gets redefined in the middle of the sequence.
2125
+ continue ;
2088
2126
}
2089
-
2090
-
2127
+
2128
+
2091
2129
// Now safe to delete the load and lsl. The LEA will be removed later.
2092
2130
CanDeleteLEA = true ;
2093
2131
Shift->eraseFromParent ();
2094
2132
Load->eraseFromParent ();
2095
2133
DeadSize += 4 ;
2096
2134
}
2097
-
2135
+
2098
2136
DEBUG (dbgs () << " Shrink JT: " << *MI);
2099
2137
MachineInstr *CPEMI = User.CPEMI ;
2100
2138
unsigned Opc = ByteOk ? ARM::t2TBB_JT : ARM::t2TBH_JT;
0 commit comments