diff --git a/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp b/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp --- a/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp +++ b/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp @@ -5831,9 +5831,28 @@ SetCandidateCallInfo(MachineOutlinerDefault, Costs.CallDefault); CandidatesWithoutStackFixups.push_back(C); } - else + else return outliner::OutlinedFunction(); } + + // Does every candidate's MBB contain a call? If so, then we might have a + // call in the range. + if (FlagsSetInAll & MachineOutlinerMBBFlags::HasCalls) { + // check if the range contains a call. These require a save + restore of + // the link register. + if (std::any_of(FirstCand.front(), FirstCand.back(), + [](const MachineInstr &MI) { return MI.isCall(); })) + NumBytesToCreateFrame += Costs.FrameDefault; + + // Handle the last instruction separately. If it is tail call, then the + // last instruction is a call, we don't want to save + restore in this + // case. However, it could be possible that the last instruction is a + // call without it being valid to tail call this sequence. We should + // consider this as well. + else if (FrameID != MachineOutlinerThunk && + FrameID != MachineOutlinerTailCall && FirstCand.back()->isCall()) + NumBytesToCreateFrame += Costs.FrameThunk; + } RepeatedSequenceLocs = CandidatesWithoutStackFixups; } @@ -5973,6 +5992,23 @@ return outliner::InstrType::Illegal; if (MI.isCall()) { + // Get the function associated with the call. Look at each operand and find + // the one that represents the calle and get its name. + const Function *Callee = nullptr; + for (const MachineOperand &MOP : MI.operands()) { + if (MOP.isGlobal()) { + Callee = dyn_cast(MOP.getGlobal()); + break; + } + } + + // Dont't outline calls to "mcount" like functions, in particular Linux + // kernel function tracing relies on it. + if (Callee && (Callee->getName() == "\01__gnu_mcount_nc" || + Callee->getName() == "\01mcount" || + Callee->getName() == "__mcount")) + return outliner::InstrType::Illegal; + // If we don't know anything about the callee, assume it depends on the // stack layout of the caller. In that case, it's only legal to outline // as a tail-call. Explicitly list the call instructions we know about so @@ -5982,7 +6018,29 @@ Opc == ARM::tBLXr || Opc == ARM::tBLXi) UnknownCallOutlineType = outliner::InstrType::LegalTerminator; - return UnknownCallOutlineType; + if (!Callee) + return UnknownCallOutlineType; + + // We have a function we have information about. Check if it's something we + // can safely outline. + MachineFunction *MF = MI.getParent()->getParent(); + MachineFunction *CalleeMF = MF->getMMI().getMachineFunction(*Callee); + + // We don't know what's going on with the callee at all. Don't touch it. + if (!CalleeMF) + return UnknownCallOutlineType; + + // Check if we know anything about the callee saves on the function. If we + // don't, then don't touch it, since that implies that we haven't computed + // anything about its stack frame yet. + MachineFrameInfo &MFI = CalleeMF->getFrameInfo(); + if (!MFI.isCalleeSavedInfoValid() || MFI.getStackSize() > 0 || + MFI.getNumObjects() > 0) + return UnknownCallOutlineType; + + // At this point, we can say that CalleeMF ought to not pass anything on the + // stack. Therefore, we can outline it. + return outliner::InstrType::Legal; } // Since calls are handled, don't touch LR or PC @@ -6045,10 +6103,6 @@ void ARMBaseInstrInfo::buildOutlinedFrame( MachineBasicBlock &MBB, MachineFunction &MF, const outliner::OutlinedFunction &OF) const { - // Nothing is needed for tail-calls. - if (OF.FrameConstructionID == MachineOutlinerTailCall) - return; - // For thunk outlining, rewrite the last instruction from a call to a // tail-call. if (OF.FrameConstructionID == MachineOutlinerThunk) { @@ -6065,9 +6119,59 @@ if (isThumb && !Call->getOperand(FuncOp).isReg()) MIB.add(predOps(ARMCC::AL)); Call->eraseFromParent(); - return; } + // Is there a call in the outlined range? + auto IsNonTailCall = [](MachineInstr &MI) { + return MI.isCall() && !MI.isReturn(); + }; + if (std::any_of(MBB.instr_begin(), MBB.instr_end(), IsNonTailCall)) { + MachineBasicBlock::iterator It = MBB.begin(); + MachineBasicBlock::iterator Et = MBB.end(); + + if (OF.FrameConstructionID == MachineOutlinerTailCall || + OF.FrameConstructionID == MachineOutlinerThunk) + Et = std::prev(MBB.end()); + + // We have to save and restore LR, we need to add it to the liveins if it + // is not already part of the set. This is suffient since outlined + // functions only have one block. + if (!MBB.isLiveIn(ARM::LR)) + MBB.addLiveIn(ARM::LR); + + // Insert a save before the outlined region + saveLROnStack(MBB, It); + + unsigned StackAlignment = Subtarget.getStackAlignment().value(); + const TargetSubtargetInfo &STI = MF.getSubtarget(); + const MCRegisterInfo *MRI = STI.getRegisterInfo(); + unsigned DwarfReg = MRI->getDwarfRegNum(ARM::LR, true); + // Add a CFI saying the stack was moved down. + int64_t StackPosEntry = + MF.addFrameInst(MCCFIInstruction::cfiDefCfaOffset(nullptr, + StackAlignment)); + BuildMI(MBB, It, DebugLoc(), get(ARM::CFI_INSTRUCTION)) + .addCFIIndex(StackPosEntry) + .setMIFlags(MachineInstr::FrameSetup); + + // Add a CFI saying that the LR that we want to find is now higher than + // before. + int64_t LRPosEntry = + MF.addFrameInst(MCCFIInstruction::createOffset(nullptr, DwarfReg, + StackAlignment)); + BuildMI(MBB, It, DebugLoc(), get(ARM::CFI_INSTRUCTION)) + .addCFIIndex(LRPosEntry) + .setMIFlags(MachineInstr::FrameSetup); + + // Insert a restore before the terminator for the function. Restore LR. + restoreLRFromStack(MBB, Et); + } + + // If this is a tail call outlined function, then there's already a return. + if (OF.FrameConstructionID == MachineOutlinerTailCall || + OF.FrameConstructionID == MachineOutlinerThunk) + return; + // Here we have to insert the return ourselves. Get the correct opcode from // current feature set. BuildMI(MBB, MBB.end(), DebugLoc(), get(Subtarget.getReturnOpcode())) diff --git a/llvm/test/CodeGen/ARM/machine-outliner-calls.mir b/llvm/test/CodeGen/ARM/machine-outliner-calls.mir new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/ARM/machine-outliner-calls.mir @@ -0,0 +1,308 @@ +# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py +# RUN: llc -mtriple=arm-- -run-pass=prologepilog -run-pass=machine-outliner \ +# RUN: -verify-machineinstrs %s -o - | FileCheck %s + +--- | + define void @outline_call_arm() #0 { ret void } + define void @outline_call_thumb() #1 { ret void } + define void @outline_call_tailcall_arm() #0 { ret void } + define void @outline_call_tailcall_thumb() #1 { ret void } + define void @outline_call_KO_mcount() #0 { ret void } + define void @bar() #0 { ret void } + declare void @"\01mcount"() + + attributes #0 = { minsize optsize } + attributes #1 = { minsize optsize "target-features"="+armv7-a,+thumb-mode" } +... +--- + +name: outline_call_arm +tracksRegLiveness: true +body: | + ; CHECK-LABEL: name: outline_call_arm + ; CHECK: bb.0: + ; CHECK: liveins: $r4, $lr + ; CHECK: $sp = frame-setup STMDB_UPD $sp, 14 /* CC::al */, $noreg, killed $r4, killed $lr + ; CHECK: frame-setup CFI_INSTRUCTION def_cfa_offset 8 + ; CHECK: frame-setup CFI_INSTRUCTION offset $lr, -4 + ; CHECK: frame-setup CFI_INSTRUCTION offset $r4, -8 + ; CHECK: BL @OUTLINED_FUNCTION_2 + ; CHECK: bb.1: + ; CHECK: BL @OUTLINED_FUNCTION_2 + ; CHECK: bb.2: + ; CHECK: BL @OUTLINED_FUNCTION_2 + ; CHECK: bb.3: + ; CHECK: $sp = frame-destroy LDMIA_UPD $sp, 14 /* CC::al */, $noreg, def $r4, def $lr + ; CHECK: BX_RET 14 /* CC::al */, $noreg + bb.0: + BL @bar, implicit-def dead $lr, implicit $sp + $r0 = MOVi 1, 14, $noreg, $noreg + $r1 = MOVi 1, 14, $noreg, $noreg + $r2 = MOVi 1, 14, $noreg, $noreg + $r3 = MOVi 1, 14, $noreg, $noreg + $r4 = MOVi 1, 14, $noreg, $noreg + bb.1: + BL @bar, implicit-def dead $lr, implicit $sp + $r0 = MOVi 1, 14, $noreg, $noreg + $r1 = MOVi 1, 14, $noreg, $noreg + $r2 = MOVi 1, 14, $noreg, $noreg + $r3 = MOVi 1, 14, $noreg, $noreg + $r4 = MOVi 1, 14, $noreg, $noreg + bb.2: + BL @bar, implicit-def dead $lr, implicit $sp + $r0 = MOVi 1, 14, $noreg, $noreg + $r1 = MOVi 1, 14, $noreg, $noreg + $r2 = MOVi 1, 14, $noreg, $noreg + $r3 = MOVi 1, 14, $noreg, $noreg + $r4 = MOVi 1, 14, $noreg, $noreg + bb.3: + BX_RET 14, $noreg +... +--- + +name: outline_call_thumb +tracksRegLiveness: true +body: | + ; CHECK-LABEL: name: outline_call_thumb + ; CHECK: bb.0: + ; CHECK: liveins: $r7, $lr + ; CHECK: $sp = frame-setup t2STMDB_UPD $sp, 14 /* CC::al */, $noreg, killed $r7, killed $lr + ; CHECK: frame-setup CFI_INSTRUCTION def_cfa_offset 8 + ; CHECK: frame-setup CFI_INSTRUCTION offset $lr, -4 + ; CHECK: frame-setup CFI_INSTRUCTION offset $r7, -8 + ; CHECK: tBL 14 /* CC::al */, $noreg, @OUTLINED_FUNCTION_4 + ; CHECK: bb.1: + ; CHECK: tBL 14 /* CC::al */, $noreg, @OUTLINED_FUNCTION_4 + ; CHECK: bb.2: + ; CHECK: tBL 14 /* CC::al */, $noreg, @OUTLINED_FUNCTION_4 + ; CHECK: bb.3: + ; CHECK: $sp = frame-destroy t2LDMIA_RET $sp, 14 /* CC::al */, $noreg, def $r7, def $pc + bb.0: + tBL 14, $noreg, @bar, implicit-def dead $lr, implicit $sp + $r0 = t2MOVi 1, 14, $noreg, $noreg + $r1 = t2MOVi 1, 14, $noreg, $noreg + $r2 = t2MOVi 1, 14, $noreg, $noreg + bb.1: + tBL 14, $noreg, @bar, implicit-def dead $lr, implicit $sp + $r0 = t2MOVi 1, 14, $noreg, $noreg + $r1 = t2MOVi 1, 14, $noreg, $noreg + $r2 = t2MOVi 1, 14, $noreg, $noreg + bb.2: + tBL 14, $noreg, @bar, implicit-def dead $lr, implicit $sp + $r0 = t2MOVi 1, 14, $noreg, $noreg + $r1 = t2MOVi 1, 14, $noreg, $noreg + $r2 = t2MOVi 1, 14, $noreg, $noreg + bb.3: + tBX_RET 14, $noreg +... +--- + +name: outline_call_tailcall_arm +tracksRegLiveness: true +body: | + ; CHECK-LABEL: name: outline_call_tailcall_arm + ; CHECK: bb.0: + ; CHECK: liveins: $r4, $lr + ; CHECK: $sp = frame-setup STMDB_UPD $sp, 14 /* CC::al */, $noreg, killed $r4, killed $lr + ; CHECK: frame-setup CFI_INSTRUCTION def_cfa_offset 8 + ; CHECK: frame-setup CFI_INSTRUCTION offset $lr, -4 + ; CHECK: frame-setup CFI_INSTRUCTION offset $r4, -8 + ; CHECK: BL @OUTLINED_FUNCTION_0 + ; CHECK: bb.1: + ; CHECK: BL @OUTLINED_FUNCTION_0 + ; CHECK: bb.2: + ; CHECK: BL @OUTLINED_FUNCTION_0 + ; CHECK: bb.3: + ; CHECK: $sp = frame-destroy LDMIA_UPD $sp, 14 /* CC::al */, $noreg, def $r4, def $lr + ; CHECK: BX_RET 14 /* CC::al */, $noreg + bb.0: + BL @bar, implicit-def dead $lr, implicit $sp + $r0 = MOVi 2, 14, $noreg, $noreg + $r1 = MOVi 2, 14, $noreg, $noreg + $r2 = MOVi 2, 14, $noreg, $noreg + $r3 = MOVi 2, 14, $noreg, $noreg + $r4 = MOVi 2, 14, $noreg, $noreg + BL @bar, implicit-def dead $lr, implicit $sp + bb.1: + BL @bar, implicit-def dead $lr, implicit $sp + $r0 = MOVi 2, 14, $noreg, $noreg + $r1 = MOVi 2, 14, $noreg, $noreg + $r2 = MOVi 2, 14, $noreg, $noreg + $r3 = MOVi 2, 14, $noreg, $noreg + $r4 = MOVi 2, 14, $noreg, $noreg + BL @bar, implicit-def dead $lr, implicit $sp + bb.2: + BL @bar, implicit-def dead $lr, implicit $sp + $r0 = MOVi 2, 14, $noreg, $noreg + $r1 = MOVi 2, 14, $noreg, $noreg + $r2 = MOVi 2, 14, $noreg, $noreg + $r3 = MOVi 2, 14, $noreg, $noreg + $r4 = MOVi 2, 14, $noreg, $noreg + BL @bar, implicit-def dead $lr, implicit $sp + bb.3: + BX_RET 14, $noreg +... +--- + +name: outline_call_tailcall_thumb +tracksRegLiveness: true +body: | + ; CHECK-LABEL: name: outline_call_tailcall_thumb + ; CHECK: bb.0: + ; CHECK: liveins: $r7, $lr + ; CHECK: $sp = frame-setup t2STMDB_UPD $sp, 14 /* CC::al */, $noreg, killed $r7, killed $lr + ; CHECK: frame-setup CFI_INSTRUCTION def_cfa_offset 8 + ; CHECK: frame-setup CFI_INSTRUCTION offset $lr, -4 + ; CHECK: frame-setup CFI_INSTRUCTION offset $r7, -8 + ; CHECK: tBL 14 /* CC::al */, $noreg, @OUTLINED_FUNCTION_1 + ; CHECK: bb.1: + ; CHECK: tBL 14 /* CC::al */, $noreg, @OUTLINED_FUNCTION_1 + ; CHECK: bb.2: + ; CHECK: tBL 14 /* CC::al */, $noreg, @OUTLINED_FUNCTION_1 + ; CHECK: bb.3: + ; CHECK: $sp = frame-destroy t2LDMIA_RET $sp, 14 /* CC::al */, $noreg, def $r7, def $pc + bb.0: + tBL 14, $noreg, @bar, implicit-def dead $lr, implicit $sp + $r0 = t2MOVi 2, 14, $noreg, $noreg + $r1 = t2MOVi 2, 14, $noreg, $noreg + $r2 = t2MOVi 2, 14, $noreg, $noreg + tBL 14, $noreg, @bar, implicit-def dead $lr, implicit $sp + bb.1: + tBL 14, $noreg, @bar, implicit-def dead $lr, implicit $sp + $r0 = t2MOVi 2, 14, $noreg, $noreg + $r1 = t2MOVi 2, 14, $noreg, $noreg + $r2 = t2MOVi 2, 14, $noreg, $noreg + tBL 14, $noreg, @bar, implicit-def dead $lr, implicit $sp + bb.2: + tBL 14, $noreg, @bar, implicit-def dead $lr, implicit $sp + $r0 = t2MOVi 2, 14, $noreg, $noreg + $r1 = t2MOVi 2, 14, $noreg, $noreg + $r2 = t2MOVi 2, 14, $noreg, $noreg + tBL 14, $noreg, @bar, implicit-def dead $lr, implicit $sp + bb.3: + tBX_RET 14, $noreg +... +--- + +name: outline_call_KO_mcount +tracksRegLiveness: true +body: | + ; CHECK-LABEL: name: outline_call_KO_mcount + ; CHECK: bb.0: + ; CHECK: liveins: $r4, $lr + ; CHECK: $sp = frame-setup STMDB_UPD $sp, 14 /* CC::al */, $noreg, killed $r4, killed $lr + ; CHECK: frame-setup CFI_INSTRUCTION def_cfa_offset 8 + ; CHECK: frame-setup CFI_INSTRUCTION offset $lr, -4 + ; CHECK: frame-setup CFI_INSTRUCTION offset $r4, -8 + ; CHECK: BL @"\01mcount", csr_aapcs, implicit-def dead $lr, implicit $sp + ; CHECK: BL @OUTLINED_FUNCTION_3 + ; CHECK: bb.1: + ; CHECK: BL @"\01mcount", csr_aapcs, implicit-def dead $lr, implicit $sp + ; CHECK: BL @OUTLINED_FUNCTION_3 + ; CHECK: bb.2: + ; CHECK: BL @"\01mcount", csr_aapcs, implicit-def dead $lr, implicit $sp + ; CHECK: BL @OUTLINED_FUNCTION_3 + ; CHECK: bb.3: + ; CHECK: $sp = frame-destroy LDMIA_UPD $sp, 14 /* CC::al */, $noreg, def $r4, def $lr + ; CHECK: BX_RET 14 /* CC::al */, $noreg + bb.0: + BL @"\01mcount", csr_aapcs, implicit-def dead $lr, implicit $sp + $r0 = MOVi 3, 14, $noreg, $noreg + $r1 = MOVi 3, 14, $noreg, $noreg + $r2 = MOVi 3, 14, $noreg, $noreg + $r3 = MOVi 3, 14, $noreg, $noreg + $r4 = MOVi 3, 14, $noreg, $noreg + bb.1: + BL @"\01mcount", csr_aapcs, implicit-def dead $lr, implicit $sp + $r0 = MOVi 3, 14, $noreg, $noreg + $r1 = MOVi 3, 14, $noreg, $noreg + $r2 = MOVi 3, 14, $noreg, $noreg + $r3 = MOVi 3, 14, $noreg, $noreg + $r4 = MOVi 3, 14, $noreg, $noreg + bb.2: + BL @"\01mcount", csr_aapcs, implicit-def dead $lr, implicit $sp + $r0 = MOVi 3, 14, $noreg, $noreg + $r1 = MOVi 3, 14, $noreg, $noreg + $r2 = MOVi 3, 14, $noreg, $noreg + $r3 = MOVi 3, 14, $noreg, $noreg + $r4 = MOVi 3, 14, $noreg, $noreg + bb.3: + BX_RET 14, $noreg +... +--- + +name: bar +tracksRegLiveness: true +body: | + bb.0: + BX_RET 14, $noreg + + + ; CHECK-LABEL: name: OUTLINED_FUNCTION_0 + ; CHECK: bb.0: + ; CHECK: liveins: $r11, $r10, $r9, $r8, $r7, $r6, $r5, $d15, $d14, $d13, $d12, $d11, $d10, $d9, $d8, $lr + ; CHECK: early-clobber $sp = STR_PRE_IMM killed $lr, $sp, -8, 14 /* CC::al */, $noreg + ; CHECK: frame-setup CFI_INSTRUCTION def_cfa_offset 8 + ; CHECK: frame-setup CFI_INSTRUCTION offset $lr, 8 + ; CHECK: BL @bar, implicit-def dead $lr, implicit $sp + ; CHECK: $r0 = MOVi 2, 14 /* CC::al */, $noreg, $noreg + ; CHECK: $r1 = MOVi 2, 14 /* CC::al */, $noreg, $noreg + ; CHECK: $r2 = MOVi 2, 14 /* CC::al */, $noreg, $noreg + ; CHECK: $r3 = MOVi 2, 14 /* CC::al */, $noreg, $noreg + ; CHECK: $r4 = MOVi 2, 14 /* CC::al */, $noreg, $noreg + ; CHECK: $lr, $sp = LDR_POST_IMM $sp, $noreg, 8, 14 /* CC::al */, $noreg + ; CHECK: TAILJMPd @bar, implicit $sp + + ; CHECK-LABEL: name: OUTLINED_FUNCTION_1 + ; CHECK: bb.0: + ; CHECK: liveins: $r11, $r10, $r9, $r8, $r6, $r5, $r4, $d15, $d14, $d13, $d12, $d11, $d10, $d9, $d8, $lr + ; CHECK: early-clobber $sp = t2STR_PRE killed $lr, $sp, -8, 14 /* CC::al */, $noreg + ; CHECK: frame-setup CFI_INSTRUCTION def_cfa_offset 8 + ; CHECK: frame-setup CFI_INSTRUCTION offset $lr, 8 + ; CHECK: tBL 14 /* CC::al */, $noreg, @bar, implicit-def dead $lr, implicit $sp + ; CHECK: $r0 = t2MOVi 2, 14 /* CC::al */, $noreg, $noreg + ; CHECK: $r1 = t2MOVi 2, 14 /* CC::al */, $noreg, $noreg + ; CHECK: $r2 = t2MOVi 2, 14 /* CC::al */, $noreg, $noreg + ; CHECK: $lr, $sp = t2LDR_POST $sp, 8, 14 /* CC::al */, $noreg + ; CHECK: tTAILJMPdND @bar, 14 /* CC::al */, $noreg, implicit $sp + + ; CHECK-LABEL: name: OUTLINED_FUNCTION_2 + ; CHECK: bb.0: + ; CHECK: liveins: $r11, $r10, $r9, $r8, $r7, $r6, $r5, $d15, $d14, $d13, $d12, $d11, $d10, $d9, $d8, $lr + ; CHECK: early-clobber $sp = STR_PRE_IMM killed $lr, $sp, -8, 14 /* CC::al */, $noreg + ; CHECK: frame-setup CFI_INSTRUCTION def_cfa_offset 8 + ; CHECK: frame-setup CFI_INSTRUCTION offset $lr, 8 + ; CHECK: BL @bar, implicit-def dead $lr, implicit $sp + ; CHECK: $r0 = MOVi 1, 14 /* CC::al */, $noreg, $noreg + ; CHECK: $r1 = MOVi 1, 14 /* CC::al */, $noreg, $noreg + ; CHECK: $r2 = MOVi 1, 14 /* CC::al */, $noreg, $noreg + ; CHECK: $r3 = MOVi 1, 14 /* CC::al */, $noreg, $noreg + ; CHECK: $r4 = MOVi 1, 14 /* CC::al */, $noreg, $noreg + ; CHECK: $lr, $sp = LDR_POST_IMM $sp, $noreg, 8, 14 /* CC::al */, $noreg + ; CHECK: MOVPCLR 14 /* CC::al */, $noreg + + ; CHECK-LABEL: name: OUTLINED_FUNCTION_3 + ; CHECK: bb.0: + ; CHECK: liveins: $r11, $r10, $r9, $r8, $r7, $r6, $r5, $d15, $d14, $d13, $d12, $d11, $d10, $d9, $d8 + ; CHECK: $r0 = MOVi 3, 14 /* CC::al */, $noreg, $noreg + ; CHECK: $r1 = MOVi 3, 14 /* CC::al */, $noreg, $noreg + ; CHECK: $r2 = MOVi 3, 14 /* CC::al */, $noreg, $noreg + ; CHECK: $r3 = MOVi 3, 14 /* CC::al */, $noreg, $noreg + ; CHECK: $r4 = MOVi 3, 14 /* CC::al */, $noreg, $noreg + ; CHECK: MOVPCLR 14 /* CC::al */, $noreg + + ; CHECK-LABEL: name: OUTLINED_FUNCTION_4 + ; CHECK: bb.0: + ; CHECK: liveins: $r11, $r10, $r9, $r8, $r6, $r5, $r4, $d15, $d14, $d13, $d12, $d11, $d10, $d9, $d8, $lr + ; CHECK: early-clobber $sp = t2STR_PRE killed $lr, $sp, -8, 14 /* CC::al */, $noreg + ; CHECK: frame-setup CFI_INSTRUCTION def_cfa_offset 8 + ; CHECK: frame-setup CFI_INSTRUCTION offset $lr, 8 + ; CHECK: tBL 14 /* CC::al */, $noreg, @bar, implicit-def dead $lr, implicit $sp + ; CHECK: $r0 = t2MOVi 1, 14 /* CC::al */, $noreg, $noreg + ; CHECK: $r1 = t2MOVi 1, 14 /* CC::al */, $noreg, $noreg + ; CHECK: $r2 = t2MOVi 1, 14 /* CC::al */, $noreg, $noreg + ; CHECK: $lr, $sp = t2LDR_POST $sp, 8, 14 /* CC::al */, $noreg + ; CHECK: tBX_RET 14 /* CC::al */, $noreg + + + diff --git a/llvm/test/CodeGen/ARM/machine-outliner-default.mir b/llvm/test/CodeGen/ARM/machine-outliner-default.mir --- a/llvm/test/CodeGen/ARM/machine-outliner-default.mir +++ b/llvm/test/CodeGen/ARM/machine-outliner-default.mir @@ -5,8 +5,6 @@ --- | define void @outline_default_arm() #0 { ret void } define void @outline_default_thumb() #1 { ret void } - define void @outline_default_KO_call_arm() #0 { ret void } - define void @outline_default_KO_call_thumb() #1 { ret void } define void @outline_default_KO_stack_arm() #0 { ret void } define void @outline_default_KO_stack_thumb() #0 { ret void } declare void @bar() @@ -118,120 +116,6 @@ ... --- -name: outline_default_KO_call_arm -tracksRegLiveness: true -body: | - ; CHECK-LABEL: name: outline_default_KO_call_arm - ; CHECK: bb.0: - ; CHECK: liveins: $lr - ; CHECK: BL @bar, implicit-def dead $lr, implicit $sp - ; CHECK: $r0 = MOVi 2, 14 /* CC::al */, $noreg, $noreg - ; CHECK: $r1 = MOVi 2, 14 /* CC::al */, $noreg, $noreg - ; CHECK: $r2 = MOVi 2, 14 /* CC::al */, $noreg, $noreg - ; CHECK: $r3 = MOVi 2, 14 /* CC::al */, $noreg, $noreg - ; CHECK: $r4 = MOVi 2, 14 /* CC::al */, $noreg, $noreg - ; CHECK: bb.1: - ; CHECK: liveins: $lr, $r5, $r6, $r7, $r8, $r9, $r10, $r11 - ; CHECK: BL @bar, implicit-def dead $lr, implicit $sp - ; CHECK: $r0 = MOVi 2, 14 /* CC::al */, $noreg, $noreg - ; CHECK: $r1 = MOVi 2, 14 /* CC::al */, $noreg, $noreg - ; CHECK: $r2 = MOVi 2, 14 /* CC::al */, $noreg, $noreg - ; CHECK: $r3 = MOVi 2, 14 /* CC::al */, $noreg, $noreg - ; CHECK: $r4 = MOVi 2, 14 /* CC::al */, $noreg, $noreg - ; CHECK: bb.2: - ; CHECK: liveins: $lr, $r5, $r6, $r7, $r8, $r9, $r10, $r11 - ; CHECK: BL @bar, implicit-def dead $lr, implicit $sp - ; CHECK: $r0 = MOVi 2, 14 /* CC::al */, $noreg, $noreg - ; CHECK: $r1 = MOVi 2, 14 /* CC::al */, $noreg, $noreg - ; CHECK: $r2 = MOVi 2, 14 /* CC::al */, $noreg, $noreg - ; CHECK: $r3 = MOVi 2, 14 /* CC::al */, $noreg, $noreg - ; CHECK: $r4 = MOVi 2, 14 /* CC::al */, $noreg, $noreg - ; CHECK: bb.3: - ; CHECK: liveins: $lr, $r5, $r6, $r7, $r8, $r9, $r10, $r11 - ; CHECK: $r2 = MOVr $lr, 14 /* CC::al */, $noreg, $noreg - ; CHECK: BX_RET 14 /* CC::al */, $noreg - bb.0: - liveins: $lr - BL @bar, implicit-def dead $lr, implicit $sp - $r0 = MOVi 2, 14, $noreg, $noreg - $r1 = MOVi 2, 14, $noreg, $noreg - $r2 = MOVi 2, 14, $noreg, $noreg - $r3 = MOVi 2, 14, $noreg, $noreg - $r4 = MOVi 2, 14, $noreg, $noreg - bb.1: - liveins: $lr, $r5, $r6, $r7, $r8, $r9, $r10, $r11 - BL @bar, implicit-def dead $lr, implicit $sp - $r0 = MOVi 2, 14, $noreg, $noreg - $r1 = MOVi 2, 14, $noreg, $noreg - $r2 = MOVi 2, 14, $noreg, $noreg - $r3 = MOVi 2, 14, $noreg, $noreg - $r4 = MOVi 2, 14, $noreg, $noreg - bb.2: - liveins: $lr, $r5, $r6, $r7, $r8, $r9, $r10, $r11 - BL @bar, implicit-def dead $lr, implicit $sp - $r0 = MOVi 2, 14, $noreg, $noreg - $r1 = MOVi 2, 14, $noreg, $noreg - $r2 = MOVi 2, 14, $noreg, $noreg - $r3 = MOVi 2, 14, $noreg, $noreg - $r4 = MOVi 2, 14, $noreg, $noreg - bb.3: - liveins: $lr, $r5, $r6, $r7, $r8, $r9, $r10, $r11 - $r2 = MOVr $lr, 14, $noreg, $noreg - BX_RET 14, $noreg -... ---- - -name: outline_default_KO_call_thumb -tracksRegLiveness: true -body: | - ; CHECK-LABEL: name: outline_default_KO_call_thumb - ; CHECK: bb.0: - ; CHECK: liveins: $lr - ; CHECK: tBL 14 /* CC::al */, $noreg, @bar, implicit-def dead $lr, implicit $sp - ; CHECK: $r0 = t2MOVi 2, 14 /* CC::al */, $noreg, $noreg - ; CHECK: $r1 = t2MOVi 2, 14 /* CC::al */, $noreg, $noreg - ; CHECK: $r2 = t2MOVi 2, 14 /* CC::al */, $noreg, $noreg - ; CHECK: bb.1: - ; CHECK: liveins: $lr, $r3, $r4, $r5, $r6, $r7, $r8, $r9, $r10, $r11 - ; CHECK: tBL 14 /* CC::al */, $noreg, @bar, implicit-def dead $lr, implicit $sp - ; CHECK: $r0 = t2MOVi 2, 14 /* CC::al */, $noreg, $noreg - ; CHECK: $r1 = t2MOVi 2, 14 /* CC::al */, $noreg, $noreg - ; CHECK: $r2 = t2MOVi 2, 14 /* CC::al */, $noreg, $noreg - ; CHECK: bb.2: - ; CHECK: liveins: $lr, $r3, $r4, $r5, $r6, $r7, $r8, $r9, $r10, $r11 - ; CHECK: tBL 14 /* CC::al */, $noreg, @bar, implicit-def dead $lr, implicit $sp - ; CHECK: $r0 = t2MOVi 2, 14 /* CC::al */, $noreg, $noreg - ; CHECK: $r1 = t2MOVi 2, 14 /* CC::al */, $noreg, $noreg - ; CHECK: $r2 = t2MOVi 2, 14 /* CC::al */, $noreg, $noreg - ; CHECK: bb.3: - ; CHECK: liveins: $lr, $r3, $r4, $r5, $r6, $r7, $r8, $r9, $r10, $r11 - ; CHECK: $r2 = tMOVr $lr, 14 /* CC::al */, $noreg - ; CHECK: tBX_RET 14 /* CC::al */, $noreg - bb.0: - liveins: $lr - tBL 14, $noreg, @bar, implicit-def dead $lr, implicit $sp - $r0 = t2MOVi 2, 14, $noreg, $noreg - $r1 = t2MOVi 2, 14, $noreg, $noreg - $r2 = t2MOVi 2, 14, $noreg, $noreg - bb.1: - liveins: $lr, $r3, $r4, $r5, $r6, $r7, $r8, $r9, $r10, $r11 - tBL 14, $noreg, @bar, implicit-def dead $lr, implicit $sp - $r0 = t2MOVi 2, 14, $noreg, $noreg - $r1 = t2MOVi 2, 14, $noreg, $noreg - $r2 = t2MOVi 2, 14, $noreg, $noreg - bb.2: - liveins: $lr, $r3, $r4, $r5, $r6, $r7, $r8, $r9, $r10, $r11 - tBL 14, $noreg, @bar, implicit-def dead $lr, implicit $sp - $r0 = t2MOVi 2, 14, $noreg, $noreg - $r1 = t2MOVi 2, 14, $noreg, $noreg - $r2 = t2MOVi 2, 14, $noreg, $noreg - bb.3: - liveins: $lr, $r3, $r4, $r5, $r6, $r7, $r8, $r9, $r10, $r11 - $r2 = tMOVr $lr, 14, $noreg - tBX_RET 14, $noreg -... ---- - name: outline_default_KO_stack_arm tracksRegLiveness: true body: |