diff options
Diffstat (limited to 'llvm/lib/Target/ARM/ARMISelLowering.cpp')
| -rw-r--r-- | llvm/lib/Target/ARM/ARMISelLowering.cpp | 35 |
1 files changed, 22 insertions, 13 deletions
diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp index 75d16a42d020..d788229f0c9b 100644 --- a/llvm/lib/Target/ARM/ARMISelLowering.cpp +++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp @@ -3024,18 +3024,27 @@ bool ARMTargetLowering::IsEligibleForTailCallOptimization( assert(Subtarget->supportsTailCall()); - // Indirect tail calls cannot be optimized for Thumb1 if the args - // to the call take up r0-r3. The reason is that there are no legal registers - // left to hold the pointer to the function to be called. - // Similarly, if the function uses return address sign and authentication, - // r12 is needed to hold the PAC and is not available to hold the callee - // address. - if (Outs.size() >= 4 && - (!isa<GlobalAddressSDNode>(Callee.getNode()) || isIndirect)) { - if (Subtarget->isThumb1Only()) - return false; - // Conservatively assume the function spills LR. - if (MF.getInfo<ARMFunctionInfo>()->shouldSignReturnAddress(true)) + // Indirect tail-calls require a register to hold the target address. That + // register must be: + // * Allocatable (i.e. r0-r7 if the target is Thumb1). + // * Not callee-saved, so must be one of r0-r3 or r12. + // * Not used to hold an argument to the tail-called function, which might be + // in r0-r3. + // * Not used to hold the return address authentication code, which is in r12 + // if enabled. + // Sometimes, no register matches all of these conditions, so we can't do a + // tail-call. + if (!isa<GlobalAddressSDNode>(Callee.getNode()) || isIndirect) { + SmallSet<MCPhysReg, 5> AddressRegisters; + for (Register R : {ARM::R0, ARM::R1, ARM::R2, ARM::R3}) + AddressRegisters.insert(R); + if (!(Subtarget->isThumb1Only() || + MF.getInfo<ARMFunctionInfo>()->shouldSignReturnAddress(true))) + AddressRegisters.insert(ARM::R12); + for (const CCValAssign &AL : ArgLocs) + if (AL.isRegLoc()) + AddressRegisters.erase(AL.getLocReg()); + if (AddressRegisters.empty()) return false; } @@ -9210,7 +9219,7 @@ static SDValue LowerCONCAT_VECTORS_i1(SDValue Op, SelectionDAG &DAG, }; // Concat each pair of subvectors and pack into the lower half of the array. - SmallVector<SDValue> ConcatOps(Op->op_begin(), Op->op_end()); + SmallVector<SDValue> ConcatOps(Op->ops()); while (ConcatOps.size() > 1) { for (unsigned I = 0, E = ConcatOps.size(); I != E; I += 2) { SDValue V1 = ConcatOps[I]; |
